Android 14中AppWidget配置Activity无法启动:缺少PI发送方授权
解决Android 14 Widget配置Activity启动失败问题
问题背景
按标准流程实现Widget配置Activity后,Android 14上出现后台启动拦截错误,核心原因是系统自动发起的配置Intent未携带Context.BIND_ALLOW_ACTIVITY_STARTS标志,触发了Android 14的后台启动限制规则。
解决方案:接管配置Activity启动逻辑
通过移除XML中的自动配置声明,手动创建带权限标志的PendingIntent启动配置Activity,步骤如下:
1. 修改AppWidget配置XML
打开你的appwidget-provider配置文件(如res/xml/widget_info.xml),移除android:configure属性,避免系统自动启动配置Activity:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="180dp" android:minHeight="180dp" android:updatePeriodMillis="86400000" android:initialLayout="@layout/widget_layout" <!-- 移除以下自动配置声明 --> <!-- android:configure="com.minar.birday.activities.MinimalWidgetConfigurationActivity" --> android:widgetCategory="home_screen"> </appwidget-provider>
2. 重写AppWidgetProvider的onReceive方法
在你的AppWidgetProvider子类中,拦截ACTION_APPWIDGET_ADD事件,手动构建带权限标志的PendingIntent启动配置Activity:
@Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); String action = intent.getAction(); if (AppWidgetManager.ACTION_APPWIDGET_ADD.equals(action)) { int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { // 构建配置Activity的Intent Intent configIntent = new Intent(context, MinimalWidgetConfigurationActivity.class); configIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); // 创建携带权限标志的PendingIntent PendingIntent pendingIntent = PendingIntent.getActivity( context, appWidgetId, // 用appWidgetId作为请求码,避免重复PendingIntent冲突 configIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE | Context.BIND_ALLOW_ACTIVITY_STARTS ); try { // 启动配置Activity pendingIntent.send(); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } // 设置结果告知系统已处理Widget添加请求 setResult(context, Activity.RESULT_OK, configIntent); } } }
3. 确认配置Activity的Manifest声明
确保配置Activity已开启exported,并添加对应Intent Filter:
<activity android:name=".activities.MinimalWidgetConfigurationActivity" android:exported="true" android:theme="@style/YourWidgetConfigurationTheme"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> </intent-filter> </activity>
原理说明
通过手动创建携带Context.BIND_ALLOW_ACTIVITY_STARTS标志的PendingIntent,明确授权系统从该PendingIntent启动Activity,绕过Android 14的后台启动拦截。结合错误日志中realCallingUidHasAnyVisibleWindow: true的信息(实际调用方为前台Launcher),完全符合前台启动的安全规则,配置Activity即可像Android 13及以下版本一样正常运行。
内容的提问来源于stack exchange,提问作者m.i.n.a.r.
相关产品推荐
相关产品推荐

