Condividi tramite


Condividi

Sfoglia l'esempio. Sfoglia l'esempio

Questo articolo descrive come usare l'interfaccia utente dell'app multipiattaforma .NET (.NET MAUI). IShare Questa interfaccia fornisce un'API per inviare dati, ad esempio collegamenti di testo o Web, alla funzione di condivisione dei dispositivi.

L'implementazione predefinita dell'interfaccia IShare è disponibile tramite la proprietà Share.Default. Sia l'interfaccia IShare che la classe Share sono contenute nello spazio dei nomi Microsoft.Maui.ApplicationModel.DataTransfer.

Quando viene effettuata una richiesta di condivisione, il dispositivo visualizza una finestra di condivisione, richiedendo all'utente di scegliere un'app con cui condividere:

Condividi dalla tua app a un'altra app

Inizia subito

Per accedere alla funzionalità condivisione, è necessaria la seguente configurazione specifica della piattaforma:

Non è necessaria alcuna configurazione.

La funzionalità di condivisione funziona chiamando il metodo RequestAsync con un payload di dati che include informazioni da condividere con altre applicazioni. ShareTextRequest.Text e ShareTextRequest.Uri possono essere misti e ogni piattaforma gestirà il filtro in base al contenuto.

public async Task ShareText(string text)
{
    await Share.Default.RequestAsync(new ShareTextRequest
    {
        Text = text,
        Title = "Share Text"
    });
}

public async Task ShareUri(string uri, IShare share)
{
    await share.RequestAsync(new ShareTextRequest
    {
        Uri = uri,
        Title = "Share Web Link"
    });
}

Condividere un file

È anche possibile condividere file in altre applicazioni nel dispositivo. .NET MAUI rileva automaticamente il tipo di file (MIME) e richiede una condivisione. Tuttavia, i sistemi operativi possono limitare i tipi di file che possono essere condivisi. Per condividere un singolo file, usare il tipo di ShareFileRequest.

L'esempio di codice seguente scrive un file di testo nel dispositivo e quindi richiede di condividerlo:

public async Task ShareFile()
{
    string fn = "Attachment.txt";
    string file = Path.Combine(FileSystem.CacheDirectory, fn);

    File.WriteAllText(file, "Hello World");

    await Share.Default.RequestAsync(new ShareFileRequest
    {
        Title = "Share text file",
        File = new ShareFile(file)
    });
}

Condividere più file

La condivisione di più file è leggermente diversa dalla condivisione di un singolo file. Per condividere un singolo file, usare il tipo di ShareMultipleFilesRequest.

L'esempio di codice seguente scrive due file di testo nel dispositivo e quindi richiede di condividerli:

public async Task ShareMultipleFiles()
{
    string file1 = Path.Combine(FileSystem.CacheDirectory, "Attachment1.txt");
    string file2 = Path.Combine(FileSystem.CacheDirectory, "Attachment2.txt");

    File.WriteAllText(file1, "Content 1");
    File.WriteAllText(file2, "Content 2");

    await Share.Default.RequestAsync(new ShareMultipleFilesRequest
    {
        Title = "Share multiple files",
        Files = new List<ShareFile> { new ShareFile(file1), new ShareFile(file2) }
    });
}

Controllare i percorsi dei file

Importante

Questa sezione si applica solo ad Android.

In alcuni scenari su Android, ad esempio quando un file si trova in un'archiviazione privata, può essere copiato nella cache dell'app, che viene quindi condivisa tramite FileProvidersu Android. Tuttavia, questo può esporre involontariamente l'intera cache e i dati dell'applicazione a un utente malintenzionato. Ciò può essere impedito aggiungendo alla tua app un file di override dei percorsi del provider di file e assicurandoti che i file vengano copiati nel percorso specificato in questo file prima della condivisione.

Per aggiungere un file di sostituzione dei percorsi del provider di file all'app, inserire un file chiamato microsoft_maui_essentials_fileprovider_file_paths.xml nella cartella Platforms\Android\Resources\xml dell'app. Pertanto, il nome file relativo completo al progetto deve essere Platforms\Android\Resources\xml\microsoft_maui_essentials_fileprovider_file_paths.xml. Aggiungere quindi XML al file per i percorsi necessari:

 <?xml version="1.0" encoding="UTF-8" ?>
 <paths>
    <external-path name="external_files" path="sharing-root" />
    <cache-path name="internal_cache" path="sharing-root" />
    <external-cache-path name="external_cache" path="sharing-root" />  
 </paths>

Per altre informazioni sui percorsi del provider di file, vedere FileProvider su developer.android.com.

Prima di condividere un file, assicurati che sia prima salvato nella cartella sharing-root, in una delle posizioni indicate nel file di override.

// Write into the specific sub-directory
var dir = Path.Combine(FileSystem.CacheDirectory, "sharing-root");  
Directory.CreateDirectory(dir);
var file = Path.Combine(dir, "mydata.txt");
await File.WriteAllTextAsync(file, $"My data: {count}");

// Share the file
await Launcher.OpenAsync(new OpenFileRequest
{
   Title = "My data",
   File = new ReadOnlyFile(file),
});

È possibile verificare che il file sia condiviso correttamente se l'URI condiviso esclude la directory radice di condivisione. Ad esempio, se si condivide il file <CacheDirectory>/sharing-root/mydata.txt e l'URI condiviso è content://com.companyname.overwritefileproviderpaths.fileProvider/internal_cache/sharing-root/mydata.txt il provider di file non usa il percorso corretto. Se l'URI condiviso è content://com.companyname.overwritefileproviderpaths.fileProvider/internal_cache/mydata.txt, il provider di file usa il percorso corretto.

Avvertimento

Quando si condivide un file, se si riceve un Java.Lang.IllegalArgumentException, con un messaggio simile a "Impossibile trovare la radice configurata che contiene /data/data/com.companyname.overwritefileproviderpaths/cache/some-non-sharing-path/mydata.txt", è molto probabile che stiate condividendo un file al di fuori della radice di condivisione.

Posizione presentazione

Importante

Questa sezione si applica solo a iPadOS.

Quando si richiede una condivisione o si apre un'utilità di avvio in iPadOS, è possibile presentarla in un popover. Specifica dove verrà visualizzato il popover e dove punterà direttamente una freccia. Questo luogo è spesso il comando che ha avviato l'azione. È possibile specificare il percorso usando la proprietà PresentationSourceBounds:

await Share.RequestAsync(new ShareFileRequest
    {
        Title = Title,
        File = new ShareFile(file),
        PresentationSourceBounds = DeviceInfo.Platform == DevicePlatform.iOS && DeviceInfo.Idiom == DeviceIdiom.Tablet
                                ? new Rect(0, 20, 0, 0)
                                : Rect.Zero
    });
await Launcher.OpenAsync(new OpenFileRequest
    {
        File = new ReadOnlyFile(file),
        PresentationSourceBounds = DeviceInfo.Platform == DevicePlatform.iOS && DeviceInfo.Idiom == DeviceIdiom.Tablet
                                ? new Rect(0, 20, 0, 0)
                                : Rect.Zero
    });

Tutti gli elementi descritti di seguito funzionano allo stesso modo per Share e Launcher.

Ecco un metodo di estensione che consente di calcolare i limiti di una visualizzazione:

public static class ViewHelpers
{
    public static Rect GetAbsoluteBounds(this Microsoft.Maui.Controls.View element)
    {
        Element looper = element;

        var absoluteX = element.X + element.Margin.Top;
        var absoluteY = element.Y + element.Margin.Left;

        // Add logic to handle titles, headers, or other non-view bars

        while (looper.Parent != null)
        {
            looper = looper.Parent;
            if (looper is Microsoft.Maui.Controls.View v)
            {
                absoluteX += v.X + v.Margin.Top;
                absoluteY += v.Y + v.Margin.Left;
            }
        }

        return new Rect(absoluteX, absoluteY, element.Width, element.Height);
    }
}

Questa operazione può quindi essere usata quando si chiama RequestAsync:

public Command<Microsoft.Maui.Controls.View> ShareCommand { get; } = new Command<Microsoft.Maui.Controls.View>(Share);

async void Share(Microsoft.Maui.Controls.View element)
{
    try
    {
        await Share.Default.RequestAsync(new ShareTextRequest
        {
            PresentationSourceBounds = element.GetAbsoluteBounds(),
            Title = "Title",
            Text = "Text"
        });
    }
    catch (Exception)
    {
        // Handle exception that share failed
    }
}

È possibile passare l'elemento chiamante quando il Command viene attivato:

<Button Text="Share"
        Command="{Binding ShareWithFriendsCommand}"
        CommandParameter="{Binding Source={RelativeSource Self}}"/>

Per un esempio della classe ViewHelpers, vedere l'esempio MAUI di .NET ospitato in GitHub.

Differenze tra le piattaforme

Questa sezione descrive le differenze specifiche della piattaforma con l'API di condivisione.