Saturday, December 21, 2013

Repeating update on AppWidget

The most easy way to set up a repeating update is declaring the android:updatePeriodMillis in the appwidget-provider xml.  However, Android's AppWidget update framework ignore any of its value less than 30 minutes - it is not providing update more than once in every half an hours.

We can use AlarmManager's setRepeating function to raise an Intent repeating for a set interval.  In this case, we set the updatePeriodMillis="0".  Herewith is a solution using the AlarmManager approach.

1. Declare in the AndroidManifest.xml that your AppWidget is listening to the Intent (e.g. ContactWidgetUpdate)

<receiver android:name=".ContactWidgetProvider"
android:label="@string/widget_name">
<intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    <action android:name="ContactWidgetUpdate" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/widget_contact" />
</receiver>


2.  In the onEnabled method of AppWidgetProvider, the AlarmManager is setup with a repeating Intent.  Here the ContactWdigetUpdate Intent is raised every 60 seconds

public void onEnabled(Context context) {
        Log.d(this.getClass().getName(), "onEnabled");
        super.onEnabled(context);
        PendingIntent anIntent=PendingIntent.getBroadcast(context, 0, new Intent("ContactWidgetUpdate"),                PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmMgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        alarmMgr.setRepeating(AlarmManager.RTC,System.currentTimeMillis(),60000, anIntent);
    }



3. The onRecieve method is called as per the arrival of ConactWidgetUpdate Intent, it calls the onUpdate to update the Widget.

public void onReceive(Context context, Intent intent) {
        Log.d(this.getClass().getName(), "onReceive: intent="+intent);
        if("ContactWidgetUpdate".equalsIgnoreCase(intent.getAction())){
            ComponentName componentName=new ComponentName(context,getClass().getName());
            AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);
            int[] appWidgetIds=appWidgetManager.getAppWidgetIds(componentName);
            onUpdate(context,appWidgetManager,appWidgetIds);
        }
    }