访问文件 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 控制台应用更新因违反政策而被拒绝:所有文件访问权限
adb remount 权限被拒绝,但能够在 shell 中访问超级用户 -- android