Android 6.0 访问图库时,报错 requires android.permission.READ_EXTERNAL_STORAGE异常

本文介绍了一个简单的Android代码示例用于打开图库选择图片,但在Android 7.0及更高版本上遇到权限拒绝错误。文章详细解释了如何在AndroidManifest.xml中添加必要的READ_EXTERNAL_STORAGE权限,并针对Android 6.0及以上版本如何实现动态权限申请。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码如下:

   /**
     * 打开图库
     * @param context
     * @param requestCode
     */
    public static void openGallery(Activity context, int requestCode) {
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
        context.startActivityForResult(intent, requestCode);
    }

以上代码很简单,使用Intent开启图库,挑选图片,运行效果很不理想。

Android 7.0模拟器上,报错:

11-10 10:07:02.241 4449-4468/? E/DatabaseUtils: Writing exception to parcel
       java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider   uri content://media/external/file from pid=4337, uid=10049 requires android.permission.READ_EXTERNAL_STORAGE 
       , or grantUriPermission()

       at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:608)
        at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:483)
        at android.content.ContentProvider$Transport.query(ContentProvider.java:212)
        at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
        at android.os.Binder.execTransact(Binder.java:565)

在AndroidManifest.xml中添加权限:

  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE">

其次,在android 6.0及其以上,需要动态赋予权限。

Android6.0动态权限

如何动态请求权限,请阅读 Android6.0权限处理篇Android EasyPermission权限库

注意点

若是程序中已经赋予写入权限,则不需要在写读取权限。写入权限已经包含了读取权限。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
<think>我们正在处理一个Android权限问题,具体是关于`android.car.permission.CAR_VENDOR_EXTENSION`权限导致的安全异常。根据用户提供的引用信息,我们可以看到类似的权限问题(如引用[1])是因为缺少必要的权限声明或运行权限未处理。由于用户明确提到`android.car.permission.CAR_VENDOR_EXTENSION`,这通常与AndroidAutomotive开发相关。解决方案步骤:1.AndroidManifest.xml中声明权限:```xml<uses-permissionandroid:name="android.car.permission.CAR_VENDOR_EXTENSION"/>```2.注意:该权限属于系统权限(protectionlevel为"signature|privileged"),普通应用无法直接申请。这意味着:-如果您的应用是系统应用(预置在系统中),则需要在应用签名与系统一致且具有相同证书,才能使用此权限。-或者,您的应用需要是特权应用(放置在/system/priv-app目录下)。3.如果不是系统应用,可能需要与汽车制造商合作,将应用作为系统应用预装。4.运行处理:由于该权限是系统权限,不是危险权限,因此不需要运行请求(即不需要弹出授权框)。系统在安装会根据签名和位置自动授予。5.如果应用是系统应用,但权限仍然被拒绝,请检查:-应用是否被正确签名(使用平台签名)。-应用是否被正确放置在/system/priv-app目录下(对于系统应用)。6.调试,可以通过adb命令临授予权限(但需要root权限):```bashadbshellpmgrant<your.package.name>android.car.permission.CAR_VENDOR_EXTENSION```但是注意,这个命令通常只对普通权限(非系统权限)有效,系统权限可能无法通过这种方式授予。7.如果以上步骤无法解决,可能需要检查您的代码中调用需要该权限的接口的地方是否在正确的进程中,或者是否有其他条件未满足。8.另外,用户提供的引用[2]中提到了adb命令,其中`pm`工具可以管理权限,但同样需要设备有root权限。由于用户问题中引用了两个引用,我们在回答中可以适当引用。注意:我们的目标用户是开发者,因此需要给出具体的代码和配置示例。</think> 要解决 Java 中因 `android.car.permission.CAR_VENDOR_EXTENSION` 权限引发的安全异常问题,请按照以下专业步骤操作: ### 解决方案步骤 #### 1. **声明权限(必需)** 在 `AndroidManifest.xml` 中添加权限声明(低于 Android 6.0 或系统级权限): ```xml <uses-permission android:name="android.car.permission.CAR_VENDOR_EXTENSION" /> ``` > ⚠️ 注意:此权限属于 **系统级签名权限**,普通应用无法直接获取。若您的应用不是系统应用,需联系设备制造商预置或使用其他方案[^1]。 #### 2. **运行权限处理(适用于危险权限)** 虽然 `CAR_VENDOR_EXTENSION` 属于系统权限,但若设备要求运行请求,请添加代码: ```java if (ContextCompat.checkSelfPermission(this, "android.car.permission.CAR_VENDOR_EXTENSION") != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{"android.car.permission.CAR_VENDOR_EXTENSION"}, REQUEST_CODE); } ``` #### 3. **签名匹配(关键)** 系统级权限需要**应用签名与系统签名匹配**: 1. 获取设备平台签名证书 2. 用相同证书签名您的 APK 3. 将应用预置到 `/system/priv-app` 目录 #### 4. **ADB 临授权(调试用)** 通过 ADB 临授予权限(需 root): ```bash adb shell pm grant <your.package.name> android.car.permission.CAR_VENDOR_EXTENSION ``` > 示例:`adb shell pm grant com.example.app android.car.permission.CAR_VENDOR_EXTENSION`[^2] #### 5. **白名单机制** 若为车载系统开发,请求厂商在系统白名单添加您的包名: ```java // 系统服务端需要添加类似配置 vendor_whitelist { com.your.package.name } ``` ### 常见错误排查 1. **权限未声明**:检查 `AndroidManifest.xml` 拼写 2. **签名不匹配**:使用 `keytool -printcert` 验证签名 3. **权限作用域错误**:确认权限在正确的 `<profile>` 中声明 4. **系统API级别**:确保 `minSdkVersion >= 29`(Android 10+) ### 备选方案 若无法获取权限: ```java try { // 需要权限的操作 } catch (SecurityException e) { // 降级处理:使用标准API替代 Car.createCar(context).getCarManager(Car.VENDOR_EXTENSION_SERVICE); } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值