Android系统 给第三方应用(system/app) 权限开启(不会弹授予权限窗口)

本文介绍如何使用DefaultPermissionGrantPolicy类中的方法对Android系统中的应用进行默认权限设置,并提供了一个具体的例子,展示如何修改系统中应用的存储空间权限。

frameworks/base/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java 类是对默认权限管理类

可以查看grantDefaultSystemHandlerPermissions 该方法,里面有就有授予权限类似方法,可以模仿

我们可以通过此类来对我们系统中存在的应用进行默认权限设置。 

下面举个例子,修改系统中应用存储空间权限:

    private void grantDefaultSystemHandlerPermissions(int userId) {
        ...
        grantStoragePermissionsToCustomApp(userId);// add 
        ...
    }

private void grantStoragePermissionsToCustomApp(int userId){
    final String []itemString = mService.mContext.getResources()
        .getStringArray(com.android.internal.R.array.storage_permission_custom_packagename);
    for (int i = 0; i < itemString.length; i++) {
        PackageParser.Package customPackage = getPackageLPr(itemString[i]);
        if ((customPackage != null) && doesPackageSupportRuntimePermissions(customPackage)) {
            grantRuntimePermissionsLPw(customPackage, STORAGE_PERMISSIONS, userId);
        }
    }
}
  • frameworks/base/core/res/res/values/ .xml文件 需要默认打开的应用包名列表
<string-array name="storage_permission_custom_packagename" translatable="false">
    <item>com.**.**</item>
</string-array>
<think>我们正在讨论的是Android SDK 29(即Android 10)中第三方应用获取SYSTEM_ALERT_WINDOW权限(悬浮窗权限)的问题。 根据Android官方文档,从Android 6.0(API 23)开始,SYSTEM_ALERT_WINDOW权限被列为危险权限,需要动态申请,并且用户必须在设置中明确授予。 在Android 10(API 29)中,这一机制仍然存在,并且变得更加严格。第三方应用(非系统应用)必须通过引导用户到设置页面手动开启悬浮窗权限,而不能直接通过代码授予。 根据引用[2]的内容,我们可以知道: - 在Android 6.0及以上版本,应用需要动态申请悬浮窗权限,即使用`Settings.canDrawOverlays(context)`检查权限,如果没有权限则跳转到设置页面让用户开启。 - 在引用[1]中提到了一个现象:当用户从设置页面开启权限后返回应用,立即调用`Settings.canDrawOverlays(context)`可能返回false,但过一段时间或界面刷新后可能变为true。这可能是由于权限状态更新延迟或Activity生命周期问题。 因此,在Android 10(API 29)中,第三方应用不能直接获取SYSTEM_ALERT_WINDOW权限,必须由用户手动在设置中开启。 另外,引用[3]提到在小米手机(Android 8.1)上存在兼容性问题,即使用`Settings.canDrawOverlays`和`AppOpsManager`检查权限结果不一致。这说明不同厂商可能有不同的实现,但总体流程不变:需要用户手动开启。 所以,结论是:在Android 10(API 29)中,第三方应用无法直接获取SYSTEM_ALERT_WINDOW权限,必须引导用户到设置页面开启。 回答结构: 1. 明确回答用户的问题:第三方应用Android 10上不能直接获取悬浮窗权限。 2. 解释为什么需要动态申请以及申请流程。 3. 提到可能的兼容性问题(如引用[1]和[3]中提到的)。 4. 给出一个标准的申请悬浮窗权限的代码示例(参考引用[2]并适配Android 10)。 注意:在Android 10中,窗口类型必须使用`TYPE_APPLICATION_OVERLAY`(而不是之前的`TYPE_SYSTEM_ALERT`等),但权限申请流程Android 6.0及以上版本一致。 代码示例:</think>在 Android SDK 29(Android 10)中,第三方应用**无法直接获取** `SYSTEM_ALERT_WINDOW` 悬浮窗权限。根据 Android 权限管理机制和引用内容,以下是关键点: ### 权限获取机制 1. **必须手动授权** - 从 Android 6.0(API 23)开始,`SYSTEM_ALERT_WINDOW` 被列为**危险权限**,需要动态申请 - 用户必须**手动在系统设置中开启**,无法通过代码直接授予(引用[2]) ```java // 检查权限 if (!Settings.canDrawOverlays(context)) { // 跳转到系统设置页 Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + context.getPackageName())); startActivity(intent); } ``` 2. **Android 10 的限制强化** - 在 Android 10 中,Google 收紧了悬浮窗权限策略: - 即使声明了 `<uses-permission>`,仍需用户手动授权 - 非系统应用无法绕过权限检查(引用[4]) - 窗口类型必须使用 `TYPE_APPLICATION_OVERLAY`(弃用 `TYPE_PHONE`) 3. **权限状态同步问题** - 用户开启权限后返回应用时,`Settings.canDrawOverlays()` **可能暂时返回 false**(引用[1]) - 需要等待系统广播更新或主动刷新 UI(如重启 Activity) ### 厂商兼容性问题 - **小米等定制 ROM** 可能存在检测不一致: ```java // 备用检测方法(针对厂商兼容性) AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE); int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, android.os.Process.myUid(), getPackageName()); boolean granted = (mode == AppOpsManager.MODE_ALLOWED); // 引用[3] ``` ### 总结 | 特性 | Android 10 (SDK 29) | |------|----------------------| | **直接获取权限** | ❌ 不可能 | | **动态申请流程** | ✅ 必须跳转系统设置页 | | **自动授权** | ❌ 禁止 | | **兼容性问题** | 需处理厂商 ROM 差异 | 第三方应用必须通过 `Settings.ACTION_MANAGE_OVERLAY_PERMISSION` 引导用户手动授权,且需注意权限状态同步延迟问题(引用[1][2][3])。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值