You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:58:09