更新AppWidget后未调用RemoteViewsFactory上的onDataSetChanged()

时间:2018-02-15 08:14:06

标签: android android-appwidget remoteview

我有以下小部件提供商信息:

<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"/>

在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>

我的RemoteViewsService也已注册:

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

它有以下定义:

class AgendaWidgetService : RemoteViewsService() {

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

要强制更新窗口小部件并在onUpdate()上调用AgendaWidgetProvider方法,我会发送以下广播:

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)
    }
}

每次都会调用它!我的onUpdate()看起来像这样:

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)

}

onDataSetChanged()有以下def:

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

我使用Android模拟器(8.0)和Nexus 5x(8.1)来测试它。每次调用onUpdate(),而onDataSetChanged()似乎仅在退出或进入应用时调用。有线索吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

要在窗口小部件中触发onDataSetChanged(),则无需创建广播。只需从您的应用程序内调用notifyAppWidgetViewDataChanged,就像这样:

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

此外,您无需在notifyAppWidgetViewDataChanged()中调用onCreate()。根据{{​​3}},onCreate()自动触发onDataSetChanged()