访问文件 Android 11 时权限被拒绝

Posted

技术标签:

【中文标题】访问文件 Android 11 时权限被拒绝【英文标题】:Permission denied while accessing file Android 11 【发布时间】:2021-09-16 18:13:25 【问题描述】:

我正在访问 android 中的文本文件,但出现了权限被拒绝 errno13 并且我已经授予了所有存储权限

这是显示的 logcat 错误

应用权限代码

【问题讨论】:

你的目标是 Android 11 吗? Android 不再允许访问外部存储,除非您正在开发文件管理器。如果是为了教育目的,你可以声明所有文件访问权限(成为文件管理员) 并且这个权限已经被声明(MANAGE_EXTERNAL_STORAGE),但是它被授予了吗? @op 检查您应用的系统设置 在清单中声明权限是旧方法。在现代 Android 版本中,这些权限可能还需要在运行时以 runtime permissions 的形式询问。 【参考方案1】:

来自Chaquopy FAQ:

从 API 级别 29 开始,Android 有一个 scoped storage policy,它可以防止直接访问外部存储,即使您的应用具有 READ_EXTERNAL_STORAGE 权限。相反,您可以使用system file picker,并将文件作为字节数组传递给 Python:

val REQUEST_OPEN = 0

fun myMethod() 
    startActivityForResult(
        Intent(if (Build.VERSION.SDK_INT >= 19) Intent.ACTION_OPEN_DOCUMENT
               else Intent.ACTION_GET_CONTENT).apply 
            addCategory(Intent.CATEGORY_OPENABLE)
            setType("*/*")
        , REQUEST_OPEN)


override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) 
    if (requestCode == REQUEST_OPEN && resultCode == RESULT_OK) 
        val uri = data!!.data!!
        // For Java, see https://***.com/a/10297073
        val content = contentResolver.openInputStream(uri)!!.use  it.readBytes() 
        myPythonModule.callAttr("process", content)
    

Python 函数可以随心所欲地访问文件内容:

def process(content):
    # `content` is already a bytes-like object, but if you need a standard bytes object:
    content = bytes(content)

    # If you need a file-like object:
    import io
    content_file = io.BytesIO(content)

    # If you need a filename (less efficient):
    import tempfile
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_file.write(content)
        filename = temp_file.name  # Valid only inside the `with` block.

【讨论】:

【参考方案2】:

除了获得这些权限(READ_EXTERNAL_STORAGE、 WRITE_EXTERNAL_STORAGE)在程序初始运行时,必须将以下代码添加到AndroidManifest.xml文件的tag中。

  android: requestLegacyExternalStorage = "true"

【讨论】:

Google 自 2021 年 5 月 1 日起更改其隐私政策。此后,Google Play 商店将不再接受此“(android: requestLegacyExternalStorage = "true")”。 如果应用面向 Android 11,则忽略此标志号

以上是关于访问文件 Android 11 时权限被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

Android:Google Play 控制台应用更新因违反政策而被拒绝:所有文件访问权限

Android 11 打开失败:EACCES(权限被拒绝)

adb remount 权限被拒绝,但能够在 shell 中访问超级用户 -- android

打开失败:EACCES(权限被拒绝)ANDROID 11

尝试使用 FileLock、Python 写入文件时权限被拒绝

已授予 Android 运行时权限,但仍被拒绝