manifest权限添加无效

在InCallUI中添加了一段代码
private boolean isDreaming(){
boolean isDreaming = false;
        try{
IDreamManager mDreamManager = IDreamManager.Stub.asInterface(
                ServiceManager.getService(DreamService.DREAM_SERVICE));
if(mDreamManager!=null){
            isDreaming = mDreamManager.isDreaming();
        android.util.Log.i("fullincall11","mDreamManager = "+mDreamManager.isDreaming());
        }
        } catch (Exception e) {
android.util.Log.i("fullincall11","e = "+e);
}
return isDreaming;
}


用来判断是否处于屏保状态,程序运行提示需要权限“android.permission.READ_DREAM_STATE”,可是在Manifest中添加之后,依然提示缺少该权限。
 解决办法:
通过在framework/base/core/res/Manifest.xml中找到
    <!-- Allows applications to read dream settings and dream state.
         @hide -->
    <permission android:name="android.permission.READ_DREAM_STATE"
        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
        android:protectionLevel="signature" />


权限android.permission.READ_DREAM_STATE 的android:protectionLevel="signature",而我们一般直接添加的权限的protectionLevel都是normal。
网上找了一段资料:
在声明权限时需要一个android:protectionLevel的属性,它代表“风险级别”。必须是以下值之一:
normal、dangerous、signature、signatureOrSystem。
normal表示权限是低风险的,不会对系统、用户或其他应用程序造成危害。
dangerous表示权限是高风险的,系统将可能要求用户输入相关信息,才会授予此权限。
signature告诉Android,只有当应用程序所用数字签名与声明此权限的应用程序所有数字签名相同时,才能将权限授给它。
signatureOrSystem告诉Android,将权限授给具有相同数字签名的应用程序或Android包类,这一级别适用于非常特殊的情况,比如多个供应商需要通过系统影像共享功能时。
另外一个是android:permissionGroup属性,表示一个权限组。可以将权限放在一个组中,但对于自定义权限,应该避免设置此属性。如果确实希望设置此属性,可以使用以下属性代替:android.permission-group.SYSTEM_TOOLS。
从资料中分析,应该是签名的问题。最终将Dialer的LOCAL_CERTIFICATE := shared修改为LOCAL_CERTIFICATE := platform解决了问题。
<think>嗯,我现在需要解决在Android应用中正确配置文件读写权限的问题。首先,我应该从哪里开始呢?记得不同的Android版本有不同的权限管理机制,可能得分开处理。比如在Android 6.0(API 23)之后,应用需要动态申请权限,而不仅仅是声明在清单文件里。用户提到的Android 11的问题,动态申请可能也不够,可能需要其他配置。 首先,基础的部分是在AndroidManifest.xml里声明权限。比如读写外部存储的权限,应该添加<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>和<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>。不过,对于Android 10及以上,作用域存储可能限制访问外部存储,可能需要调整。 然后动态申请权限的部分,需要在运行时请求用户授权。使用ActivityResultContracts.RequestPermission或者RequestMultiplePermissions。比如在Activity或Fragment中检查是否有权限,没有的话就弹窗请求。但用户提到Android 11以上即使动态申请了也无效,可能需要检查是否正确地处理了返回结果,或者是否有其他配置问题。 接下来是Android 7.0以上的FileProvider配置。在AndroidManifest.xml里定义FileProvider,指定authorities为应用包名加.FileProvider,然后配置meta-data指向xml资源文件,里面指定可访问的路径。比如在res/xml下创建file_paths.xml,添加外部存储路径或缓存目录。这样在访问文件URI时,使用FileProvider.getUriForFile来生成content://URI,避免使用file://导致的异常。 关于Android 11的问题,用户提到手动给予权限没有按钮,可能是因为在清单中没有正确声明,或者权限被标记为无效。Android 11引入了MANAGE_EXTERNAL_STORAGE权限,但普通应用不应该使用这个,而是遵循作用域存储。可能需要检查应用是否需要访问特定目录,比如使用MediaStore或者选择文档的方式让用户指定文件。 另外,用户提到的flutter_downloader库需要配置FileProvider,可能涉及到跨包名的配置,确保authorities一致。比如在AndroidManifest中的FileProvider的authorities属性应该和代码中使用的完全一致,包括包名部分,否则会出错。 还有,对于Android 11,应用可能需要在清单中添加android:requestLegacyExternalStorage="true"来暂时停用作用域存储,但这只是临时解决方案,因为Android 11以后可能不再支持。所以需要考虑适配作用域存储,使用应用专属目录或MediaStore API来访问公共目录的文件。 总结一下步骤:1. 声明静态权限;2. 动态申请权限;3. 处理FileProvider配置;4. 适配Android 11及以上的作用域存储;5. 测试不同版本的兼容性。可能还需要处理文件路径的访问方式,避免直接使用绝对路径,而是通过ContentResolver或者FileProvider来访问。</think>### 如何在Android应用中正确配置文件读写权限? #### 一、基础权限配置 1. **静态权限声明** 在`AndroidManifest.xml`中添加以下权限: ```xml <!-- 低于Android 13的读写权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Android 13及以上需申请媒体文件权限 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> ``` 2. **动态权限申请**(Android 6.0+) 在代码中检查并请求权限: ```kotlin val permissions = arrayOf( Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE ) if (ContextCompat.checkSelfPermission(this, permissions[0]) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE) } ``` **注意**:Android 11(API 30)及以上版本,即使动态申请权限,仍需适配作用域存储[^2]。 --- #### 二、FileProvider配置(Android 7.0+) 1. **定义FileProvider** 在`AndroidManifest.xml`中添加: ```xml <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.FileProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> ``` 2. **配置可访问路径** 创建`res/xml/file_paths.xml`文件: ```xml <paths> <external-path name="external_files" path="." /> <cache-path name="cache_files" path="." /> </paths> ``` 3. **生成Content URI** ```kotlin val file = File(context.getExternalFilesDir(null), "example.jpg") val uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { FileProvider.getUriForFile(context, "${context.packageName}.FileProvider", file) } else { Uri.fromFile(file) } ``` --- #### 三、Android 11+适配 1. **作用域存储限制** - 公共目录(如`Downloads`、`Pictures`)需通过`MediaStore` API访问。 - 应用专属目录(`getExternalFilesDir()`)无需权限。 2. **临时兼容方案** 在`AndroidManifest.xml`中添加: ```xml <application ... android:requestLegacyExternalStorage="true"> ``` **注**:此属性仅对Android 10-12有效,Android 13+强制作用域存储。 --- #### 四、常见问题解决 1. **权限被拒绝但用户已授权** - 检查`FileProvider`的`authorities`是否与应用包名完全一致[^3]。 - 确保`file_paths.xml`中路径配置正确。 2. **Android 11无法手动授权** - 确认应用未请求`MANAGE_EXTERNAL_STORAGE`权限(仅限特定场景使用)。 - 优先使用应用专属目录或`MediaStore` API。 --- #### 五、最佳实践 - 优先使用`Context.getExternalFilesDir()`存储私有文件。 - 通过`Intent.ACTION_OPEN_DOCUMENT`让用户主动选择文件。 - 对公共文件使用`MediaStore` API(如插入图片到相册): ```kotlin ContentValues().apply { put(MediaStore.Images.Media.DISPLAY_NAME, "photo.jpg") put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") }.also { values -> contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values) } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值