安卓10报错:open failed: EACCES (Permission denied)

本文详细介绍了在Android Q上遇到的存储权限问题及其解决方案。通过在AndroidManifest.xml中添加特定属性,可以解决访问外部存储时出现的权限拒绝错误,避免了 Scoped Storage 引入的限制。

一、环境

项目的版本设置:

compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 26
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

测试用的小米mix2s,安卓版本是10.0

我的demo地址https://github.com/Wangzg97/MyApplication

二、解决方法

刚开始在AndroidManifest.xml已经声明了读写权限,

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

但在访问相册的时候,还是报错:

open failed: EACCES (Permission denied)

网上的从手机设置里改权限、或者随用随检验存储权限啥的在我这都不管用。

又发现了一个有效方法,在AndroidManifest.xml添加一句:

android:requestLegacyExternalStorage="true"

位置如下

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:requestLegacyExternalStorage="true">

然后成功解决问题!

三、原因

Android Q分区存储权限变更及适配问题:

为了让用户更好地控制自己的文件,并限制文件混乱的情况,Android Q修改了APP访问外部存储中文件的方法。外部存储的新特性被称为Scoped Storage。

Android Q仍然使用READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE作为面向用户的存储相关运行时权限,但现在即使获取了这些权限,访问外部存储也受到了限制。APP需要这些运行时权限的情景发生了变化,且各种情况下外部存储对APP的可见性也发生了变化。

具体请参考:https://blog.youkuaiyun.com/irizhao/article/details/94121551

在 Android 系统中,`android.system.ErrnoException: open failed: EACCES (Permission denied)` 错误通常表示应用程序没有足够的权限来访问文件或目录。以下是一些解决此错误的方法: ### 声明权限 在 `AndroidManifest.xml` 文件中声明所需的权限。若需要读写外部存储,需添加以下权限声明: ```xml <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ``` 对于网络访问等其他操作,也需声明相应权限,例如网络访问权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> ``` 如果需要挂载和卸载文件系统,可添加如下权限声明,但要注意该权限可能需要特殊处理: ```xml <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" tools:ignore="ProtectedPermissions" /> ``` 上述权限声明可参考引用内容 [^1][^2]。 ### 动态权限申请 从 Android 6.0(API 级别 23)开始,部分危险权限需要在运行时动态申请。以下是申请读写外部存储权限的示例代码: ```java if (Build.VERSION.SDK_INT >= 23) { int REQUEST_CODE_PERMISSION_STORAGE = 100; String[] permissions = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; for (String str : permissions) { if (context.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) { context.requestPermissions(permissions, REQUEST_CODE_PERMISSION_STORAGE); return; } } } ``` 此方法依据引用 [^3] 提供的思路。 ### Android 10 及以上版本的特殊处理 在 Android 10 及以上版本,即使权限申请成功,仍可能出现该错误。可在 `AndroidManifest.xml` 的 `application` 标签下添加 `android:requestLegacyExternalStorage="true"` 来启用旧的存储访问模式: ```xml <application android:requestLegacyExternalStorage="true" ... > ... </application> ``` 这一处理方式参考了引用 [^4]。 ### 检查文件路径和权限 确保要访问的文件或目录路径正确,并且应用程序有足够的权限访问。若文件位于外部存储的特定目录,要确保该目录可被应用程序访问。 ### 检查文件是否存在 在尝试打开文件之前,可先检查文件是否存在,避免因文件不存在而引发权限错误。示例代码如下: ```java File file = new File("your_file_path"); if (file.exists()) { // 打开文件的操作 } else { // 处理文件不存在的情况 } ```
评论 25
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值