【发布时间】:2021-08-28 07:35:16
【问题描述】:
我的应用小部件(显示游戏分数的列表视图)在主屏幕上创建时工作正常,但是当我在提供程序内调用 appWidgetManager.updateAppWidget(id, R.id.appwidget) 时,小部件或 RemoteViewsFactory 中的日志调用没有反应onCreate() 或 onDataSetChanged() 方法。我知道updateAppWidget 会被调用,因为我可以看到它之前的日志调用。
为什么小部件没有更新?
我的 AppWidgetProvider:
class ScoresAppWidgetProvider : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
updateAllWidgets(appWidgetIds, context, appWidgetManager)
super.onUpdate(context, appWidgetManager, appWidgetIds)
}
private fun updateAllWidgets(appWidgetIds: IntArray, context: Context, appWidgetManager: AppWidgetManager) {
appWidgetIds.forEach { appWidgetId ->
updateWidget(appWidgetId, context, appWidgetManager, false)
}
}
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
Log.i("TAG", "onReceive appWidgetId $appWidgetId") // This is logged and id is correct
if (intent.action.equals(ACTION_CLICK_REFRESH)) {
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.appwidget_list_view) // Works fine and updates the widget list
} else if (intent.action.equals((ACTION_CLICK_SPOILERS_ON))) { // This is received
updateWidget(appWidgetId, context, appWidgetManager, true)
} else if (intent.action.equals((ACTION_CLICK_SPOILERS_OFF))) { // This is received
updateWidget(appWidgetId, context, appWidgetManager, false)
}
}
private fun updateWidget(appWidgetId: Int, context: Context, appWidgetManager: AppWidgetManager, spoilers: Boolean) {
val intent = Intent(context, AppWidgetService::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
putExtra("testString", "Intent received")
data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
}
// PendingIntent to refresh the appWidget contents
val pendingRefreshClickIntent: PendingIntent = Intent(context, ScoresAppWidgetProvider::class.java).let {
it.action = ScoresAppWidgetProvider.ACTION_CLICK_REFRESH
it.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
return@let PendingIntent.getBroadcast(context, appWidgetId, it, PendingIntent.FLAG_UPDATE_CURRENT)
}
// PendingIntent to toggle score spoilers
val pendingSpoilersClickIntent: PendingIntent = Intent(context, ScoresAppWidgetProvider::class.java).let {
it.action = if (spoilers) ScoresAppWidgetProvider.ACTION_CLICK_SPOILERS_ON else ScoresAppWidgetProvider.ACTION_CLICK_SPOILERS_ON
it.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
return@let PendingIntent.getBroadcast(context, appWidgetId, it, PendingIntent.FLAG_UPDATE_CURRENT)
}
// RemoteViews object for the app widget layout
val remoteViews = RemoteViews(context.packageName, R.layout.appwidget).apply {
if (spoilers) {
setImageViewResource(R.id.btn_spoilers, R.drawable.avd_anim_turn_off_spoilers)
} else {
setImageViewResource(R.id.btn_spoilers, R.drawable.avd_anim_turn_on_spoilers)
}
setRemoteAdapter(R.id.appwidget_list_view, intent)
setEmptyView(R.id.appwidget_list_view, R.id.empty_view)
setOnClickPendingIntent(R.id.btn_refresh, pendingRefreshClickIntent)
setOnClickPendingIntent(R.id.btn_spoilers, pendingSpoilersClickIntent)
}
Log.i(TAG, "updateWidget: Calling updateWidget!") // This is logged
appWidgetManager.updateAppWidget(appWidgetId, remoteViews) // NO EFFECT FROM THIS CALL!!
}
}
我的 RemoteViewsService 和 RemoteViewsFactory:
class AppWidgetService: RemoteViewsService() {
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
return ListRemoteViewsFactory(this.applicationContext, intent)
}
class ListRemoteViewsFactory(private val context: Context, val intent: Intent): RemoteViewsFactory {
...
override fun onCreate() {
Log.i(TAG, "onCreate: created!") // Logged when I add the widget first time, not logged when I call updateAppWidget() from AppWidgetProvider
updateList()
}
override fun onDataSetChanged() {
Log.i(TAG, "onDataSetChanged: changed!")
updateList()
}
...
}
}
【问题讨论】:
标签: android android-appwidget remoteview appwidgetprovider