Android 11中如何访问/storage/emulated/0/Android/data/com.abc.appName目录?
在Android 11中访问Android/data目录的正确姿势
嘿,这个问题我太熟悉了!Android 11开始推行的**Scoped Storage(分区存储)**就是导致你代码返回null的核心原因——它把每个应用的Android/data/[包名]目录彻底隔离了,默认情况下你根本没法直接遍历整个Android/data目录,更别说访问其他应用的子目录了。下面分情况给你讲解决办法:
一、访问自己应用的Android/data目录(最推荐)
如果你的目标是访问自己应用的/storage/emulated/0/Android/data/com.abc.appName,完全不需要绕弯路,直接用系统提供的API就能拿到,还不需要额外权限:
// 获取自己应用的Android/data/com.abc.appName/files目录 File ownDataFilesDir = getExternalFilesDir(null); // 要是想拿到上级的com.abc.appName目录,调用getParent()就行 File ownRootDataDir = ownDataFilesDir.getParentFile(); // 现在就可以正常遍历这个目录下的文件了 File[] files = ownRootDataDir.listFiles(); if (files != null) { for (File file : files) { // 处理你的文件逻辑 } }
这个方法完全符合Android 11的存储规范,不会有任何权限问题。
二、访问其他应用的Android/data目录(受限)
如果是要访问其他应用的Android/data子目录,Android 11不允许直接通过文件路径访问,只能通过**SAF(存储访问框架)**让用户手动选择目标目录,代码示例如下:
1. 启动SAF选择目录
private static final int REQUEST_CODE_PICK_DIR = 1001; // 触发目录选择 private void pickOtherAppDataDir() { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); startActivityForResult(intent, REQUEST_CODE_PICK_DIR); }
2. 处理用户选择的结果
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_PICK_DIR && resultCode == RESULT_OK) { // 获取用户选择的目录Uri Uri treeUri = data.getData(); // 申请持久访问权限,避免重启后失效 getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); // 用DocumentFile来操作目录下的内容 DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri); if (pickedDir != null && pickedDir.isDirectory()) { for (DocumentFile file : pickedDir.listFiles()) { // 处理每个文件/子目录 } } } }
注意:这种方式必须由用户手动选择目录,你的应用不能静默访问——这是Android 11强制的安全限制,没有任何绕过的办法。
三、关于MANAGE_EXTERNAL_STORAGE权限(不推荐)
你可能听说过MANAGE_EXTERNAL_STORAGE权限,它可以让应用访问所有外部存储,但Google对这个权限的审核极其严格,只有文件管理器、备份工具这类必须全局访问存储的应用才能通过审核。如果你的应用不符合这个场景,别浪费时间:
1. 清单文件声明权限
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" />
2. 引导用户开启权限
if (!Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); startActivity(intent); }
再次强调:除非你的应用是专门的文件管理类工具,否则Google Play会拒绝你的上架申请,而且这种方式也破坏了分区存储的安全设计,尽量别用。
内容的提问来源于stack exchange,提问作者enthusiastdev




