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

标签 java android widget

我使用以下代码:

我的主要 Activity :

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 号。

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

为什么我的应用程序在由第二个小部件启动时无法检索到正确的 ID 号?我的代码有什么问题吗?它应该如何工作?如果是,我如何区分哪个小部件启动了该应用程序?

最佳答案

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

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

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

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

来自文档:

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

......

关于java - 在启动时获取正确的 Id 小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18291262/

相关文章:

java - 为什么在使用 objectInputStream.readObject() 反序列化后我的对象的字段设置为默认值?

android - Dagger2 单例实际上并不是单例问题

启动设置 Activity 时 Android 9 后退按钮无法正常工作

android - 如何使用 Altbeacon : Android Beacon Library? 在后台对信标进行测距

jquery - 如何通过动态创建的 id 从 gridster.js 中删除单个小部件

string - ExtJS 如何从字符串动态创建小部件和布局

java - 请求方法 'GET' 不受支持,但它实际上存在于 Controller 中

java - 用 ByteBuddy 替换字节码中出现的类型

javax.net.ssl.SSLHandshakeException : sun. security.validator.ValidatorException:PKIX 路径构建失败:

iOS Today 小部件内容有时会消失并重绘