照片和视频的媒体选取器

浏览示例。 浏览示例

本文介绍如何使用 .NET Multi-platform App UI (.NET MAUI) IMediaPicker 接口。 此接口允许用户在设备上选取或拍摄照片或视频。

IMediaPicker 接口的默认实现通过 MediaPicker.Default 属性提供。 IMediaPicker 接口和 MediaPicker 类都包含在 Microsoft.Maui.Media 命名空间中。

开始使用

要访问媒体选取器功能,需要以下特定于平台的设置。

需要具有 CAMERA 权限,并且必须在 Android 项目中进行配置。 此外:

  • 如果应用面向 Android 12 或更低版本,则必须请求 READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE 权限。

  • 如果你的应用面向 Android 13 或更高版本,并且需要访问其他应用已经创建的媒体文件,则必须请求以下一个或多个精细媒体权限,而不是 READ_EXTERNAL_STORAGE 权限:

    • READ_MEDIA_IMAGES
    • READ_MEDIA_VIDEO
    • READ_MEDIA_AUDIO

可通过以下方式添加这些权限:

  • 添加基于程序集的权限:

    打开 Platforms/Android/MainApplication.cs 文件,并在 using 指令后面添加以下程序集属性:

    // Needed for Picking photo/video
    [assembly: UsesPermission(Android.Manifest.Permission.ReadExternalStorage, MaxSdkVersion = 32)]
    [assembly: UsesPermission(Android.Manifest.Permission.ReadMediaAudio)]
    [assembly: UsesPermission(Android.Manifest.Permission.ReadMediaImages)]
    [assembly: UsesPermission(Android.Manifest.Permission.ReadMediaVideo)]
    
    // Needed for Taking photo/video
    [assembly: UsesPermission(Android.Manifest.Permission.Camera)]
    [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage, MaxSdkVersion = 32)]
    
    // Add these properties if you would like to filter out devices that do not have cameras, or set to false to make them optional
    [assembly: UsesFeature("android.hardware.camera", Required = true)]
    [assembly: UsesFeature("android.hardware.camera.autofocus", Required = true)]
    

    - 或 -

  • 更新 Android 清单:

    打开 Platforms/Android/AndroidManifest.xml 文件并在 manifest 节点中添加以下内容:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />    
    <!-- Required only if your app needs to access images or photos that other apps created -->
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <!-- Required only if your app needs to access videos that other apps created -->
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
    <!-- Required only if your app needs to access audio files that other apps created -->
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />    
    

    - 或 -

  • 在清单编辑器中更新 Android 清单:

    在 Visual Studio 中,双击 Platforms/Android/AndroidManifest.xml 文件以打开 Android 清单编辑器。 然后在“所需权限”下方检查上方所列权限。 这样会自动更新 AndroidManifest.xml 文件。

如果项目的目标 Android 版本设置为 Android 11 (R API 30) 或更高版本,则必须通过使用 Android 包装可见性要求的查询更新 Android 清单

Platforms/Android/AndroidManifest.xml 文件中,在 manifest 节点中添加以下 queries/intent 节点:

<queries>
  <intent>
    <action android:name="android.media.action.IMAGE_CAPTURE" />
  </intent>
</queries>

使用媒体选取器

IMediaPicker 接口包含以下方法,这些方法都会返回一个 FileResult,可将其用于获取文件位置或者读取它。

每个方法都可以选择采用一种 MediaPickerOptions 参数类型,通过该参数可以在某些操作系统上设置 Title 来向用户显示。

重要说明

必须在 UI 线程上调用所有方法,因为 .NET MAUI 会自动处理权限检查和请求。

拍摄照片

调用 CapturePhotoAsync 方法打开相机并让用户拍照。 如果用户拍照,该方法的返回值将是一个非 null 值。 下面的代码示例使用媒体选取器拍摄照片并将其保存到缓存目录:

public async void TakePhoto()
{
    if (MediaPicker.Default.IsCaptureSupported)
    {
        FileResult photo = await MediaPicker.Default.CapturePhotoAsync();

        if (photo != null)
        {
            // save the file into local storage
            string localFilePath = Path.Combine(FileSystem.CacheDirectory, photo.FileName);

            using Stream sourceStream = await photo.OpenReadAsync();
            using FileStream localFileStream = File.OpenWrite(localFilePath);

            await sourceStream.CopyToAsync(localFileStream);
        }
    }
}

提示

FullPath 属性并不总是返回文件的物理路径。 若要获取文件,请使用 OpenReadAsync 方法。