2013-08-17 58 views
1

我使用下面的代碼:獲得正確的標識部件在啓動

我的主要活動:

public class MainActivity extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    int idWidget; 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    if(getIntent().getExtras()!=null){ 
     idWidget=getIntent().getExtras().getInt("com.example.testwidget.myIntent.IDWidget"); 

     Toast.makeText(this,"Id widget : "+Integer.toString(idWidget),Toast.LENGTH_LONG).show(); 
    } 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

}

我的微件提供者:

public class myWidgetProvider extends AppWidgetProvider { 

public void onUpdate(Context contexte, AppWidgetManager gestionnaireWidget, int[] appWidgetIds) { 
    final int N = appWidgetIds.length; 
    int appWidgetId; 
    RemoteViews vue; 
    Intent intentPostIt; 
    PendingIntent pendingIntentPostIt; 

    Toast.makeText(contexte,"Starting updating widgets",Toast.LENGTH_SHORT).show(); 

    for (int i=0; i<N; i++) { 
     appWidgetId = appWidgetIds[i]; 

     Toast.makeText(contexte,"Id widget : "+Integer.toString(appWidgetId),Toast.LENGTH_LONG).show(); 

     intentPostIt = new Intent(contexte,MainActivity.class); 

     Logger.getLogger(MainActivity.class.getName()).log(Level.INFO,"Intent : "+intentPostIt.toString()); 

     intentPostIt.setAction("com.example.testwidget.myIntent"); 
     intentPostIt.putExtra("com.example.testwidget.myIntent.IDWidget",appWidgetId); 
     pendingIntentPostIt = PendingIntent.getActivity(contexte,0, intentPostIt,0); 

     Logger.getLogger(MainActivity.class.getName()).log(Level.INFO,"Intent extra : "+Integer.toString(intentPostIt.getIntExtra("GL.PostIt.IDWidget",-1))); 

     vue=new RemoteViews(contexte.getPackageName(),R.layout.widget_description); 
     vue.setOnClickPendingIntent(R.id.widget,pendingIntentPostIt); 
     gestionnaireWidget.updateAppWidget(appWidgetId,vue); 
    } 

    Toast.makeText(contexte,"Ending updating widgets",Toast.LENGTH_SHORT).show(); 
} 

}

有了這個代碼,當在主屏幕上添加第一個小部件時,Toast會通知您AppWidgetManager的update函數正在啓動。第二個Toast爲您提供正在處理的窗口小部件的標識。第三個告訴你update函數的結束。

如果您在主屏幕上添加了第二個小部件,則會重複相同的序列,但會使用另一個Id號碼。

現在,單擊第一個窗口小部件:主要活動已啓動,並且Toast爲您提供了與啓動應用程序的Intent綁定的Id。關閉應用程序並觸摸其他小部件:應用程序將再次啓動,並出現另一個Toast。在我看來,它應該給第二個小部件的Id。情況並非如此:第一個ID再次顯示。

爲什麼我的應用程序在第二個小部件啓動時沒有檢索到好的Id號?我的代碼有什麼問題嗎?它是如何工作的?如果是的話,我怎麼才能區分哪個部件啓動了應用程序?

回答

0

你需要與你的PendingIntent像這樣使用標誌:

pendingIntentPostIt = PendingIntent.getActivity(contexte,0, intentPostIt,PendingIntent.FLAG_UPDATE_CURRENT); 

沒有這個標誌,你把額外的數據的arent更新,因爲同樣的PendingIntent在系統中已經存在,系統只是返回你的第一個創建而不更新其數據。

請仔細閱讀本完全理解爲什麼會出現這種情況:http://developer.android.com/reference/android/app/PendingIntent.html

從DOC:

一個的PendingIntent本身很簡單,就是通過描述用於獲取原始數據的系統維護一個令牌的引用它。這意味着,即使其擁有的應用程序的進程被終止,PendingIntent本身仍然可以從其他被賦予的進程中使用。如果稍後創建的應用程序重新獲取相同類型的PendingIntent(相同的操作,相同的Intent操作,數據,類別和組件,以及相同的標誌),它將會收到一個表示相同標記的PendingIntent(如果該標記仍然有效)因此調用cancel()將其刪除。 由於這種行爲,重要的是要知道兩個Intents何時被認爲是相同的,以檢索PendingIntent。人們犯的一個常見錯誤是創建多個PenttentIntent對象,其Intents只在其「額外」內容中有所不同,期望每次都得到不同的PendingIntent。這不會發生。用於匹配的Intent部分與Intent.filterEquals定義的部分相同。如果您使用兩個與Intent.filterEquals等效的Intent對象,那麼您將爲它們獲得相同的PendingIntent。

.....

+0

使用「PendingIntent.FLAG_UPDATE_CURRENT」不是一個解決方案:不是有兩次第一個小工具ID,我得到了第二個!我無法區分哪個小部件是應用程序啓動的起源。但是談論「PendingIntent」是個好主意:通過在請求代碼中傳遞小部件Id,我可以獲得trigerring小部件的小部件Id。我的問題就解決了。 – Zelig63