如何处理Android分区存储向后兼容 解决低版本图库保存失败问题
问题根因
Android系统存储权限机制随版本迭代存在差异:
- Android 10(API 29)及以上版本启用分区存储模式,通过
MediaStore向公共图库写入文件不需要申请存储权限,所以你的代码在Android10、11上运行正常 - Android 9(API 28)及以下版本,向公共存储写入文件必须申请
WRITE_EXTERNAL_STORAGE危险权限,你当前清单没有声明权限、也没有动态申请逻辑,所以触发权限拒绝报错。
修复步骤
1. 声明Manifest权限
在AndroidManifest.xml中添加适配多版本的权限声明:
<!-- 安卓9及以下需要的写存储权限,安卓10+系统会自动忽略该权限申请 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
加上maxSdkVersion=28是为了避免在高版本系统上出现不必要的权限申请提示
2. 添加动态权限申请逻辑
WRITE_EXTERNAL_STORAGE属于危险权限,安卓6.0(API23)到安卓9的版本,需要用户手动授权后才能调用存图逻辑,存图前先做权限判断:
// 存图执行前先校验权限 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q && ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // 无权限,先发起权限申请,REQUEST_CODE_WRITE_STORAGE可自定义为任意int值 ActivityCompat.requestPermissions( mContext, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_CODE_WRITE_STORAGE ) return } // 已有权限,直接调用存图方法 saveImageToStorage(mContext, bitmap, filename)
在DisplayActivity中重写onRequestPermissionsResult接收授权结果,用户同意授权后再执行存图操作即可。
3. 兼容低版本的ContentValues参数
MediaStore.Images.Media.RELATIVE_PATH是API29才新增的字段,安卓9及以下系统无法识别,需要做版本判断,避免低版本出现未知异常:
val values = ContentValues().apply { put(MediaStore.Images.Media.DISPLAY_NAME, filename) put(MediaStore.Images.Media.MIME_TYPE, mimeType) // 仅API29及以上添加RELATIVE_PATH字段 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { put(MediaStore.Images.Media.RELATIVE_PATH, directory) } }
低版本系统会自动把图片存在公共图库的默认路径下,不影响最终保存结果
内容的提问来源于stack exchange,提问作者AndroLearner
相关产品推荐
相关产品推荐

