Android Widget点击跳转传ID异常:多Widget均传递最新ID
解决Android多个Widget点击传递相同ID的问题
当创建多个桌面Widget时,点击任意Widget都会传递最后创建的Widget的ID,而非被点击的那个。这是因为所有Widget的PendingIntent使用了相同的requestCode,导致系统复用了同一个PendingIntent实例,后续更新会覆盖之前的extra数据。
问题根源
在updateAppWidget函数中,创建PendingIntent时传入的requestCode固定为0:
val pendingIntent: PendingIntent = PendingIntent.getActivity( context, 0, // 固定requestCode导致PendingIntent复用 intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE )
系统会根据requestCode、Intent的action、data等信息判断是否复用已有PendingIntent。当多个Widget使用相同requestCode且Intent结构一致时,后续创建的PendingIntent会覆盖之前的extra参数,最终所有Widget点击都使用最后一次设置的ID。
解决方案
将requestCode替换为每个Widget独有的appWidgetId,确保每个Widget的PendingIntent都是独立实例:
修改后的updateAppWidget函数代码:
internal fun updateAppWidget( context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int ) { val views = RemoteViews(context.packageName, R.layout.new_app_widget) val intent = Intent(context, MainActivity::class.java) intent.putExtra(Intent.EXTRA_UID, appWidgetId.toString()) // 使用appWidgetId作为requestCode,保证每个PendingIntent唯一 val pendingIntent: PendingIntent = PendingIntent.getActivity( context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) views.setOnClickPendingIntent(R.id.root_layout, pendingIntent) appWidgetManager.updateAppWidget(appWidgetId, views) }
原理说明
每个Widget的appWidgetId是系统分配的唯一标识,用它作为requestCode后,系统会为每个Widget创建独立的PendingIntent,不会互相覆盖。点击不同Widget时,对应的Intent会携带正确的appWidgetId参数传递给MainActivity。
内容的提问来源于stack exchange,提问作者Markus Laire
相关产品推荐
相关产品推荐

