0

I have an issue/problem with my app widget. I've created an app widget with 6 buttons, i compine these 6 buttons with 6 actions (in the manifest and in the onUpdate() Method). Cause if the user press one of these that i can react to this. But after a default time i didn't get a response, it sound like, the appwidgetmanager is not working.

The Problem is, if i connect the device to the pc it works eg. 1 week, but when i use the smartphone in the normal way (i not connected it with the pc, i use it a whole day) at end of the day the appwidget is not response, the buttons give no response.

The Widget must only display some text, for this reason i disable the updateperiod -> the appwidget runs only one time in the onUpdate() Method.

Now the Question: Must i implement the updateperiod, that i can certified that the appwidget still life on the end of a day or is that an other issue/problem?

regards Manu

Manu Zi
  • 2,300
  • 6
  • 33
  • 67

2 Answers2

2

It is a good idea to set the updatePeriodMillis in something like 900000 milliseconds. This will call your onUpdate method every 15 minutes. In the onUpdate method you can "refresh" your pending intents for your remote views. The other thing you can do is to perform a widget update every time you are changing your remote views. For example is the user press the button do what you have to do and then perform a widget update.

There are a number of reasons that a pending intent will be destroyed by the system thus leaving your remote views dead and all of them are hard to find and understand so the best practice is to update your widget once a while.

My research shows that 15 minutes is a good time frame for this. For example this is my onUpdate method which runs every 15 minutes for a widget with many buttons:

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    Log.d(TAG, "onUpdate");
    super.onUpdate(context, appWidgetManager, appWidgetIds);

    FullWidgetPreferencesHelper wp;

    // If no specific widgets requested, collect list of all
    if (appWidgetIds == null) {
        appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, FullWidgetProvider.class));
    }

    for (int widgetId : appWidgetIds) {
        Commands.FullWidgetUpdate(context, widgetId, 0); //<-- Update το widgetId
    }
}

and the FullWidgetUpdate method is something like this:

...
    views.setInt(R.id.cmdwifi, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_topleft_black));
    views.setInt(R.id.cmdbluetooth, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
    views.setInt(R.id.cmddata, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
    views.setInt(R.id.cmdsync, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
    views.setInt(R.id.cmdflight, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
    views.setInt(R.id.cmdgps, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
    views.setInt(R.id.cmdorientation, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
    views.setInt(R.id.cmdvolume, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_topright_black));
...
        final int PendingIntentFLAG = PendingIntent.FLAG_UPDATE_CURRENT;

    Intent iWiFi = new Intent(cx, CommandsReceiver.class).setAction(CommandsReceiver.cmdwifi).setData(Uri.parse("custom:" + widgetID));
    PendingIntent piWiFi = PendingIntent.getBroadcast(cx, 0, iWiFi, PendingIntentFLAG);
    views.setOnClickPendingIntent(R.id.cmdwifi, piWiFi);

    Intent iBT = new Intent(cx, CommandsReceiver.class).setAction(CommandsReceiver.cmdbt).setData(Uri.parse("custom:" + widgetID));
    PendingIntent piBT = PendingIntent.getBroadcast(cx, 0, iBT, PendingIntentFLAG);
    views.setOnClickPendingIntent(R.id.cmdbluetooth, piBT);
... and so on for other buttons ....

Hope this helps...

ChD Computers
  • 3,135
  • 3
  • 23
  • 33
  • thank u very much for this detailed answer. But one think: every 15 minutes an update, i'm a little bit scared about memoryleaks, have u any experience about that you have to do is not worry about it? – Manu Zi Jun 25 '13 at 11:53
  • Memory leaks are result of bad code and not of update times. As long as your code is efficient and small you have nothing to worry about. If your widget has many things to do when the user interacts with it then you have to go with services but that's a whole different matter. In your case in which you are changing some views visibility when the user press a button you are fine to go with the 15 minutes approach. It's fine to worry about update times in widgets but not so much, the most common widgets are those with clocks which are updating every minute with no noticeable resources draining. – ChD Computers Jun 25 '13 at 17:39
0

Do you update every view in the widget every time you update one of the views?

Last time I checked you had to update every view every time or else the views will end up becoming unresponsive sooner or later. In other words if you have 6 buttons and 2 text views and you want to update one of the textviews you also need to update the other textview and the buttons (with the same information that you sent to them earlier of course).

It may or may not be a bug in Android, but it's the way it is.

Rasmusob
  • 508
  • 3
  • 13
  • No, i not update every view. I might image ... if the user press btn 1 then i fill text 1 and set the visibility of text 2,3,4,5,6 of gone and with the other one i go the same way. btn2 -> text2 -> visible -> text 1,3,4,5,6 gone. if this is an bug ... i don't think so, cause other app widget can manage there lifetime ... – Manu Zi Jun 24 '13 at 20:52