Selezione multimediale per foto e video

Sfoglia l'esempio. Sfoglia l'esempio

Questo articolo descrive come usare l'interfaccia utente dell'app multipiattaforma .NET (.NET MAUI). IMediaPicker Questa interfaccia consente a un utente di scegliere o scattare una foto o un video nel dispositivo.

L'implementazione predefinita dell'interfaccia IMediaPicker è disponibile tramite la MediaPicker.Default proprietà . Sia l'interfaccia IMediaPicker che la classe MediaPicker sono contenute nel namespace Microsoft.Maui.Media.

Inizia

Per accedere alla funzionalità di selezione multimediale, è necessaria la configurazione specifica della piattaforma seguente.

L'autorizzazione CAMERA è obbligatoria e deve essere configurata nel progetto Android. In aggiunta:

  • Se la tua app è destinata ad Android 12 o versione precedente, devi richiedere le autorizzazioni READ_EXTERNAL_STORAGE e WRITE_EXTERNAL_STORAGE.

  • Se l'app è destinata ad Android 13 o versione successiva e deve accedere ai file multimediali creati da altre app, è necessario richiedere una o più delle seguenti autorizzazioni granulari per i file multimediali anziché l'autorizzazione READ_EXTERNAL_STORAGE:

    • READ_MEDIA_IMAGES
    • READ_MEDIA_VIDEO
    • READ_MEDIA_AUDIO

Queste autorizzazioni possono essere aggiunte nei modi seguenti:

  • Aggiungere le autorizzazioni basate su assembly:

    Aprire il file Platforms/Android/MainApplication.cs e aggiungere gli attributi assembly seguenti dopo using le direttive:

    // 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)]
    

    o

  • Aggiornare il manifesto Android:

    Aprire il file Platforms/Android/AndroidManifest.xml e aggiungere quanto segue nel manifest nodo:

    <!-- 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" />
    

    o

  • Aggiornare il manifesto Android nell'editor del manifesto:

    In Visual Studio fare doppio clic sul file Platforms/Android/AndroidManifest.xml per aprire l'editor del manifesto Android. Quindi, in Autorizzazioni necessarie controllare le autorizzazioni elencate in precedenza. Il file AndroidManifest.xml verrà aggiornato automaticamente.

Se la versione di Android di destinazione del progetto è impostata su Android 11 (API R 30) o versione successiva, è necessario aggiornare il manifesto Android con query che usano i requisiti di visibilità dei pacchetti android.

Nel file Platforms/Android/AndroidManifest.xml aggiungere i nodi seguenti queries/intent nel nodo manifest:

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

Uso del selettore multimediale

L'interfaccia IMediaPicker include i metodi seguenti che restituiscono un FileResultoggetto , che può essere usato per ottenere il percorso del file o leggerlo.

Ogni metodo accetta facoltativamente un parametro MediaPickerOptions che consente di impostare il Title per alcuni sistemi operativi, e che viene mostrato all'utente.

In .NET 10, il selettore multimediale aggiunge il supporto per la selezione multipla e nuove opzioni di elaborazione. Usare i metodi seguenti:

  • PickPhotosAsync (restituisce List<FileResult>)
    Apre il browser multimediale per selezionare una o più foto.

  • CapturePhotoAsync (restituisce FileResult?)
    Apre la fotocamera per scattare una foto.

  • PickVideosAsync (restituisce List<FileResult>)
    Apre il browser multimediale per selezionare uno o più video.

  • CaptureVideoAsync (restituisce FileResult?)
    Apre la fotocamera per scattare un video.

Il MediaPickerOptions parametro espone campi aggiuntivi, ad esempio, SelectionLimit, MaximumWidth, MaximumHeight, CompressionQuality, RotateImage e PreserveMetaData.

Importante

Quando l'utente annulla un'operazione di selezione multipla, l'elenco restituito è vuoto. In Android alcune interfacce utente di selezione potrebbero non applicare SelectionLimit; in Windows, SelectionLimit non è supportato. Implementare la propria logica per applicare limiti o notificare all'utente su queste piattaforme.

Selezionare più foto

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
}

Selezionare più video

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
}

Suggerimento

Per la selezione singola, preferire anche PickPhotosAsync/PickVideosAsync. Impostare SelectionLimit = 1 (impostazione predefinita) e leggere il primo elemento, se presente.

Importante

I metodi di selezione multimediale che aprono la fotocamera o l'interfaccia utente di selezione devono essere chiamati nel thread dell'interfaccia utente perché i controlli delle autorizzazioni e le richieste vengono gestiti automaticamente da .NET MAUI.

La MediaPickerOptions.SaveToGallery proprietà controlla se anche una foto o un video acquisito viene salvato nella raccolta del dispositivo. Il valore predefinito è falsee la proprietà si applica solo alle CapturePhotoAsync operazioni e CaptureVideoAsync . Viene ignorato dalle operazioni di selezione multimediale.

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

Il salvataggio di supporti acquisiti nella raccolta è supportato in Android, iOS e Mac Catalyst. In iOS e Mac Catalyst, la NSPhotoLibraryAddUsageDescription chiave deve essere presente in Info.plist. Nelle versioni di Android precedenti all'API 29, l'autorizzazione WRITE_EXTERNAL_STORAGE è necessaria. La proprietà viene ignorata in Windows e Tizen.

Ripristinare le operazioni di selezione multimediale Android interrotte

In Android, il sistema può distruggere e ricreare l'app mentre l'interfaccia utente della fotocamera o della selezione foto si trova davanti. Se l'attività di selezione multimediale originale non è più disponibile quando l'app viene ripresa, usare le API di ripristino solo Android per recuperare i risultati accettati.

Il recupero è disponibile per le operazioni di selezione multimediale supportate da AndroidX: acquisizione di foto, acquisizione di video, selezione di una foto, selezione di foto, selezione di un video e selezione video. Ogni RecoveredMediaPickerResult ha un Id, un Kind e una raccolta Files contenente oggetti FileResult recuperati. Il RecoveredMediaPickerResultKind valore identifica l'operazione come CapturePhoto, CaptureVideoPickPhoto, PickPhotos, PickVideo, o PickVideos.

Poiché le API di ripristino sono solo Android, inserire il codice di ripristino in un file specifico di Android o sorvegliarlo con #if ANDROID nel codice condiviso.

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

Usare MediaPicker.GetRecoveredMediaPickerResultsAsync per eseguire query sui risultati già recuperati e chiamare MediaPicker.ClearRecoveredMediaPickerResultAsync dopo che l'app gestisce ogni risultato. Se il flusso di avvio o di ripresa deve attendere la riconciliazione del ripristino, chiamare MediaPicker.WaitForRecoveredMediaPickerResultsAsync con un CancellationToken. Se l'app deve abbandonare invece un'operazione di selezione multimediale in sospeso, chiamare MediaPicker.DiscardPendingMediaPickerOperationAsync.

Importante

Il recupero dei risultati della selezione multimediale è solo Android e non modifica il comportamento della selezione multimediale in iOS, Mac Catalyst o Windows.

Scattare una foto

Chiamare il CapturePhotoAsync metodo per aprire la fotocamera e consentire all'utente di scattare una foto. Se l'utente acquisisce una foto, il valore restituito del metodo sarà un valore non Null. L'esempio di codice seguente usa la selezione multimediale per scattare una foto e salvarla nella directory della 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);
        }
    }
}

Suggerimento

La FullPath proprietà non restituisce sempre il percorso fisico del file. Per ottenere il file, usare il OpenReadAsync metodo .