简体   繁体   中英

onDataSetChanged() on RemoteViewsFactory not being called after updating AppWidget

I have the following widget provider info:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget_agenda"
    android:minHeight="110dp"
    android:minResizeHeight="110dp"
    android:minResizeWidth="110dp"
    android:minWidth="180dp"
    android:previewImage="@drawable/widget_preview"
    android:resizeMode="horizontal|vertical"
    android:updatePeriodMillis="600000" android:widgetCategory="home_screen"/>

Used in the widget provider registered in the Manifest:

<receiver
    android:name=".AgendaWidgetProvider"
    android:label="MyWidget">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
    </intent-filter>

    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/agenda_widget_info" />
</receiver>

My RemoteViewsService is registered as well:

<service
        android:name=".AgendaWidgetService"
        android:permission="android.permission.BIND_REMOTEVIEWS" />

It has the following definition:

class AgendaWidgetService : RemoteViewsService() {

    override fun onGetViewFactory(intent: Intent?) =
        AgendaWidgetViewsFactory(applicationContext)
}

To force update the widget and call the onUpdate() method on AgendaWidgetProvider I send the following broadcast:

val widgetIds = AppWidgetManager.getInstance(context).getAppWidgetIds(
    ComponentName(context, AgendaWidgetProvider::class.java)
)
if (widgetIds.isNotEmpty()) {
    Intent(context, AgendaWidgetProvider::class.java).apply {
        this.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
        putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds)
        context.sendBroadcast(this)
    }
}

This gets called every time! My onUpdate() looks like this:

override fun onUpdate(
    context: Context,
    appWidgetManager: AppWidgetManager,
    appWidgetIds: IntArray
) {

    appWidgetIds.forEach {

        val rv = RemoteViews(context.packageName, R.layout.widget_agenda)

        rv.setTextViewText(R.id.widgetDate, "Today")

        val i = Intent(context, AgendaWidgetService::class.java)
        i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)
        rv.setRemoteAdapter(
            R.id.widgetAgendaList,
            i
        )

        rv.setEmptyView(R.id.widgetAgendaList, R.id.widgetAgendaEmpty)

        appWidgetManager.notifyAppWidgetViewDataChanged(it, R.id.widgetDate)

        appWidgetManager.notifyAppWidgetViewDataChanged(it, R.id.widgetAgendaList)
        appWidgetManager.updateAppWidget(it, rv)
    }

    super.onUpdate(context, appWidgetManager, appWidgetIds)

}

The onDataSetChanged() has the following def:

override fun onDataSetChanged() {
    Timber.d("AAA onDataSetChanged")
}

I use Android emulator (8.0) and Nexus 5x (8.1) to test this. The onUpdate() is called every time, while onDataSetChanged() seems to be called only when exiting or entering the app. Any clues?

Thanks!

To trigger onDataSetChanged() in a widget, you don't need to create a broadcast. Just call notifyAppWidgetViewDataChanged from within your app, like this:

                Context context = getApplicationContext();
                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, AgendaWidgetProvider.class));
                appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widgetAgendaList);

Also, you shouldn't need to call notifyAppWidgetViewDataChanged() in onCreate() . According to this answer , onCreate() automatically triggers onDataSetChanged() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM