You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Jetpack Glance创建Widget时如何同时获取WidgetId与PhotoItem?

问题解决:Glance Widget添加时获取WidgetId与关联数据

核心问题是Android 12+中PendingIntent默认不可修改,导致系统无法将AppWidgetManager.EXTRA_APPWIDGET_ID注入到回调Intent中,同时需要避免PendingIntent被重复覆盖。以下是具体修复步骤:

1. 修正PendingIntent的创建逻辑

修改PhotoPinnedReceiver的getPendingIntent方法,确保Intent可被系统修改,并使用唯一的requestCode避免覆盖:

companion object {
    private const val TAG = "PhotoPinnedReceiver"

    fun getPendingIntent(context: Context, photoItem: PhotoItem): PendingIntent {
        val intent = Intent(context, PhotoPinnedReceiver::class.java)
            .putExtra("photo_item", photoItem)
        
        // 根据系统版本设置正确的Flags
        val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
        } else {
            PendingIntent.FLAG_UPDATE_CURRENT
        }
        
        // 使用PhotoItem的唯一ID作为requestCode,避免不同请求的PendingIntent被覆盖
        return PendingIntent.getBroadcast(
            context,
            photoItem.id.hashCode(),
            intent,
            flags
        )
    }
}

2. 确认requestPinAppWidget调用逻辑

保持现有调用逻辑即可,若不需要给Widget传递初始配置数据,第二个参数可传null:

val photoItem: PhotoItem = ... 
val appWidgetManager = AppWidgetManager.getInstance(this)
if (appWidgetManager.isRequestPinAppWidgetSupported) {
    val widgetProvider = ComponentName(this, PhotoWidgetReceiver::class.java)
    val successCallback = PhotoPinnedReceiver.getPendingIntent(this, photoItem)
    appWidgetManager.requestPinAppWidget(widgetProvider, null, successCallback)
}

3. 验证onReceive中的数据获取

修改后,onReceive方法中将能正常获取widgetId和photoItem,关联存储后精准更新对应Widget:

override fun onReceive(context: Context, intent: Intent) {
    val widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
    if (widgetId == -1) {
        Log.w(TAG, "onReceive - widgetId not exist")
        return
    }

    val photoItem: PhotoItem? = intent.getParcelableExtra("photo_item")
    if (photoItem == null) {
        Log.w(TAG, "onReceive[$widgetId] photoItem is null")
        return
    }

    Log.w(TAG, "onReceive[$widgetId] $photoItem")
    CoroutineScope(Dispatchers.IO).launch {
        widgetRepo.saveWidgetInfo(widgetId, photoItem)
        // 仅更新当前添加的Widget,无需更新全部
        PhotoWidget().update(context, GlanceAppWidgetManager(context).getGlanceIdBy(widgetId))
    }
}

关键说明

  • FLAG_MUTABLE:Android 12及以上必须设置此Flag,允许系统向回调Intent中注入EXTRA_APPWIDGET_ID;
  • 唯一requestCode:使用PhotoItem的唯一标识作为requestCode,防止不同照片的PendingIntent被互相覆盖;
  • 精准更新:使用update而非updateAll,只刷新刚添加的Widget,提升性能。

内容的提问来源于stack exchange,提问作者dev.farmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 02:05:59