Reputation: 560
I have a very weird problem with my AppWidget in Android 4.1.1. I'm currently developing a music player application and its widget. Widget must be updated when song changes, player starts and stops. It has a ListView which must be in sync with playlist in application.
Prior to Jelly Bean everything was working fine. After my test device is upgraded from 4.0.3 to 4.1.1, whenever widget is programmatically forced to update, layout of Android's Messaging widget is set to my widget for a few seconds! I also checked this case in emulator with 4.1, which works fine.
I use that piece of code to force my widget to update:
AppWidgetManager man = AppWidgetManager.getInstance(applicationContext);
int[] ids = man.getAppWidgetIds(
new ComponentName(applicationContext, MuzikLargeWidgetProvider.class));
Intent updateIntent = new Intent();
updateIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
applicationContext.sendBroadcast(updateIntent);
And here is my onUpdate method
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
this.context = context;
this.appWidgetManager = appWidgetManager;
ComponentName thisWidget = new ComponentName(context,
MuzikLargeWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int appWidgetId : allWidgetIds) {
Intent svcIntent = new Intent(context, UpdateService.class);
svcIntent.putExtra(WidgetActions.DATA_WIDGET_ID, appWidgetId);
context.startService(svcIntent);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
I'm using a service (UpdateService), which is a static inner class, to update my widget:
public static class UpdateService extends IntentService {
public UpdateService() {
super("UpdateService");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public RemoteViews buildUpdate(Context context, int widgetId) {
final RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.muzikwidget_large);
return views;
}
@Override
protected void onHandleIntent(Intent intent) {
// Build the widget update
RemoteViews updateViews = buildUpdate(this, intent.getIntExtra(WidgetActions.DATA_WIDGET_ID, 0));
// Push update for this widget to the home screen
ComponentName thisWidget = new ComponentName(this, MuzikLargeWidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
}
}
buildUpdate method does a few more things (setting intents for widget's buttons, setting textviews, etc.) but they are not related with my problem. I'm having this problem on a Asus TF 300 TG tablet (not rooted).
Any help is appreciated.
Upvotes: 2
Views: 425
Reputation: 560
The problem is resolved. I modified the code piece which I use to force widget to update. This is working:
AppWidgetManager man = AppWidgetManager.getInstance(applicationContext);
int[] ids = man.getAppWidgetIds(
new ComponentName(applicationContext, MuzikLargeWidgetProvider.class));
for (int appWidgetId : ids) {
Intent svcIntent = new Intent(applicationContext, UpdateService.class);
svcIntent.putExtra(WidgetActions.DATA_WIDGET_ID, appWidgetId);
applicationContext.startService(svcIntent);
}
Widget's onUpdate method is not called and UpdateService is invoked directly. It seems like sendBroadcast should be avoided sometimes.
EDIT
If you need to use broadcast to update your widget, this seems to be a proper way to accomplish that:
AppWidgetManager man = AppWidgetManager.getInstance(applicationContext);
int[] ids = man.getAppWidgetIds(
new ComponentName(applicationContext, MuzikLargeWidgetProvider.class));
Intent updateIntent = new Intent(applicationContext, MuzikLargeWidgetProvider.class);
updateIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
applicationContext.sendBroadcast(updateIntent);
Upvotes: 2