Android 11适配时scoped storage下getExternalStoragePublicDirectory返回异常
问题根本原因
- targetSdk=29(Android 10)场景
- 安卓10首次引入分区存储机制,默认禁用
Environment.getExternalStoragePublicDirectory()方法,返回null。在清单中添加android:requestLegacyExternalStorage="true"即可申请启用旧版存储权限,恢复该方法的正常返回逻辑,这属于系统预期行为。
- targetSdk=30(Android 11+)场景
- 安卓11起
requestLegacyExternalStorage配置完全失效,无论是否添加都不会生效。同时官方调整了getExternalStoragePublicDirectory()的返回逻辑:方法会正常返回/storage/emulated/0/Pictures这类公共路径,但应用没有该路径的读写权限,即使申请了存储权限也无法直接操作该路径下的文件,这就是你遇到的不符合预期的表现,属于系统设计的正常行为。
适配解决方案
根据业务需求选择对应适配方案即可:
- 若需要存储图片到公共相册,可供系统图库等其他应用访问:
使用MediaStore API完成写入,核心逻辑如下:
构造ContentValues对象,设置MediaStore.Images.Media.RELATIVE_PATH为Environment.DIRECTORY_PICTURES/你的自定义目录名,调用getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)得到文件Uri,再打开输出流写入图片数据即可。安卓11+向公共媒体目录写入自身创建的文件不需要额外申请存储权限。 - 若仅需要存储应用私有图片,不需要对外暴露:
直接调用context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)获取应用专属目录路径,该目录读写不需要任何权限,卸载应用时会同步删除,所有安卓版本兼容。 - 若需要访问其他应用创建的公共目录下的图片:
安卓13及以上申请READ_MEDIA_IMAGES权限,安卓11-12申请READ_EXTERNAL_STORAGE权限,通过MediaStore查询获取目标文件的Uri进行访问,禁止直接使用原始文件路径操作。
内容的提问来源于stack exchange,提问作者mik8305
相关产品推荐
相关产品推荐

