Android framework给非system app添加权限

文章介绍了如何在不进行动态申请权限的情况下,使非系统进程在开机时就能获得系统权限。通过在frameworksaseservicescorejavacomandroidserver中的代码修改,添加grantDefaultSystemHandlerPermissions方法,并在privapp-permissions-platform.xml文件中配置所需权限,可以为特定app如com.test.demo赋予相机、联系人、存储等敏感权限。

非系统进程/app如何在不动态申请或者刚开机的情况下获取系统权限

适用场景:

  • 当app不需要动态申请权限页面的提示时
  • 在开机启动需要直接赋予权限
  • 某些开机运行的app中有对某数据库的监听,需要立即响应onchange事件

代码流程:

1.在frameworks\base\services\core\java\com\android\server\pm
DefaultPermissionGrantPolicy.java中添加方法,其中STORAGE_PERMISSIONS等静态常量为所需要申请的权限数组.

private void grantDefaultSystemHandlerPermissions(int userId)

    private void grantDefaultSystemHandlerPermissions(int userId) {
        Log.i(TAG, "Granting permissions to default platform handlers for user " + userId);
        final PackagesProvider locationPackagesProvider;
        ......
        
         synchronized (mService.mPackages) {
    		//就是下面这里增加一个方法
    		grantStoragePermissionsToCustomApp(userId);
                // Installer
                PackageParser.Package installerPackage = getSystemPackageLPr(
                        mService.mRequiredInstallerPackage);
                if (installerPackage != null
                        && doesPackageSupportRuntimePermissions(installerPackage)) {
                    grantRuntimePermissionsLPw(installerPackage, STORAGE_PERMISSIONS, true, userId);
                }
     
        ......
    }
     
    private void grantStoragePermissionsToCustomApp(int userId){
            final String []itemString = {"com.test.demo"};
            for (int i = 0; i < itemString.length; i++) {
                PackageParser.Package customPackage = getPackageLPr(itemString[i]);
                if ((customPackage != null) && doesPackageSupportRuntimePermissions(customPackage)) {
    				grantRuntimePermissionsLPw(customPackage, MICROPHONE_PERMISSIONS, userId);
                    grantRuntimePermissionsLPw(customPackage, STORAGE_PERMISSIONS, userId);
                    grantRuntimePermissionsLPw(customPackage, CONTACTS_PERMISSIONS, userId);
                    //grantRuntimePermissionsLPw(customPackage, LOCATION_PERMISSIONS,true, userId);
                    grantRuntimePermissionsLPw(customPackage, PHONE_PERMISSIONS, userId);
                    grantRuntimePermissionsLPw(customPackage, CAMERA_PERMISSIONS, userId);
                }
            }
        }

2.然后需要在frameworks\base\data\etc\privapp-permissions-platform.xml文件中加上所需要的所有权限:

    <privapp-permissions package="com.test.demo">
    		<permission name="android.permission.CAMERA"/>
            <permission name="android.permission.READ_CONTACTS"/>
            <permission name="android.permission.ACCESS_FINE_LOCATION"/>
            <permission name="android.permission.RECORD_AUDIO"/>
            <permission name="android.permission.READ_PHONE_STATE"/>
            <permission name="android.permission.WRITE_EXTERNAL_STORAGE"/>
            <permission name="android.permission.SEND_SMS"/>
    </privapp-permissions>
<think> 我们正在讨论的是在Android R(API 30)的Framework层面为没有后台运行权限的应用程序添加后台运行权限。这涉及到修改系统级的权限控制逻辑。请注意,这通常需要修改Android系统源代码,并且需要重新编译系统镜像。普通应用开发者无法直接修改Framework层,但如果是设备制造商或系统开发者,可以按照以下步骤进行。 关键点:在Android系统中,后台运行权限(尤其是后台位置权限)是受严格控制的。在Framework层修改,意味着我们要改变系统对特定应用或所有应用的权限检查行为。 步骤: 1. **定位权限检查的代码位置**: 在Android Framework中,权限检查通常发生在`ActivityManagerService`(AMS)和`PermissionManagerService`中。具体到后台权限,我们需要关注与位置权限相关的检查逻辑。 2. **修改权限检查逻辑**: 我们可以通过修改AMS中关于权限检查的代码,跳过对特定应用的后台权限检查。例如,在`ActivityManagerService`中,有一个方法`checkPermission`,我们可以在此处添加逻辑:如果检测到是我们想要放行的应用,并且权限是后台位置权限(`android.permission.ACCESS_BACKGROUND_LOCATION`),则直接返回`PackageManager.PERMISSION_GRANTED`。 3. **添加应用白名单**: 为了避免对所有应用都放行,我们可以定义一个系统白名单(例如,通过包名列表),只有白名单中的应用才能被授予后台权限。 4. **重新编译并刷入系统**: 修改完成后,需要重新编译Android系统(通常是`services`模块),并将新的系统镜像刷入设备。 具体代码修改示例(基于Android 11源代码): 假设我们要在`checkPermission`方法中修改,该方法位于`frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java`。 我们可以在方法开始处添加如下代码: ```java // 假设我们有一个系统白名单,包含允许后台权限的包名 private static final String[] BACKGROUND_PERMISSION_WHITELIST = { "com.example.app1", "com.example.app2" }; // 在checkPermission方法中添加 @Override public int checkPermission(String permission, int pid, int uid) { // 如果是后台位置权限 if (permission.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) { // 获取调用者的包名 String[] packages = getPackageManager().getPackagesForUid(uid); if (packages != null && packages.length > 0) { String packageName = packages[0]; // 检查包名是否在白名单中 for (String allowedPkg : BACKGROUND_PERMISSION_WHITELIST) { if (allowedPkg.equals(packageName)) { // 直接返回授予权限 return PackageManager.PERMISSION_GRANTED; } } } } // 否则继续正常的权限检查流程 return super.checkPermission(permission, pid, uid); } ``` 注意:以上代码仅为示例,实际实现可能需要更严谨的处理(例如,考虑多包名的情况、用户ID等)。此外,我们还需要考虑权限检查的其他路径,因为权限检查可能发生在多个地方。 5. **其他注意事项**: - 这种修改会绕过系统的权限检查机制,可能带来安全风险,请谨慎使用。 - 在Android R之后,后台权限的管理更加严格,修改系统代码可能会导致CTS测试失败,影响设备认证。 6. **替代方案(无需修改Framework)**: 如果可能,建议应用通过正常渠道申请后台权限。如果应用必须后台运行,可以考虑使用前台服务(需要可见通知),或者利用系统允许的后台运行场景(如绑定服务、同步适配器等)。 由于修改Framework层需要系统级别的开发权限,并且涉及系统安全机制,请确保在充分理解后果的情况下进行。 参考引用: - 在AndroidManifest.xml中添加权限(引用[1])是应用层的基本要求,但我们在Framework层修改后,应用即使没有在manifest中声明后台权限也可能被授予(不推荐,因为应用可能不会声明,但系统检查时我们跳过了,这样不安全)。因此,我们建议只对manifest中声明了后台权限的应用进行白名单处理。 - 启动设置界面(引用[2])是应用层引导用户去设置权限的方法,而我们这里讨论的是系统层直接授予权限,无需用户操作。 - PMS(PackageManagerService)在更新过程中会处理apk文件和权限(引用[3]),因此如果我们修改了权限授予逻辑,需要确保PMS在更新应用时不会覆盖我们的修改。 相关问题: 1. 如何在不修改系统源码的情况下为应用获取后台运行权限? 2. Android Framework层中权限检查的流程是怎样的? 3. 修改Android系统源码后如何通过CTS测试? 4. 如何为特定应用添加系统白名单? 注意:以上Framework层的修改需要系统开发经验,并且需要重新编译系统。对于普通应用开发者,建议遵循标准的权限申请流程。 </think>在Android R(API 30)的Framework层面为应用添加后台运行权限,需要修改系统核心组件。以下是关键步骤和代码实现: ### 1. **修改权限检查逻辑** 在`ActivityManagerService`中重写权限检查方法: ```java // frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java @Override public int checkPermission(String permission, int pid, int uid) { // 添加白名单逻辑 if (permission.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) { String packageName = getPackageManager().getNameForUid(uid); if (isWhitelistedApp(packageName)) { // 自定义白名单检测 return PackageManager.PERMISSION_GRANTED; } } return super.checkPermission(permission, pid, uid); } private boolean isWhitelistedApp(String packageName) { // 从系统配置读取白名单 return SystemProperties.get("persist.sys.bg_whitelist", "") .contains(packageName); } ``` ### 2. **添加白名单配置接口** 在`SystemProperties`中设置白名单: ```java // 通过ADB添加应用到白名单 adb shell setprop persist.sys.bg_whitelist "com.example.app1,com.example.app2" // 或通过系统API动态配置 public void addToBackgroundWhitelist(String packageName) { String current = SystemProperties.get("persist.sys.bg_whitelist", ""); if (!current.contains(packageName)) { SystemProperties.set("persist.sys.bg_whitelist", current + "," + packageName); } } ``` ### 3. **修改包管理器逻辑** 在`PackageManagerService`中跳过权限检查: ```java // frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java private boolean shouldGrantBackgroundPermission(String permission, PackageSetting ps) { return permission.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION) && isWhitelistedApp(ps.pkg.packageName); } ``` ### 4. **处理权限变更通知** ```java // 在权限更新时刷新应用状态 private void updatePermissionState(String packageName) { Intent intent = new Intent(Intent.ACTION_PACKAGE_PERMISSION_CHANGED); intent.setData(Uri.fromParts("package", packageName, null)); mContext.sendBroadcast(intent); } ``` ### 关键注意事项 1. **系统签名要求** 修改Framework需要系统签名权限,需在`AndroidManifest.xml`添加: ```xml <uses-permission android:name="android.permission.INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" /> ``` 2. **CTS兼容性** 修改可能影响CTS认证,需在`/etc/permissions/`中添加兼容性配置: ```xml <!-- vendor/etc/permissions/privapp-permissions-platform.xml --> <privapp-permissions package="com.example.permmanager"> <permission name="android.permission.GRANT_RUNTIME_PERMISSIONS"/> </privapp-permissions> ``` 3. **安全风险控制** - 白名单应加密存储 - 仅允许系统应用修改白名单 - 添加审计日志: ```java Slog.i(TAG, "Background permission granted to " + packageName); ``` ### 验证方法 ```bash # 检查权限状态 adb shell dumpsys package com.example.app | grep ACCESS_BACKGROUND # 测试后台服务启动 adb shell am start-service -a com.example.app/.BackgroundService ``` > **警告**:此类修改会绕过Android的安全模型,仅适用于专用设备(如企业定制设备),普通应用商店上架应用禁止使用[^1][^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值