Flutter下载的图片存至Android media目录无法在系统图库显示怎么办
问题根因
Android 10(API 29)及以上系统中,/storage/emulated/0/Android/media/包名/ 属于应用专属媒体目录,默认仅对当前应用可见,系统图库这类第三方应用无权限访问该目录下的文件,即使触发MediaScanner扫描也无法被公共媒体库收录。之前存储在公共外部存储目录可以被扫描到,是因为公共目录属于所有应用都有权限读取的共享区域。
解决方案
有两种可选方案,可根据业务需求选择:
方案1:将文件插入公共媒体库(保留现有专属目录存储逻辑)
不需要修改文件存储路径,只需要在下载完成后,主动将文件信息插入系统的MediaStore公共媒体库即可,操作步骤如下:
- 申请必要权限:Android 13及以上需要申请
POST_NOTIFICATIONS和READ_MEDIA_IMAGES权限,Android 10-12需要申请WRITE_EXTERNAL_STORAGE权限(Android 13起废弃该权限) - 下载完成后调用代码插入MediaStore,可引入
media_store第三方库实现,示例代码如下:
import 'package:media_store/media_store.dart'; import 'package:path/path.dart' as path; import 'dart:io'; // 下载完成后执行以下代码 final saveResult = await MediaStore.saveImage( file: File(directory.path), albumName: "自定义相册名称", // 图库中显示的相册名 isDcim: true, // 记录到公共DCIM分类下,传false则记录到Pictures分类下 );
如果不想引入额外依赖,也可以通过MethodChannel调用原生Android的MediaStore插入逻辑,原生端参考代码:
val contentValues = ContentValues().apply { put(MediaStore.Images.Media.DISPLAY_NAME, path.basename(directory.path)) put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM + "/自定义相册名") put(MediaStore.Images.Media.IS_PENDING, 1) } val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) uri?.let { contentResolver.openOutputStream(it).use { outputStream -> File(directory.path).inputStream().copyTo(outputStream!!) } contentValues.clear() contentValues.put(MediaStore.Images.Media.IS_PENDING, 0) contentResolver.update(it, contentValues, null, null) }
方案2:修改存储路径到公共媒体目录
直接将下载的图片存储到系统公共的DCIM/或者Pictures/目录下,存储完成后再调用你现有代码的MediaScanner扫描,即可被图库识别,获取公共目录路径的Dart示例代码:
import 'package:path_provider/path_provider.dart'; import 'dart:io'; Future<String> getPublicImageDir() async { // 获取系统公共图片目录 final publicDir = await getExternalStoragePublicDirectory(DirectoryDownloads.pictures); final customDir = Directory("${publicDir!.path}/自定义相册名"); if (!await customDir.exists()) { await customDir.create(recursive: true); } return customDir.path; }
注意事项
- 你原有的MediaScanner调用逻辑是有效的,但仅对公共目录下的文件生效,专属目录下的文件即使扫描也不会加入公共媒体库
- 若选择方案1,插入MediaStore后不需要再额外调用MediaScanner,系统会自动识别新增的媒体记录
内容的提问来源于stack exchange,提问作者Narayana
相关产品推荐
相关产品推荐

