3

I created an AppWidget for my App and setup the updatePeriodMillis to 0, because this Widget is not doing anything, if the user does not interact.

Everything works fine, untill Android cleans the ram. Then the widget won't respond anymore until the App is started again or the device is rebooted (in both cases the onUpdate() will run again).

So my question: What do I need to do, to bring it back to work, after Android kicked out the Application?

This is part of the manifest:

    <receiver android:name="WidgetProvider" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            <action android:name="PATH.widgetBtnStartClicked" />
        </intent-filter>
        <meta-data android:name="android.appwidget.provider"
                   android:resource="@xml/appwidget_provider_info" />
    </receiver>

This is part of my WidgetProvider:

public class WidgetProvider extends AppWidgetProvider {

private static final String BTN_START_CLICKED = "PATH.widgetBtnStartClicked";


private static Values values;

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {

    super.onUpdate(context, appWidgetManager, appWidgetIds);

    // get RemoteView (widget):
    for (int i = 0; i < appWidgetIds.length; i++) {
        int appWidgetId = appWidgetIds[i];

        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.appwidget);


        // Register onClick for App-start-button:
        Intent intentLaunch = new Intent(BTN_APP_LAUNCH_CLICKED);
        intentLaunch.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntentLaunch = PendingIntent.getBroadcast(
                context, appWidgetId, intentLaunch,
                PendingIntent.FLAG_UPDATE_CURRENT);
        views.setOnClickPendingIntent(R.id.appwidget_btn_launch,
                pendingIntentLaunch);


        appWidgetManager.updateAppWidget(appWidgetId, views);

    }

}

@Override
public void onReceive(Context context, Intent intent) {
    RemoteViews views = new RemoteViews(context.getPackageName(),
            R.layout.appwidget);

    super.onReceive(context, intent);

    AppWidgetManager appWidgetManager = AppWidgetManager
            .getInstance(context);
    ComponentName componentName = new ComponentName(context,
            WidgetProvider.class);

    if (intent.getAction().equals(BTN_APP_LAUNCH_CLICKED)) {

        //do some stuff..
    }
    // update views
    appWidgetManager.updateAppWidget(componentName, views);

}

I hope there is everything you need to understand the problem. Just tell me, if not!

Klumbe
  • 370
  • 2
  • 12

1 Answers1

0

I think your app relies only on onUpdate() to refresh the widget. There are other events that cause the pending intents to 'drop off' the widget. Such as the RAM clearing you mention.

I recommend you:
+ put your widget update code in a separate service class
+ have that class triggered when different events happen. onUpdate() and other events, example, the one that causes your RAM to be cleared.
+ ensure you update everything each time with remoteviews, because no old pending intents etc are preserved.

You can take total control over the events that trigger the widget to update.

If it suits your situation, you can also set an arbitrary alarm, using the alarmmanager and a receiver class. in this way, you can set the alarm to only be received when the phone wakes, and use that to call your update service class. in your update service class, then clear any alarm (if the update is called from another event) and set another alarm.

There are lots of questions on SO about who to use a service with widgets. It shouldnt take long to work it out. To put that info here is outside of the scope of this question.

  • That's true, it only relies on onUpdate(). I have heard about using a service for that some times, but I still do not know how to use it in an appropriate manner. Can you please give me a smmall example? I just need to know where to start this service and how it should look like. I do not know which events causes the ram to be cleared...Android is just doing this if there is not enough free space (like when opening a big app). I would be really glad about a short example or further information. Thanks so far! – Klumbe May 04 '14 at 15:26
  • Thanks for the explanation, but I still don't get it at all. How do I pass the Information like the AppWidgetManager or appWidgetIds to the service? And even if I do this, how can I trigger at the right time? I mean the right time should be when the widget is visable. I am asking myself how google did it in it's "sound search" widget. There is now time between ram-cleaning and updating the widget. I mean when I close the app that causes ram-cleaning, this app still works, but mine is not. – Klumbe May 07 '14 at 19:30
  • The Service-Thing isn't the big problem (I got it running), but I still don't have a clue how to call it after the ram has been cleaned (or even as you said: after the device wakes). I tried to find an answer (many hours of course), but I am still not progressing. – Klumbe May 10 '14 at 15:54
  • I will try this one: http://stackoverflow.com/questions/13443543/start-activity-on-wake-up-sleep-in-android Do you mean that? – Klumbe May 10 '14 at 16:09
  • I will do some further testing, but I think that works like a charm :-) – Klumbe May 10 '14 at 16:28
  • i didnt mean any specific answer, but it sounds like you are working it out. if you set an alarm using alarmmanager, then it will be postponed by sleep or screen off - and then be triggered when the phone wakes for any reason. theres quite a lot of info about how to use alarmmanager. –  May 11 '14 at 17:09
  • Yeah, but the thing is, that (as I know) it will update it on a regular basis (which is not needed). But I just need to update it, when the focus is lost, or if the data changes. It confuses me, that this service seems to run even if I do not start it explicitly. I just added it to the manifest. – Klumbe May 14 '14 at 16:39
  • To find the best way to update my app, i just had to learn more about what android does and what event i wanted to use to trigger my updates. I couldnt choose the one i really wanted because Android just couldnt, and i had to compromise. As a noob i just had to keep learning and searching until i found a suitable way. It took time but it was the only way to get my app working. Stackoverflow is useful for little technical things, but not programming strategy. –  May 15 '14 at 19:41