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

Android13调用Settings.ACTION_APPLICATION_DETAILS_SETTINGS触发SecurityException求助

Android 13中使用Settings.ACTION_APPLICATION_DETAILS_SETTINGS触发SecurityException问题分析

问题场景

用户拒绝权限时,通过以下代码引导至应用详情设置页:

Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
getActivity().startActivity(intent);

该代码在Android 13以下系统运行正常,但在Android 13中触发如下SecurityException:

Bad call made by uid 1000. Package "package name" does not belong to uid -1.
noteOperation
java.lang.SecurityException: Specified package "package name" under uid -1 but it is not
at com.android.server.appop.AppOpsService.verifyAndGetBypass(AppOpsService.java:4858)
at com.android.server.appop.AppOpsService.noteOperationUnchecked(AppOpsService.java:3586)
at com.android.server.appop.AppOpsService.noteOperationImpl(AppOpsService.java:3574)
at com.android.server.appop.AppOpsService.-$$Nest$mnoteOperationImpl(Unknown Source:0)
at com.android.server.appop.AppOpsService$CheckOpsDelegateDispatcher.lambda$noteOperation$4(AppOpsService.java:7928)
at com.android.server.appop.AppOpsService$CheckOpsDelegateDispatcher.$r8$lambda$oOwUoG55BBmJ6yiwhp3OAq3tQ30(Unknown Source:0)
at com.android.server.appop.AppOpsService$CheckOpsDelegateDispatcher$$ExternalSyntheticLambda4.apply(Unknown Source:32)
at com.android.server.policy.AppOpsPolicy.noteOperation(AppOpsPolicy.java:225)
at com.android.server.appop.AppOpsService$CheckOpsDelegateDispatcher.noteOperation(AppOpsService.java:7926)
at com.android.server.appop.AppOpsService.noteOperation(AppOpsService.java:3558)
at com.android.internal.app.IAppOpsService$Stub.onTransact(IAppOpsService.java:486)
at android.os.Binder.execTransactInternal(Binder.java:1316)
at android.os.Binder.execTransact(Binder.java:1280)

已在AndroidManifest.xml中设置android:exported="true",仍无法解决问题。

异常原因分析

从异常信息Specified package "package name" under uid -1 but it is not可以看出,系统在校验包名与UID的对应关系时,发现指定包名不属于UID -1(无效UID),核心原因如下:

  • 上下文有效性问题:代码中使用getActivity()获取上下文,若Fragment已脱离Activity(如onDestroyView之后调用),getActivity()可能返回失效实例,导致getPackageName()无法正确获取应用包名,进而系统解析时出现UID -1的错误。
  • Uri构造的潜在问题:使用Uri.fromParts("package", getActivity().getPackageName(), null)构造Uri时,若包名获取异常(如空值),可能导致Uri格式不符合系统预期,触发AppOps校验失败。
  • 多进程场景下的上下文混淆:若代码运行在非主进程中,不同进程的上下文可能导致包名获取错误,系统校验时无法匹配正确的UID。

解决方案

针对上述原因,可通过以下方式修复:

1. 确保上下文有效

在Fragment中调用时,先判断Fragment是否已附加到Activity,使用requireActivity()替代getActivity()(若未附加会直接抛出异常,提前暴露问题):

if (isAdded()) {
    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    Uri uri = Uri.parse("package:" + requireActivity().getPackageName());
    intent.setData(uri);
    requireActivity().startActivity(intent);
}

2. 改用更可靠的Uri构造方式

使用Uri.parse("package:" + 包名)替代Uri.fromParts,避免参数传递错误:

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.parse("package:" + getContext().getApplicationContext().getPackageName());
intent.setData(uri);
// 若在非Activity上下文启动,需添加FLAG_ACTIVITY_NEW_TASK
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(intent);

3. 多进程场景下的处理

若代码运行在多进程环境,确保使用getApplicationContext().getPackageName()获取全局包名,避免进程间上下文差异导致的错误。

内容的提问来源于stack exchange,提问作者CodingBruceLee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 22:17:41