I've implementing a widget with RemoteViewsService
containing with a ListView
of items where all the items are clickable to launch a service. In short I'm using setPendingIntentTemplate
in my AppWidgetProvider.onUpdate()
and setOnClickFillInIntent
in my RemoteViewsService.RemoteViewsFactory()
.
And in most cases I get the expected behavior. However, when using up some memory and going back to try to click on an item in the list again sometimes nothing happens when clicking on items in a list: the service isn't launched, and no touch feedback is given. If I have several widgets one of the lists may have the problem while the others don't.
Does anyone know how to solve this problem?
Some other testing has revealed that:
- If I scroll for a while in a list with the problem and then try to click again, it works! My first thought was that the reason was that RemoteViewsFactory.getView was called and so updated the pending intent, but checking the logs I can see that this method isn't entered.
- I've also logged
RemoteViewsService.RemoteViewsFactory.onDestroy
to see if the reason for the problem was that this was removed, but this was not the case. - If I manage to call
AppWidgetManager.updateAppWidget
(so that AppWidgetProvider.onUpdate will run) the problem dissapears (I call updateAppWidget from inside my main app).
These three observations seems to point to the problem being in AppWidgetManager rather than RemoteViewsFactory.
AppWidgetProvider.onUpdate:
@Override
public void onUpdate(Context iContext, AppWidgetManager iWidgetMgr,
int[] iWidgetIds){
Log.d(DbgU.getAppTag(), DbgU.getMethodName());
//Going through all widgets placed (could be more than one)
for(int i = 0; i < iWidgetIds.length; i++){
//Setting up the remote view service
Intent tmpRVServiceIntent = new Intent(iContext,
RemoteViewsServiceC.class);
tmpRVServiceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
iWidgetIds[i]);
tmpRVServiceIntent.setData(Uri.parse(tmpRVServiceIntent.toUri(
Intent.URI_INTENT_SCHEME)));
//Setting up the remote views
RemoteViews tmpRemoteViews = new RemoteViews(iContext.getPackageName(),
R.layout.widget);
tmpRemoteViews.setRemoteAdapter(R.id.widget_listview,
tmpRVServiceIntent);
tmpRemoteViews.setEmptyView(R.id.widget_listview,
R.id.widget_empty_view);
//Setting up the pending intent template (the id will be filled
//in later in RemoteViewsFactoryC.getViewAt())
Intent tmpTemplateIntent = new Intent(iContext,
LauncherServiceC.class);
tmpTemplateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
iWidgetIds[i]);
PendingIntent tmpPendingIntent = PendingIntent.getService(iContext,
0, tmpTemplateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
tmpRemoteViews.setPendingIntentTemplate(R.id.widget_listview,
tmpPendingIntent);
//Applying the update for the views
iWidgetMgr.updateAppWidget(iWidgetIds[i], tmpRemoteViews);
}
}
RemoteViewsService.RemoteViewsFactory.getViewAt:
@Override
public RemoteViews getViewAt(int inPosition) {
Log.v(DbgU.getAppTag(), DbgU.getMethodName()
+ ", inPosition = " + inPosition);
//Moving the cursor to the current position
mItemCursor.moveToPosition(inPosition);
//Extracting values from the database
String tmpName = mItemCursor.getString(
mItemCursor.getColumnIndexOrThrow(ItemTableM.COLUMN_NAME));
long tmpItemId = mItemCursor.getLong(
mItemCursor.getColumnIndexOrThrow(ItemTableM.COLUMN_ID));
Uri tmpItemUri = DatabaseU.getItemUriFromId(tmpItemId);
//Setting up the remote views object
RemoteViews retRemoteViews = new RemoteViews(
mContext.getPackageName(), R.layout.widget_listitem);
retRemoteViews.setTextViewText(R.id.widget_listitem_textView, tmpName);
//Adding action URI to the intent template which was set for all the
//list rows in WidgetProviderC.onUpdate
Intent tmpFillInIntent = new Intent();
tmpFillInIntent.setData(tmpItemUri);
retRemoteViews.setOnClickFillInIntent(R.id.widget_listitem_textView,
tmpFillInIntent);
return retRemoteViews;
}
I've been having this problem for a long time and am very grateful for any help