如何在Kotlin中将照片添加到Android系统内置相册?
安卓保存图片到系统相册兼容方案(兼容API25及以上全版本)
方案1:扫描已存在的本地图片文件(替代废弃的ACTION_MEDIA_SCANNER_SCAN_FILE广播)
使用MediaScannerConnection实现,该API未被废弃,兼容API 8及以上版本,适合已经将图片保存在本地、仅需要通知相册扫描的场景:
private fun galleryAddPic(imagePath: String) { MediaScannerConnection.scanFile( requireContext(), arrayOf(imagePath), arrayOf("image/jpeg") // 替换为对应图片的MIME类型 ) { _, uri -> // 扫描完成回调,uri为相册可识别的内容uri Toast.makeText(requireContext(), "图片已添加到相册", Toast.LENGTH_SHORT).show() } }
注意:API 29及以上版本系统禁止媒体扫描器访问应用专属目录的文件,如果你需要在API29+设备上让图片在相册展示,需要用方案2直接写入公共媒体库。
方案2:直接写入公共媒体库(替代废弃的MediaStore.Images.Media.insertImage,全版本兼容)
官方推荐方案,写入完成后系统会自动将图片纳入相册,无需额外发广播通知扫描,兼容API 16及以上版本:
前置权限配置
在AndroidManifest.xml中添加权限:
<!-- 仅API <=28需要该权限,API>=29无需声明 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
保存图片到公共相册代码示例:
// bitmap为要保存的图片位图,displayName为保存的文件名 private fun saveImageToGallery(bitmap: Bitmap, displayName: String): Boolean { val contentValues = ContentValues().apply { put(MediaStore.Images.Media.DISPLAY_NAME, displayName) put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") // API <=28需要指定存储路径,API>=29系统默认存到Pictures目录 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).absolutePath put(MediaStore.Images.Media.DATA, "$imagesDir/${displayName}.jpg") } else { put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES) put(MediaStore.Images.Media.IS_PENDING, 1) } } val contentResolver = requireContext().contentResolver val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) ?: return false return try { contentResolver.openOutputStream(uri).use { outputStream -> if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)) { throw IOException("图片压缩失败") } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { contentValues.clear() contentValues.put(MediaStore.Images.Media.IS_PENDING, 0) contentResolver.update(uri, contentValues, null, null) } true } catch (e: IOException) { e.printStackTrace() contentResolver.delete(uri, null, null) false } }
内容的提问来源于stack exchange,提问作者Tbijo54
相关产品推荐
相关产品推荐

