Search code examples
androidandroid-appwidgetandroid-lifecycle

Lifetime of an android app widget


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


Solution

  • 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...