So aktualisieren Sie das App-Widget mit der Listenansicht einer Aktivität
Ich weiß, dass dies schon oft gefragt wurde, aber ich habe die Dokumentation von oben nach unten durchgesehen, alle Antworten hier gelesen und keine davon hat geholfen. Um ehrlich zu sein, sagt jede Antwort etwas anderes darüber aus, wie man das angeht.
Jetzt zurück zu meiner Frage. Ich möchte die Widget-Listenansicht von einer Aktivität aktualisieren und habe @ erstellWidgetProvider#sendUpdateBroadcastToAllWidgets()
zu diesem Zweck rufe ich aus der Aktivität.
Es ruft schließlich dieonUpdate()
Damit die Sendung korrekt empfangen wird. Die Ansichten werden jedoch nicht aktualisiert.
Ich habe auch versucht, @ anzurufAppWidgetManager#notifyAppWidgetViewDataChanged()
und aktualisierte die Daten inWidgetFactory#onDataSetChanged()
aber die Methode wurde noch nie aufgerufen.
Also ich denke, das alles funktioniert nicht, weil die Remote Views Factory zwischengespeichert ist, aber ich weiß nicht, wie ich dies zuverlässig überwinden kann. Irgendwelche Gedanken?
Und was ist mit Kontexten? Ich muss immer eine liefern, aber es ist mir eigentlich egal, welche. Ist das wichtig?
Vielen Dan
ANBIETE
public class WidgetProvider extends AppWidgetProvider {
public static void sendUpdateBroadcastToAllWidgets(Context context) {
int allWidgetIds[] = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, WidgetProvider.class));
Intent intent = new Intent(context, WidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
context.sendBroadcast(intent);
}
@Override
public void onUpdate(Context context, AppWidgetManager widgetManager, int[] widgetIds) {
for (int id : widgetIds) {
updateWidget(context, widgetManager, id);
}
super.onUpdate(context, widgetManager, widgetIds);
}
@Override
public void onDeleted(Context context, int[] widgetIds) {
WidgetPreferences prefs = new WidgetPreferences(context);
for (int widgetId : widgetIds) {
prefs.getWidgetPreferences(widgetId).edit().clear().commit();
}
super.onDeleted(context, widgetIds);
}
private static void updateWidget(Context context, AppWidgetManager widgetManager, int widgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
// set list adapter
Intent serviceIntent = new Intent(context, WidgetService.class);
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)));
views.setRemoteAdapter(android.R.id.list, serviceIntent);
views.setEmptyView(android.R.id.list, android.R.id.empty);
// set widget title
WidgetDataCategory category = new WidgetPreferences(context).getSavedCategory(widgetId);
views.setTextViewText(R.id.titleText, context.getString(category.titleResourceId()));
// set onclick listener - we create a pending intent template and when an items is clicked
// the intent is filled with missing data and sent
Intent startActivityIntent = new Intent(context, SimplePersonDetailActivity.class);
startActivityIntent.setData(Uri.parse(startActivityIntent.toUri(Intent.URI_INTENT_SCHEME)));
startActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivityIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, startActivityIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setPendingIntentTemplate(android.R.id.list, pendingIntent);
// all hail to Google
widgetManager.updateAppWidget(widgetId, views);
}
}
FABRI
public class WidgetFactory implements RemoteViewsService.RemoteViewsFactory {
private Context context;
private List<Person> people = new ArrayList<>();
public WidgetFactory(Context context, Intent intent) {
this.context = context;
int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
WidgetPreferences prefs = new WidgetPreferences(context);
WidgetDataCategory category = prefs.getSavedCategory(widgetId);
int numberOfItemsToShow = prefs.getSavedLimit(widgetId);
people = category.filterAndSlice(new PersonDao(context).getAllForGroup(Constants.SIMPLE_GROUP_ID), numberOfItemsToShow);
}
}
@Override
public void onCreate() {}
@Override
public void onDataSetChanged() {}
@Override
public void onDestroy() {}
@Override
public int getCount() {
return people.size();
}
@Override
public RemoteViews getViewAt(int position) {
Person person = people.get(position);
BigDecimal amount = ListViewUtil.sumTransactions(new TransactionDao(context).getAllForPerson(person));
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.item_widget);
remoteViews.setTextViewText(R.id.nameText, person.getName());
remoteViews.setTextViewText(R.id.amountText, MoneyFormatter.withoutPlusPrefix().format(amount));
// fill details for the onclick listener (updating the pending intent template
// set in the WidgetProvider)
Intent listenerIntent = new Intent();
listenerIntent.putExtra(Constants.PERSON_ID, people.get(position).getId());
remoteViews.setOnClickFillInIntent(R.id.widgetItem, listenerIntent);
return remoteViews;
}
@Override
public RemoteViews getLoadingView() {
return null;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return true;
}
}