Android 14下替代ACCESS_MEDIA_LOCATION权限存图片的方案问询
解决方案
核心问题分析
你完全不需要ACCESS_MEDIA_LOCATION权限——这个权限的作用是读取系统中已有媒体文件的位置元数据,而你的场景是自己拍照并存储,根本用不上它。API34+申请该权限时会自动关联READ_MEDIA_VISUAL_USER_SELECTED,这才弹出了你不需要的照片选择器弹窗。
具体实现步骤
- 移除冗余权限:直接从
AndroidManifest.xml中删掉ACCESS_MEDIA_LOCATION权限,系统自动附加的READ_MEDIA_VISUAL_USER_SELECTED也会随之消失,不会再触发照片选择器弹窗。 - 选择适配场景的存储路径:
- 推荐:应用专属外部存储目录
这个路径属于应用私有空间,无需任何存储权限,卸载应用时文件会被自动清理,代码示例:
拍照时直接将输出文件指定为这个// 获取应用专属Pictures根目录 val appPicturesDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) // 创建你的专属子文件夹MyAppFolder val myAppFolder = File(appPicturesDir, "MyAppFolder") if (!myAppFolder.exists()) { myAppFolder.mkdirs() } // 生成带时间戳的照片文件 val photoFile = File(myAppFolder, "photo_${System.currentTimeMillis()}.jpg")photoFile即可(不管是用系统相机Intent还是自定义相机逻辑)。 - 可选:公共Pictures目录(卸载后保留文件)
如果希望照片在应用卸载后仍保留,用MediaStore写入公共Pictures/MyAppFolder,API30+无需WRITE_EXTERNAL_STORAGE权限,也不需要ACCESS_MEDIA_LOCATION(你自己写入的照片可直接附带位置元数据),代码示例:val contentValues = ContentValues().apply { put(MediaStore.Images.Media.DISPLAY_NAME, "photo_${System.currentTimeMillis()}.jpg") put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") put(MediaStore.Images.Media.RELATIVE_PATH, "${Environment.DIRECTORY_PICTURES}/MyAppFolder") // 若拍照时获取了位置信息,直接写入元数据 put(MediaStore.Images.Media.LATITUDE, latitude) put(MediaStore.Images.Media.LONGITUDE, longitude) } // 插入到媒体库获取写入URI val uri = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) // 将拍照得到的字节流写入目标位置 uri?.let { context.contentResolver.openOutputStream(it)?.use { outputStream -> // 写入照片数据逻辑 } }
- 推荐:应用专属外部存储目录
关键说明
- 两种方案都不需要申请任何存储权限,完全匹配你“仅拍摄并存储自有照片、不读取已有图片”的场景。
- 应用专属目录更省心,无需处理媒体库插入逻辑;公共目录适合需要长期保留用户照片的场景。
内容的提问来源于stack exchange,提问作者ItsVicky
相关产品推荐
相关产品推荐

