You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

AOSP新增ACCESS_NEW_LOCATION权限无法识别的相关技术问询

解答你的AOSP权限定制问题

我来帮你逐个拆解解决,这些都是自定义系统权限时容易踩的坑:

1. 向AOSP中添加新权限的正确流程

你已经迈出了第一步,但完整流程还需要补充几个关键环节:

  • 补全权限字符串资源:你在Manifest里引用了@string/permlab_accessNewLocation@string/permdesc_accessNewLocation,得在frameworks/base/core/res/res/values/strings.xml里添加对应的文本内容,比如:
    <string name="permlab_accessNewLocation">访问新位置服务</string>
    <string name="permdesc_accessNewLocation">允许应用访问自定义的新位置服务,获取专属维度的位置数据</string>
    
  • 添加权限常量到Manifest.java:为了让AOSP内部代码能方便引用这个权限,需要在frameworks/base/core/java/android/Manifest.java里补充静态常量定义:
    public static final String permission.ACCESS_NEW_LOCATION = "android.permission.ACCESS_NEW_LOCATION";
    
  • 编译并刷入完整系统镜像:不要只编译单个模块,建议执行关键模块编译+系统镜像生成:
    # 先初始化编译环境
    source build/envsetup.sh
    lunch [你的设备目标型号]
    # 编译framework核心模块
    make framework -j8
    # 重新生成system镜像
    make snod
    
    之后用fastboot flash system system.img把新镜像刷入设备。
  • 验证权限存在性:刷入后在设备终端执行pm list permissions -g,就能看到你的自定义权限出现在LOCATION权限分组下了。

2. 让Android Studio识别该新增的AOSP权限

Android Studio默认用的是官方标准SDK,里面没有你的自定义权限,所以需要做以下操作:

  • 导出AOSP自定义SDK:在AOSP全量编译完成后,执行make sdk,会在out/host/linux-x86/sdk/[你的SDK版本]/路径下生成包含自定义权限的SDK包。
  • 配置Android Studio使用自定义SDK:打开IDE的File > Project Structure > SDK Location,把SDK路径替换为你刚导出的自定义SDK路径,这样IDE就能自动识别到你添加的权限了。
  • 临时应急方案:如果不想更换SDK,只是想消除IDE的红色警告,可以在项目根目录的lint.xml里添加规则:
    <lint>
        <issue id="UnknownPermission" severity="ignore" />
    </lint>
    
    但这种方法只是隐藏警告,IDE不会真正识别权限,长期来看还是用自定义SDK更规范。

3. 编写对应此权限的功能实现代码

权限本身只是一个"准入凭证",你需要在具体的功能逻辑里加入权限校验逻辑:

  • 定位对应系统服务:如果你的新权限和位置服务相关,就去修改位置服务的核心实现类frameworks/base/services/core/java/com/android/server/location/LocationManagerService.java
  • 添加权限校验逻辑:在提供新位置功能的方法里,先检查调用方是否持有该权限,比如:
    private void deliverNewLocationData(IBinder caller) {
        // 获取调用方的包名和UID
        String packageName = getPackageNameForUid(Binder.getCallingUid());
        // 执行权限检查
        int permissionCheck = checkPermission(android.Manifest.permission.ACCESS_NEW_LOCATION,
                Binder.getCallingPid(), Binder.getCallingUid());
        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("应用 " + packageName + " 未持有ACCESS_NEW_LOCATION权限");
        }
        // 这里写你的新位置功能核心逻辑
    }
    
  • 暴露API给应用层:如果要让第三方应用调用这个新功能,需要在应用层的入口类frameworks/base/core/java/android/location/LocationManager.java里添加公开方法:
    public void requestNewLocationUpdates(LocationListener listener) {
        // 先让应用自行检查权限(适配动态权限流程)
        if (mContext.checkSelfPermission(Manifest.permission.ACCESS_NEW_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("请先申请ACCESS_NEW_LOCATION权限");
        }
        // 跨进程调用系统服务的方法
        try {
            mService.deliverNewLocationData(listener.asBinder());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    
    这样第三方应用就能通过LocationManager调用你的新功能,同时必须先完成权限申请流程。

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

火山引擎 最新活动