如何在不获取所有文件管理权限的情况下在/storage/emulated/0/中创建目录
解决Android 11下无需全文件权限创建外部目录的问题
刚好碰到过类似的场景,Android 11(API 30)引入的**Scoped Storage(分区存储)**彻底改变了外部存储的访问规则,你之前直接在根目录创建自定义目录的代码失效,就是因为这个规则限制——除非申请全文件访问权限,否则没法直接操作根目录。不过不用急,有几种不用全权限的方案可以解决:
方案1:用应用专属外部存储目录(最推荐)
Android给每个应用都分配了专属的外部存储区域,这个区域不需要任何额外权限,而且卸载应用时会自动清理,完全符合你的需求。路径默认是/storage/emulated/0/Android/data/[你的包名]/files/,用户一般不会手动修改这里的文件,很安全。
修改后的代码:
// 获取应用专属外部存储的根目录,传入null表示默认的files目录 File myFolder = new File(getExternalFilesDir(null), "testDir"); if (!myFolder.exists() || myFolder.isFile()) { if (myFolder.isFile()) { Toast.makeText(getApplicationContext(), "'testDir' exists as file", Toast.LENGTH_LONG).show(); return; } try { // 用mkdirs()替代mkdir(),能自动创建不存在的父目录,更稳妥 if (myFolder.mkdirs()) { Toast.makeText(getApplicationContext(), "Directories created successfully", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "Failed to create directory", Toast.LENGTH_LONG).show(); } } catch (Exception e) { Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show(); } }
方案2:利用系统预设的媒体目录(比如Downloads、Pictures)
如果你的目录是用来存放媒体文件(图片、文档、下载内容等),可以用MediaStore API来创建,不需要全文件权限,Android 10+甚至连WRITE_EXTERNAL_STORAGE都不用申请。
举个在Downloads目录下创建testDir的例子:
ContentValues values = new ContentValues(); // 指定相对路径,Download是系统预设目录,后面跟你的自定义目录 values.put(MediaStore.Downloads.RELATIVE_PATH, "Download/testDir/"); // 必须插入一个占位文件才能触发目录创建,这里用一个空的占位文件 values.put(MediaStore.Downloads.DISPLAY_NAME, "temp_placeholder"); values.put(MediaStore.Downloads.MIME_TYPE, "application/octet-stream"); Uri uri = getContentResolver().insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values); if (uri != null) { // 目录创建成功后,可以删掉这个占位文件(可选) getContentResolver().delete(uri, null, null); Toast.makeText(getApplicationContext(), "Directory created in Downloads", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "Failed to create directory", Toast.LENGTH_LONG).show(); }
方案3:非要在根目录创建?(不推荐)
如果你的业务场景必须在外部存储根目录创建目录,那只能申请MANAGE_EXTERNAL_STORAGE权限,但要注意两个坑:
- 这个权限不能通过常规的权限请求弹窗获取,必须引导用户去系统设置里手动开启
- Google Play对这个权限的审核非常严格,只有文件管理器、备份工具这类核心功能需要全文件访问的应用才能通过
申请权限的代码逻辑:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // 检查是否已经获取全文件权限 if (!Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent); } else { // 权限已获取,执行你原来的创建目录逻辑 File myFolder=new File(Environment.getExternalStorageDirectory(),"testDir"); // ... 你原来的判断和创建代码 } }
总的来说,优先选方案1或者方案2,既符合Android的存储规范,又不用申请敏感的全文件权限,避免后续的审核和兼容性问题。
内容的提问来源于stack exchange,提问作者Barni156
相关产品推荐
相关产品推荐

