Android 9插入媒体文件时App闪退,已申请权限仍报错如何解决?
问题根因
- 媒体库类型和存储路径不匹配:你向
MediaStore.Video.Media.EXTERNAL_CONTENT_URI插入视频数据,但低于Android Q版本的代码里,把MediaStore.Video.Media.DATA字段的路径设为了DIRECTORY_PICTURES(图片目录),Android 9的MediaProvider会根据DATA路径自动匹配对应的媒体库,导致实际请求被路由到图片媒体库,触发额外的权限校验,这也是崩溃日志里报错路径为content://media/external/images/media的核心原因。 - 运行时权限兼容不全:如果你的App targetSdkVersion >= 33,若运行时权限申请逻辑仅适配了高版本的
READ_MEDIA_VIDEO权限,没有对API <=32的设备申请WRITE_EXTERNAL_STORAGE权限,会导致Android 9设备实际未拿到写入权限。 - 权限校验缺失:执行保存逻辑前没有判断权限是否已正式授予,用户拒绝权限后直接执行写入操作也会触发该异常。
修复方案
- 修正存储路径匹配问题
把低于Android Q版本的存储路径从图片目录改为视频目录,和高版本逻辑保持一致,避免请求被路由到错误的媒体库:
// 原错误代码 var videosDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).path // 修改为正确的视频目录 var videosDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).path
- 完善运行时权限适配逻辑
根据App targetSdkVersion版本,对不同系统版本申请对应权限,必须确认权限授予后再执行保存逻辑:
- API >= 33:申请
READ_MEDIA_VIDEO(仅读取其他应用写入的媒体文件时需要,写入公共视频目录无需额外权限) - API <= 32:必须申请
WRITE_EXTERNAL_STORAGE权限
- 可选:低版本优先直接写文件再通知媒体库扫描
如果修改路径后还有异常,可以在Android 9及更低版本上跳过直接插入MediaStore的逻辑,先把文件写入目标目录,再通知系统扫描媒体库,兼容性更高:
// Android 9及以下版本逻辑替换 val videosDir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), "Coutloot") if (!videosDir.exists()) { videosDir.mkdirs() } val targetFile = File(videosDir, displayName) file.copyTo(targetFile, overwrite = true) // 通知系统扫描新增的视频文件 MediaScannerConnection.scanFile(context, arrayOf(targetFile.absolutePath), arrayOf("video/mp4"), null) return Uri.fromFile(targetFile)
内容的提问来源于stack exchange,提问作者Siddhesh Pawar
相关产品推荐
相关产品推荐

