删除应用自身创建的图片时抛出SecurityException的问题求助
解决方案
问题原因
你遇到的SecurityException是因为MediaStore.Images.Media.insertImage属于旧API,在Android 11+环境下,它插入的媒体文件没有正确赋予应用持续的删除权限——即便文档说明应用可删除自身创建的媒体文件,但这个旧方法的实现未适配新的权限模型。
1. 替换旧的bitmapToUri方法,使用MediaStore标准API插入图片
放弃insertImage,改用MediaStore的标准插入流程,确保应用获得对媒体文件的完整控制权:
fun bitmapToUri(ctx: Context, bitmap: Bitmap): Uri? { val contentValues = ContentValues().apply { put(MediaStore.Images.Media.DISPLAY_NAME, "${ctx.getString(R.string.app_name)}-${System.currentTimeMillis()}.jpg") put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") // API 29+ 指定存储路径到应用专属图片目录 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/${ctx.getString(R.string.app_name)}") // 标记为待处理,确保应用拥有编辑权限 put(MediaStore.MediaColumns.IS_PENDING, 1) } } val contentResolver = ctx.contentResolver val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) ?: return null // 将Bitmap写入Uri指向的文件 contentResolver.openOutputStream(uri)?.use { outputStream -> bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream) } // API 29+:取消待处理标记,完成插入流程 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { contentValues.clear() contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0) contentResolver.update(uri, contentValues, null, null) } return uri }
2. 保留现有删除逻辑,确保Uri有效
你的deleteUri函数无需修改,只需确保传入的Uri是上述新方法返回的有效Uri即可:
fun deleteUri(context: Context, uri: Uri) { val contentResolver = context.contentResolver contentResolver.delete(uri, null, null) }
3. 移除无关配置(可选)
你配置的FileProvider针对的是应用私有文件的Uri共享,和MediaStore公共媒体文件的操作无关,若当前场景不需要共享私有文件,可暂时移除该配置,避免混淆。
关键说明
- 新插入流程通过
IS_PENDING标记,确保应用在插入后拥有对文件的编辑/删除权限,完全适配Android 11+的媒体权限模型。 - 指定
RELATIVE_PATH将文件存入应用专属的图片目录,既符合系统规范,也便于后续管理。
内容的提问来源于stack exchange,提问作者Levi
相关产品推荐
相关产品推荐

