在启动时获取正确的Id小部件

时间:2013-08-17 17:00:37

标签: java android widget

我使用以下代码:

我的主要活动:

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为您提供正在处理的窗口小部件的ID。第三个通知您update函数的结束。

如果您在主屏幕上添加第二个小部件,则会重复相同的序列,但会使用另一个ID号。

现在,点击第一个小部件:启动主要活动,Toast为您提供启动应用程序的Intent的ID绑定。关闭应用并触摸其他小部件:再次启动应用,然后显示另一个Toast。在我看来,它应该给出第二个小部件的Id。情况并非如此:第一个Id再次显示。

为什么我的应用程序在第二个小部件启动时没有检索到良好的Id号码?我的代码有什么问题吗?这是怎么回事?如果是,我怎么能区分哪个小部件启动了应用程序?

1 个答案:

答案 0 :(得分:0)

您需要在PendingIntent中使用标记,如下所示:

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

如果没有该标志,您放置的额外数据不会更新,因为系统中已存在相同的PendingIntent,系统只返回您创建的第一个而不更新其数据。

仔细阅读以充分理解为什么会发生这种情况:http://developer.android.com/reference/android/app/PendingIntent.html

来自doc:

PendingIntent本身只是对系统维护的令牌的引用,该令牌描述了用于检索它的原始数据。这意味着,即使其拥有的应用程序的进程被终止,PendingIntent本身也将保持可用于已经给出它的其他进程。如果创建应用程序稍后重新检索相同类型的PendingIntent(相同的操作,相同的Intent操作,数据,类别和组件以及相同的标志),它将接收表示同一令牌的PendingIntent,如果它仍然有效,并且可以因此调用cancel()来删除它。 由于这种行为,重要的是要知道两个Intent何时被认为是相同的,以便检索PendingIntent。人们常犯的一个错误是使用Intents创建多个PendingIntent对象,这些对象只在其“额外”内容中有所不同,期望每次都获得不同的PendingIntent。这不会发生。用于匹配的Intent部分与Intent.filterEquals定义的部分相同。如果你使用两个与Intent.filterEquals相同的Intent对象,那么你将获得两个相同的PendingIntent。

.....