Tuesday, October 19, 2010

Update Widget in onReceive() method

In my previous exercise of App Widget (Refer "App Widget using Alarm Manager" and "Cancel Alarm Service in onDisabled()"), Alarm Service was used t trigger onReceive() method of AppWidgetProvider object. It simple prompt user with a Toast only, without update widgets. This exercise, onReceive() method will update widgets.

In order to retrieve the list of appWidgetIds, the following code can be used:

ComponentName thisAppWidget = new ComponentName(context.getPackageName(), HelloWidgetProvider.class.getName());
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);


then call onUpdate() method to update all widgets.

HelloWidgetProvider.java
package com.exercise.HelloWidget;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RemoteViews;
import android.widget.Toast;

public class HelloWidgetProvider extends AppWidgetProvider {

static AlarmManager myAlarmManager;
static PendingIntent myPendingIntent;

private static SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy hh:mm:ss a");
static String strWidgetText = "";

public static String MY_WIDGET_UPDATE = "MY_OWN_WIDGET_UPDATE";

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

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

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

onUpdate(context, appWidgetManager, appWidgetIds);
}

//Toast.makeText(context, "onReceiver()", Toast.LENGTH_LONG).show();
}
}

@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
//super.onDeleted(context, appWidgetIds);
Toast.makeText(context, "onDeleted()", Toast.LENGTH_LONG).show();
}

@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
//super.onDisabled(context);

myAlarmManager.cancel(myPendingIntent);

Toast.makeText(context, "onDisabled()", Toast.LENGTH_LONG).show();
}

@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
//super.onEnabled(context);
Toast.makeText(context, "onEnabled()", Toast.LENGTH_LONG).show();
}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onUpdate(context, appWidgetManager, appWidgetIds);

final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
updateAppWidget(context, appWidgetManager, appWidgetId);

Toast.makeText(context, "onUpdate(): " + String.valueOf(i) + " : " + String.valueOf(appWidgetId), Toast.LENGTH_LONG).show();
}

}

public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId){
String currentTime = formatter.format(new Date());
strWidgetText = currentTime;

RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.hellowidget_layout);
updateViews.setTextViewText(R.id.widgettext, "[" + String.valueOf(appWidgetId) + "]" + strWidgetText);
appWidgetManager.updateAppWidget(appWidgetId, updateViews);

Toast.makeText(context, "updateAppWidget(): " + String.valueOf(appWidgetId) + "\n" + strWidgetText, Toast.LENGTH_LONG).show();

}

static void SaveAlarmManager(AlarmManager tAlarmManager, PendingIntent tPendingIntent)
{
myAlarmManager = tAlarmManager;
myPendingIntent = tPendingIntent;
}

}


Download the files.

5 comments:

zehro said...

Your update using "onReceive()" articles were very helpful to me. I'm just wondering if there is a way to extend this further so that when the device is asleep (screen off), the updates stop. Then when the device wakes up, the updates resume.

I'm just thinking of ways to further improve this widget. If you have any suggestions, let me know.

Thanks.

arttuv said...

Thanks for the example code, it was exactly what I was looking for.

Now I update my widget from the app by using broadcast, and the widget doesn't get updated when I add it to the home screen. Do you know how I could get it updated also then? My intention is, that the widget is only updated when user makes certain things in the app, and when the widget is added for the first time.

Anonymous said...

Helped me too 4 years later!

Bernd said...

Really very helpful tutorial. Even after 4 years, it is still working on Android Lollipop based apk I am working on. Thanks a lot.
And same question as zehro! Any idea how (if necessary at all) to stop the updates when the screen turns off?

Unknown said...

Thank You very match!