Android应用关闭时App Widget点击无响应、onReceive不触发问题求助
请不要将此问题标记为重复,我已翻遍StackOverflow未找到可行解决方案
我正在开发带有4个按钮的简单App Widget,当应用未在后台运行时,点击小部件按钮无法触发onReceive回调,我查找了全网可及的资料都未找到有效解决方案。
广播接收器已在Manifest中注册,配置如下:
<receiver android:name=".Amount.WidgetAdd" android:exported="true" > <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_add_info" /> </receiver>
我的onUpdate方法实现如下:
@Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { for (int i = 0; i<appWidgetIds.length; i++) { int id = appWidgetIds[i]; remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_add); remoteViews.setOnClickPendingIntent(R.id.image_joints, getPendingSelfIntent(context, JointOnClick)); remoteViews.setOnClickPendingIntent(R.id.image_bowls, getPendingSelfIntent(context, BowlOnClick)); remoteViews.setOnClickPendingIntent(R.id.image_pipe, getPendingSelfIntent(context, PipeOnClick)); remoteViews.setOnClickPendingIntent(R.id.image_more, getPendingSelfIntent(context, MoreOnClick)); Intent intent = new Intent(context, WidgetAdd.class); intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 420, intent, PendingIntent.FLAG_UPDATE_CURRENT); c = context; prefs = c.getSharedPreferences("WT", Context.MODE_PRIVATE); appWidgetManager.updateAppWidget(id, remoteViews); } super.onUpdate(context, appWidgetManager, appWidgetIds); }
我的onReceive方法实现如下:
@Override public void onReceive(Context context, Intent intent) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { context.startForegroundService(intent); } else { context.startService(intent); } if (JointOnClick.equals(intent.getAction())){ Toast.makeText(context, "Joint", Toast.LENGTH_SHORT).show(); try { AddJoint(); } catch (IOException e) { e.printStackTrace(); } } if (BowlOnClick.equals(intent.getAction())){ Toast.makeText(context, "Bowl", Toast.LENGTH_SHORT).show(); try { AddBowl(); } catch (IOException e) { e.printStackTrace(); } //your onClick action is here } if (PipeOnClick.equals(intent.getAction())){ //your onClick action is here Toast.makeText(context, "Pipe", Toast.LENGTH_SHORT).show(); try { AddPipe(); } catch (IOException e) { e.printStackTrace(); } } if (MoreOnClick.equals(intent.getAction())){ //your onClick action is here Toast.makeText(context, "More", Toast.LENGTH_SHORT).show(); Log.w("WidgetAdd", "More"); } super.onReceive(context, intent); }
请问大家有没有相关解决建议?
可行解决建议
- 首先检查
getPendingSelfIntent的实现,你没有贴出这个方法的代码,大概率是PendingIntent标记使用错误。Android 12及以上版本,PendingIntent需要显式指定FLAG_IMMUTABLE或者FLAG_MUTABLE标记,如果你之前仅传了FLAG_UPDATE_CURRENT,高版本系统会直接丢弃PendingIntent,进程被杀死后点击就没有响应。修改后创建PendingIntent的代码要按系统版本适配标记,示例如下:
private PendingIntent getPendingSelfIntent(Context context, String action) { Intent intent = new Intent(context, getClass()); intent.setAction(action); int flag = PendingIntent.FLAG_UPDATE_CURRENT; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { flag |= PendingIntent.FLAG_IMMUTABLE; } // 每个按钮的requestCode要设置不同的值,避免后续PendingIntent覆盖之前的配置 return PendingIntent.getBroadcast(context, 唯一的requestCode, intent, flag); }
- Manifest里的接收器要补充你自定义的四个点击Action的intent-filter,你现在仅注册了系统的UPDATE action,进程存活时广播可以内部传递,进程被杀死后系统匹配不到你自定义Action对应的接收器,就不会触发onReceive。在现有intent-filter节点里补充:
<action android:name="你的JointOnClick常量值" /> <action android:name="你的BowlOnClick常量值" /> <action android:name="你的PipeOnClick常量值" /> <action android:name="你的MoreOnClick常量值" />
- 检查onReceive里的服务启动逻辑,如果你启动的服务没有正确声明前台服务权限,或者没有在服务启动后5秒内调用
startForeground,Android 8及以上系统会直接杀死你的应用进程,导致看起来onReceive没有被触发。可以先注释掉服务启动的代码测试点击回调是否正常,再排查服务相关的问题。 - 部分国内定制ROM有后台进程管理、小部件权限限制,需要手动给应用开启「允许关联启动」「后台弹出界面」「小部件运行权限」,否则进程被杀死后小部件点击无响应。
内容的提问来源于stack exchange,提问作者Squash
相关产品推荐
相关产品推荐

