MAUI(.NET7) Android端拍照保存至相册可见位置的问题求助
MAUI .NET7 Android 拍照保存到相册解决方案
问题原因
- 你之前使用的
FileSystem.AppDataDirectory和FileSystem.CacheDirectory是应用私有目录,系统媒体扫描器不会扫描这些目录,因此相册无法识别其中的图片文件。
解决方案(适配Android Scoped Storage)
1. 配置权限
在Platforms/Android/AndroidManifest.xml中添加对应权限:
<!-- Android 12及以下 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- Android 13+ --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.WRITE_MEDIA_IMAGES" />
2. 完整实现代码
使用MediaStore将图片保存到公共媒体目录,并通知媒体扫描器更新相册:
#if ANDROID using Android.Content; using Android.Provider; using Android.Net; #endif async Task CaptureAndSavePhotoToAlbum() { if (MediaPicker.Default.IsCaptureSupported) { FileResult photo = await MediaPicker.Default.CapturePhotoAsync(); if (photo != null) { // 请求存储权限 #if ANDROID var permissionStatus = await Permissions.RequestAsync<Permissions.StorageWrite>(); if (permissionStatus != PermissionStatus.Granted) { // 处理权限拒绝逻辑,比如提示用户开启权限 return; } #endif await SavePhotoToPublicAlbum(photo); } } } #if ANDROID private async Task SavePhotoToPublicAlbum(FileResult photo) { using var sourceStream = await photo.OpenReadAsync(); var appContext = Android.App.Application.Context; // 构建媒体存储元数据 var contentValues = new ContentValues(); // 生成唯一文件名避免覆盖 var uniqueFileName = $"{Guid.NewGuid()}{Path.GetExtension(photo.FileName)}"; contentValues.Put(MediaStore.Images.ImageColumns.DisplayName, uniqueFileName); contentValues.Put(MediaStore.Images.ImageColumns.MimeType, photo.ContentType); // 指定保存到DCIM目录下的自定义子文件夹,可修改为"Pictures/你的应用名"等 contentValues.Put(MediaStore.Images.ImageColumns.RelativePath, "DCIM/MAUI_Photo"); // 插入媒体记录到系统媒体库 var mediaUri = appContext.ContentResolver.Insert(MediaStore.Images.Media.ExternalContentUri, contentValues); if (mediaUri == null) { // 插入失败,可添加错误处理 return; } // 将图片流写入系统媒体库 using var outputStream = appContext.ContentResolver.OpenOutputStream(mediaUri); if (outputStream != null) { await sourceStream.CopyToAsync(outputStream); await outputStream.FlushAsync(); } // 发送广播通知媒体扫描器更新,确保相册立即显示图片 appContext.SendBroadcast(new Intent(Intent.ActionMediaScannerScanFile, mediaUri)); } #endif
关键说明
- 采用
MediaStore方式符合Android 10+的Scoped Storage规范,无需直接操作文件路径,避免权限问题。 - 通过发送
Intent.ActionMediaScannerScanFile广播,强制系统媒体扫描器识别新保存的图片,相册就能立即显示。 - 生成唯一文件名可以避免覆盖已有图片,提升用户体验。
内容的提问来源于stack exchange,提问作者user1431743
相关产品推荐
相关产品推荐

