filippo
filippo

Reputation: 839

Get widget id from BroadcastReceiver

I need to know the widget id inside onReceive(). I thought to associate the selected item informations of the configure activity to the new widget id, and then save them to sharedpreferences so that i can know what to do inside onReiceive() by reading from sharedpreferences

Configure activity:

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();
    }           
});

AppWidgetProvider:

@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);      
}

BroadCastReceiver:

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

getStringExtra returns always null values... maybe the code above is completely wrong

Upvotes: 0

Views: 2563

Answers (1)

Karakuri
Karakuri

Reputation: 38585

A few things...

  1. onEnabled in an AppWidgetProvider is only called once when the first appwidget is added (that's when this AppWidgetProvider becomes "enabled"). Notice that onEnabled doesn't give you an appWidgetId - it's not a callback associated with a particular instance of an app widget on the home screen.
  2. You are calling getStringExtra(AppWidgetManager.EXTRA_APPWIDGET_ID) on an Intent you've just created. I think you meant to call putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId). However, as mentioned above, this won't work either since you aren't given an id in onEnabled().

If you want to set an alarm that is associated to each appwidget instance on the home screen, you need to do some extra work.

  1. When you finish configuring an app widget, store its appWidgetId in SharedPreferences (you could use the key "appwidgetid_##" to store a boolean value, for instance).
  2. When onUpdate() is called and you are iterating over the appWidgetIds array, check each appWidgetId in SharedPreferences first. If the check passes, you know the user has configured that appWidget and you can create and set your alarm for it; otherwise, continue to the next appWidgetId.
  3. When setting the alarm, note that Intents must be unique when creating PendingIntents, otherwise you'll get a PendingIntent that reuses or overwrites the old one (depending on which flag you specify as the last argument to the PendingIntent call). Since extras are not considered when checking for uniqueness, see the code at the bottom for how to make it unique.
  4. In onDelete(), cancel the alarm for that appwidget. Make sure you construct the PendingIntent the exact same way. You can also remove the appWidgetId from SharedPreferences here.

To make the intent unique:

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(...);

Upvotes: 2

Related Questions