【问题标题】:onDataSetChanged() on RemoteViewsFactory not being called after updating AppWidget更新 AppWidget 后未调用 RemoteViewsFactory 上的 onDataSetChanged()
【发布时间】:2018-10-12 18:15:22
【问题描述】:

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

<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中注册的widget provider中使用:

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

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

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() 具有以下定义:

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

我使用 Android 模拟器 (8.0) 和 Nexus 5x (8.1) 进行测试。 onUpdate() 每次都会被调用,而onDataSetChanged() 似乎只有在退出或进入应用程序时才会被调用。有什么线索吗?

谢谢!

【问题讨论】:

  • 制作样品并在此处发送链接,以进行复制

标签: android android-appwidget remoteview


【解决方案1】:

要在小部件中触发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);

另外,您不需要在onCreate() 中调用notifyAppWidgetViewDataChanged()。根据this answeronCreate()自动触发onDataSetChanged()

【讨论】:

  • 您似乎非常擅长小部件,我可以就一个问题征求您的意见吗?
  • @Paul 我不确定我是否是专家,但我最近一直在使用小部件。最好的办法是在 StackOverflow 上发布您的问题以获得大量专业知识。
  • 我发表了,但还没有人回答。
猜你喜欢
  • 2016-02-25
  • 1970-01-01
  • 2022-07-29
  • 1970-01-01
  • 2012-09-06
  • 1970-01-01
  • 2011-11-22
  • 2016-01-23
  • 1970-01-01
相关资源
最近更新 更多