Seletor de mídia para fotos e vídeos

Procurar exemplo. Procurar o exemplo

Este artigo descreve como você pode usar a interface .NET Multi-platform App UI (.NET MAUI). IMediaPicker Essa interface permite que um usuário escolha ou tire uma foto ou vídeo no dispositivo.

A implementação padrão da IMediaPicker interface está disponível através da MediaPicker.Default propriedade. A IMediaPicker interface e a MediaPicker classe estão contidas no Microsoft.Maui.Media namespace.

Introdução

Para acessar a funcionalidade do seletor de mídia, é necessária a seguinte configuração específica da plataforma.

A CAMERA permissão é necessária e deve ser configurada no projeto Android. Além disso:

  • Se a sua aplicação tiver como alvo o Android 12 ou inferior, deve solicitar as permissões READ_EXTERNAL_STORAGE e WRITE_EXTERNAL_STORAGE.

  • Se o seu aplicativo tiver como alvo o Android 13 ou superior e precisar de acesso a arquivos de mídia criados por outros aplicativos, você deverá solicitar uma ou mais das seguintes permissões de mídia granular em vez da READ_EXTERNAL_STORAGE permissão:

    • READ_MEDIA_IMAGES
    • READ_MEDIA_VIDEO
    • READ_MEDIA_AUDIO

Essas permissões podem ser adicionadas das seguintes maneiras:

  • Adicione as permissões com base em assemblies:

    Abra o ficheiro Platforms/Android/MainApplication.cs e adicione os seguintes atributos de assembly após as diretivas 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)]
    

    - ou -

  • Atualize o manifesto do Android:

    Abra o arquivo Platforms/Android/AndroidManifest.xml e adicione o seguinte no nó manifest:

    <!-- Needed for Picking photo/video -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
    
    <!-- Needed for Taking photo/video -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android: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 -->
    <uses-feature android:name="android.hardware.camera" android:required="true" />
    <uses-feature android:name="android.hardware.camera.autofocus" android:required="true" />
    

    - ou -

  • Atualize o manifesto do Android no editor de manifesto:

    No Visual Studio, clique duas vezes no arquivo Platforms/Android/AndroidManifest.xml para abrir o editor de manifesto do Android. Em seguida, em Permissões necessárias , verifique as permissões listadas acima. Isso atualizará automaticamente o arquivo AndroidManifest.xml .

Se a versão Android de destino do seu projeto estiver definida como Android 11 (R API 30) ou superior, você deverá atualizar seu Manifesto do Android com consultas que usam os requisitos de visibilidade do pacote do Android.

No arquivo Platforms/Android/AndroidManifest.xml, adicione os seguintes queries/intent nós no manifest nó:

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

Usando o seletor de mídia

A IMediaPicker interface tem os seguintes métodos que retornam um FileResult, que pode ser usado para obter a localização do arquivo ou lê-lo.

Cada método pode opcionalmente usar um MediaPickerOptions parâmetro que permite definir o Title em alguns sistemas operacionais, que é exibido ao utilizador.

No .NET 10, o seletor de mídia adiciona suporte a seleção múltipla e novas opções de processamento. Use os seguintes métodos:

  • PickPhotosAsync (retorna List<FileResult>)
    Abre o navegador de mídia para selecionar uma ou mais fotos.

  • CapturePhotoAsync (retorna FileResult?)
    Abre a câmera para tirar uma foto.

  • PickVideosAsync (retorna List<FileResult>)
    Abre o navegador de mídia para selecionar um ou mais vídeos.

  • CaptureVideoAsync (retorna FileResult?)
    Abre a câmara para gravar um vídeo.

O MediaPickerOptions parâmetro expõe campos adicionais, como SelectionLimit, MaximumWidth, MaximumHeight, CompressionQuality, RotateImagee PreserveMetaData.

Importante

Quando o usuário cancela uma operação de seleção múltipla, a lista retornada fica vazia. No sistema operativo Android, algumas interfaces de seleção podem não ser aplicadas SelectionLimit; no sistema operativo Windows, SelectionLimit não é suportado. Implemente sua própria lógica para impor limites ou notificar o usuário nessas plataformas.

Escolha várias fotos

var results = await MediaPicker.PickPhotosAsync(new MediaPickerOptions
{
  // Default is 1; set to 0 for no limit
  SelectionLimit = 10,
  // Optional processing for images
  MaximumWidth = 1024,
  MaximumHeight = 768,
  CompressionQuality = 85,
  RotateImage = true,
  PreserveMetaData = true,
});

foreach (var file in results)
{
  using var stream = await file.OpenReadAsync();
  // Process the stream
}

Escolha vários vídeos

var results = await MediaPicker.PickVideosAsync(new MediaPickerOptions
{
  SelectionLimit = 3,
  Title = "Select up to 3 videos",
});

foreach (var file in results)
{
  using var stream = await file.OpenReadAsync();
  // Process the stream
}

Sugestão

Para uma única seleção, prefira PickPhotosAsync/PickVideosAsync também. Defina SelectionLimit = 1 (o padrão) e leia o primeiro item, se presente.

Importante

Os métodos do seletor de multimédia que abrem a câmara ou a interface de utilizador do seletor têm de ser invocados no thread da interface de utilizador, porque a verificação e os pedidos de permissões são tratados automaticamente pelo .NET MAUI.

A MediaPickerOptions.SaveToGallery propriedade controla se uma fotografia ou vídeo capturado também é guardado na galeria do dispositivo. O valor padrão é false, e a propriedade aplica-se apenas às CapturePhotoAsync operações e CaptureVideoAsync . É ignorado pelas operações de seleção dos media.

FileResult? photo = await MediaPicker.Default.CapturePhotoAsync(
    new MediaPickerOptions
    {
        SaveToGallery = true
    });

A gravação de conteúdos capturados na galeria é suportada em Android, iOS e Mac Catalyst. No Catalyst para iOS e Mac, a NSPhotoLibraryAddUsageDescription chave deve estar presente no Info.plist. Nas versões Android anteriores à API 29, a WRITE_EXTERNAL_STORAGE permissão é necessária. A propriedade é ignorada no Windows e no Tizen.

Recuperar operações interruptas do seletor de media Android

No Android, o sistema pode destruir e recriar a sua aplicação enquanto a câmara ou a interface do seletor de fotos estão à frente. Se a tarefa original do seletor de media desaparecer quando a sua aplicação recomeçou, use as APIs de recuperação exclusivas do Android para recuperar quaisquer resultados aceites.

A recuperação está disponível para operações de seleção de media apoiadas pelo AndroidX: capturar fotografia, capturar vídeo, escolher uma foto, escolher fotos, escolher um vídeo e selecionar vídeos. Cada RecoveredMediaPickerResult tem um Id, um Kind e uma coleção Files que contém objetos FileResult recuperados. O RecoveredMediaPickerResultKind valor identifica a operação como CapturePhoto, CaptureVideo, PickPhoto, PickPhotos, PickVideo, ou PickVideos.

Como as APIs de recuperação são apenas para Android, coloque o código de recuperação num ficheiro específico para Android ou guarde-o em #if ANDROID código partilhado.

using System.IO;
using Microsoft.Maui.Media;
using Microsoft.Maui.Storage;

#if ANDROID
async Task RecoverMediaPickerResultsAsync()
{
    var results = await MediaPicker.GetRecoveredMediaPickerResultsAsync();

    foreach (var result in results)
    {
        foreach (var file in result.Files)
        {
            var destination = Path.Combine(FileSystem.CacheDirectory, file.FileName);

            using var source = await file.OpenReadAsync();
            using var target = File.Create(destination);
            await source.CopyToAsync(target);
        }

        await MediaPicker.ClearRecoveredMediaPickerResultAsync(result.Id);
    }
}
#endif

Utilize MediaPicker.GetRecoveredMediaPickerResultsAsync para consultar os resultados já recuperados e chame MediaPicker.ClearRecoveredMediaPickerResultAsync depois de a sua aplicação tratar cada resultado. Se o seu fluxo de inicialização ou retoma precisar de esperar pela reconciliação de recuperação, chame MediaPicker.WaitForRecoveredMediaPickerResultsAsync com um CancellationToken. Se, em vez disso, a aplicação tiver de abandonar uma operação pendente do seletor de multimédia, chame MediaPicker.DiscardPendingMediaPickerOperationAsync.

Importante

A recuperação dos resultados do seletor de media é apenas para Android e não altera o comportamento do seletor de media no iOS, Mac Catalyst ou Windows.

Tire uma foto

Chame o CapturePhotoAsync método para abrir a câmera e deixe o usuário tirar uma foto. Se o usuário tirar uma foto, o valor de retorno do método será um valor não nulo. O exemplo de código a seguir usa o seletor de mídia para tirar uma foto e salvá-la no diretório de cache:

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);
        }
    }
}

Sugestão

A FullPath propriedade nem sempre retorna o caminho físico para o arquivo. Para obter o arquivo, use o OpenReadAsync método.