5

I have a Android App widget and a button on the widget. I have set the update time period to 30mins but I also want to update the widget whenever I touch the button. here's my code:

        RemoteViews remoteV = new RemoteViews(context.getPackageName(), R.layout.widgetmenu);

        Intent intentSync = new Intent(context, MessMenuWidgetProvider.class);
        PendingIntent pendingSync = PendingIntent.getBroadcast(context,0, intentSync,0);
        remoteV.setOnClickPendingIntent(R.id.imageButtonSync,pendingSync);

        appWidgetManager.updateAppWidget(awID, remoteV);

I have set the update time to 30 mins so in every 30mins the function onUpdate() is called. What I want to achieve is to call onUpdate() manually using the button. But it's not happening. Any help?

iitum studant
  • 856
  • 2
  • 8
  • 24
  • 2
    Welcome to SO. "It's not working" as a problem statement truly is not specific enough to get any answers. Please consider editing your question so it is more specific. – O. Jones Oct 25 '14 at 21:10

4 Answers4

7

This is extremely easy. Below is the modified code to make the "onUpdate" method of your widget called each time the button is clicked.

RemoteViews remoteV = new RemoteViews(context.getPackageName(), R.layout.widgetmenu);

Intent intentSync = new Intent(context, MessMenuWidgetProvider.class);
intentSync.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); //You need to specify the action for the intent. Right now that intent is doing nothing for there is no action to be broadcasted.
PendingIntent pendingSync = PendingIntent.getBroadcast(context,0, intentSync, PendingIntent.FLAG_UPDATE_CURRENT); //You need to specify a proper flag for the intent. Or else the intent will become deleted.
remoteV.setOnClickPendingIntent(R.id.imageButtonSync,pendingSync);

appWidgetManager.updateAppWidget(awID, remoteV);

Now each time you click that button, the broadcast AppWidgetManager.ACTION_APPWIDGET_UPDATE will be sent to your widget and the method you have inside that class will handle the update. So either the onUpdate method is called, or the onReceive method is called. Whichever you have specified.

Seth
  • 1,769
  • 4
  • 26
  • 39
  • It's working great but it's calling onReceive not onUpdate. How do I change it to onUpdate? Thanks!! – iitum studant Oct 26 '14 at 06:58
  • `**PendingIntent.FLAG_UPDATE_CURRENT**` what is this? I have my question here: http://stackoverflow.com/questions/40776920/how-to-manually-call-onupdate-from-within-the-widget-itself – Si8 Nov 24 '16 at 01:58
  • 1
    @Si8 remove the asterisks, I have no idea why I put them there... i think it was supposed to add bold style to the text but didn't. But its simply a flag to the pending intent. It just updates the current intent with the new information. – Seth Nov 28 '16 at 01:55
  • 1
    This should be the same answer to your question you have linked. This is how to initiate the `onUpdate` method or the `onReceive` method of your WidgetProvider. – Seth Nov 28 '16 at 01:57
  • When using this `onReceive` is called instead of `onUpdate`. – stefana Jul 05 '17 at 14:51
  • 1
    You must also do `intentSync.putExtra( AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { appWidgetId } );` to get it to call `onUpdate`. If you don't add that extra, it will only call `onReceive` and you'd have to handle it yourself there (and who wants to do that?). – Khantahr Sep 16 '18 at 01:27
6

If MessMenuWidgetProvider is your AppWidgetProvider subclass, your PendingIntent will trigger onReceive() on it, not onUpdate(). You would need to call setAction() on the Intent, supplying ACTION_APPWIDGET_UPDATE, plus fill in the EXTRA_APPWIDGET_IDS extra with your app widget's ID in a one-argument int[]. In other words, you need to set up the Intent to be the same as the Intent structure that AppWidgetManager would use to trigger onUpdate() in your AppWidgetProvider.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Please help with my question: http://stackoverflow.com/questions/40776920/how-to-manually-call-onupdate-from-within-the-widget-itself – Si8 Nov 24 '16 at 02:04
6
RemoteViews remoteV = new RemoteViews(context.getPackageName(), R.layout.widgetmenu);

Intent intentSync = new Intent(context, MessMenuWidgetProvider.class);
intentSync.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); 
PendingIntent pendingSync = PendingIntent.getBroadcast(context,0, intentSync, PendingIntent.FLAG_UPDATE_CURRENT); 
remoteV.setOnClickPendingIntent(R.id.imageButtonSync,pendingSync);

appWidgetManager.updateAppWidget(awID, remoteV);

It will call onReceive(); In your onReceive() method just add the following to call onUpdate manually.

@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    super.onReceive(context, intent);

    Bundle extras = intent.getExtras();
       if(extras!=null) {
        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
        ComponentName thisAppWidget = new ComponentName(context.getPackageName(), MessMenuWidgetProvider.class.getName());
        int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);

        onUpdate(context, appWidgetManager, appWidgetIds);
       }
}
iitum studant
  • 856
  • 2
  • 8
  • 24
  • I am testing out this code... with my code (http://stackoverflow.com/questions/40776920/how-to-manually-call-onupdate-from-within-the-widget-itself) I will let you know how it goes. – Si8 Nov 24 '16 at 02:00
  • It didn't do anything :/ – Si8 Nov 24 '16 at 02:03
0

In the onUpdate() code of the App Widget Provider, add the following to the intent to give the widget id:

intentSync.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, awID);

In the App Widget Configure activity, make sure you get the widget id:

int awID = AppWidgetManager.INVALID_APPWIDGET_ID;

 // Find the widget id from the intent. 
        Intent intent = getIntent();
        Bundle extras = intent.getExtras();
        if (extras != null) {
            awID = extras.getInt(
                    AppWidgetManager.EXTRA_APPWIDGET_ID,  AppWidgetManager.INVALID_APPWIDGET_ID);
        }

    // If we got intent without the widget id, exit.
    if (awID == AppWidgetManager.INVALID_APPWIDGET_ID) {
        finish();
    }

For the button listener call the update then use the following code to pass back original widget id:

Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, awID);
setResult(RESULT_OK, resultValue); 
Wildroid
  • 864
  • 7
  • 9