0

我需要知道 onReceive() 中的小部件 ID。我想将配置活动的选定项目信息与新的小部件 id 相关联,然后将它们保存到 sharedpreferences 以便我可以通过读取 sharedpreferences 来知道在 onReiceive() 内部做什么

配置活动:

resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetId);
setResult(RESULT_CANCELED, resultValue);

listView.setOnItemClickListener(new OnItemClickListener()
{
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
    {
        ...
        resultValue.putExtra("mykey", "otherinfo");
        setResult(RESULT_OK, resultValue);
        finish();
    }           
});

应用小部件提供者:

@Override
public void onEnabled(Context context)
{
    super.onEnabled(context);
    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
    int id = intent.getStringExtra(AppWidgetManager.EXTRA_APPWIDGET_ID) // <-- THIS IS NULL!

    // save id on shared preferences

    PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);   
    am.setInexactRepeating(AlarmManager.RTC, System.currentTimeMillis(), UPDATE_INTERVAL, pi);      
}

广播接收器:

public void onReceive(Context context, Intent intent)
{       
    intent.getStringExtra(AppWidgetManager.EXTRA_APPWIDGET_ID); // <-- NULL
    ..  
}

getStringExtra 总是返回空值......也许上面的代码是完全错误的

4

1 回答 1

2

一些东西...

  1. onEnabled在 AppWidgetProvider 中仅在添加第一个 appwidget 时调用一次(即当此 AppWidgetProvider 变为“启用”时)。请注意,onEnabled 不会给您appWidgetId- 它不是与主屏幕上应用程序小部件的特定实例相关联的回调。
  2. 您正在调用getStringExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)您刚刚创建的 Intent。我想你的意思是打电话putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)。但是,如上所述,这也不起作用,因为您没有在onEnabled().

如果要在主屏幕上设置与每个 appwidget 实例关联的警报,则需要做一些额外的工作。

  1. 完成配置应用小部件后,将其存储appWidgetId在 SharedPreferences 中(例如,您可以使用键“appwidgetid_##”来存储布尔值)。
  2. onUpdate()被调用并且您正在遍历appWidgetIds数组时,appWidgetId首先检查 SharedPreferences 中的每个。如果检查通过,您就知道用户已经配置了该 appWidget,您可以为其创建和设置闹钟;否则,continue到下一个appWidgetId
  3. 设置警报时,请注意Intent在创建 s 时 s 必须是唯一PendingIntent的,否则您将获得一个PendingIntent重用或覆盖旧的 s(取决于您指定作为PendingIntent调用的最后一个参数的标志)。由于在检查唯一性时不考虑额外内容,请参阅底部的代码以了解如何使其唯一性。
  4. onDelete()中,取消该应用小部件的警报。确保以完全相同的方式构造 PendingIntent。您也可以在appWidgetId此处从 SharedPreferences 中删除。

为了使意图独一无二:

Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWIdgetId);
// IMPORTANT!
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
// Note the FLAG_UPDATE_CURRENT
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = ...
am.setInexactRepeating(...);
于 2013-08-14T16:05:48.567 回答