Android 11存储适配咨询:公共目录读写及getExternalStorageDirectory替代方案
Android 11+ 公共目录存储适配方案(符合Google Play政策要求)
核心结论
- 完全可以使用Downloads等公共目录存储你的专属文件,满足「非应用私有目录、卸载不删除数据」的需求
- 无需申请
MANAGE_EXTERNAL_STORAGE权限,不会被Google Play驳回 getExternalStorageDirectory的官方替代方案是MediaStore API,适配Android 10+的分区存储规则
具体实现步骤
1. 权限配置
- AndroidManifest.xml 中移除
requestLegacyExternalStorage和MANAGE_EXTERNAL_STORAGE相关配置 - 仅保留必要权限:
<!-- Android 9及以下需要 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- Android 13+不需要额外写权限,应用自身创建的公共目录文件可直接访问 -->
2. Downloads目录下创建专属目录/写入文件实现(Java)
替换你原来的废弃代码,直接通过MediaStore写入Downloads的FileChat子目录:
// 要保存的文件名和内容 String fileName = "test_transfer.bin"; byte[] fileContent = ...; // 你的文件字节内容 ContentValues values = new ContentValues(); values.put(MediaStore.Downloads.DISPLAY_NAME, fileName); // 指定存储到Download/FileChat目录下 values.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + "/FileChat"); values.put(MediaStore.Downloads.MIME_TYPE, "application/octet-stream"); Uri uri = getContentResolver().insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values); if (uri != null) { try (OutputStream outputStream = getContentResolver().openOutputStream(uri)) { outputStream.write(fileContent); // 写入成功,可记录uri或者文件路径用于后续访问 } catch (IOException e) { e.printStackTrace(); } }
3. 其他操作适配
- 读取/修改/删除自有文件:Android 11+中,你当前应用版本创建的所有公共目录文件,可直接通过File路径或者对应Uri操作,无需额外权限
- 访问卸载前创建的旧文件:你已经实现了用户主动选择文件的Intent逻辑,刚好符合分区存储要求,通过系统文件选择器返回的Uri即可直接操作对应文件
- 目录文件列表读取:如果要读取当前应用创建的FileChat目录下的所有文件,可以通过MediaStore查询实现:
List<File> fileList = new ArrayList<>(); String[] projection = new String[]{MediaStore.Downloads.DATA}; String selection = MediaStore.Downloads.RELATIVE_PATH + "=?"; String[] selectionArgs = new String[]{Environment.DIRECTORY_DOWNLOADS + "/FileChat/"}; try (Cursor cursor = getContentResolver().query(MediaStore.Downloads.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs, null)) { while (cursor.moveToNext()) { String filePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Downloads.DATA)); fileList.add(new File(filePath)); } }
注意事项
- 应用卸载重装后,无法直接访问卸载前创建的文件,必须通过用户主动选择的方式获取权限,你的现有逻辑已经满足该要求
- 该方案完全符合Google Play的权限政策,不会因为存储权限问题被驳回
内容的提问来源于stack exchange,提问作者SWIK
相关产品推荐
相关产品推荐

