次の方法で共有


共有

サンプルを参照します。 サンプルを参照する

この記事では、.NET マルチプラットフォーム アプリ UI (.NET MAUI) ITextToSpeech インターフェイスを使用する方法について説明します。 このインターフェイスは、テキストや Web リンクなどのデータをデバイス共有機能に送信する API を提供します。

IShare インターフェイスの既定の実装は、Share.Default プロパティを使用して使用できます。 IShare インターフェイスと Share クラスの両方が、Microsoft.Maui.ApplicationModel.DataTransfer 名前空間に含まれています。

共有要求が行われると、デバイスに共有ウィンドウが表示され、共有するアプリを選択するようユーザーに求められます。

アプリから別のアプリに共有する

始めましょう

共有機能にアクセスするには、次のプラットフォーム固有のセットアップが必要です。

セットアップは必要ありません。

共有機能は、他のアプリケーションと共有する情報を含むデータ ペイロードを使用して RequestAsync メソッドを呼び出すことによって機能します。 ShareTextRequest.TextShareTextRequest.Uri を混在させることができます。各プラットフォームはコンテンツに基づくフィルター処理を処理します。

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

ファイルを共有する

デバイス上の他のアプリケーションとファイルを共有することもできます。 .NET MAUI は、ファイルの種類 (MIME) を自動的に検出し、共有を要求します。 ただし、オペレーティング システムでは、共有できるファイルの種類が制限される場合があります。 1 つのファイルを共有するには、 ShareFileRequest の種類を使用します。

次のコード例では、テキスト ファイルをデバイスに書き込み、共有を要求します。

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

複数のファイルを共有する

複数のファイルの共有は、1 つのファイルの共有とは若干異なります。 1 つのファイルを共有するには、 ShareMultipleFilesRequest の種類を使用します。

次のコード例では、2 つのテキスト ファイルをデバイスに書き込み、共有を要求します。

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

ファイルの場所を制御する

重要

このセクションは Android にのみ適用されます。

ファイルがプライベート ストレージ内にある場合など、Android 上の一部のシナリオでは、アプリ キャッシュにコピーし、Android FileProvider経由で共有できます。 ただし、これにより、キャッシュとアプリのデータ 全体が意図せずに攻撃者に公開 可能性があります。 これを防ぐには、ファイル プロバイダーのファイル パスオーバーライド ファイルをアプリに追加し、共有前にこのファイルで指定された場所にファイルがコピーされるようにします。

ファイル プロバイダー のファイル パスオーバーライド ファイルをアプリに追加するには、microsoft_maui_essentials_fileprovider_file_paths.xml という名前のファイルをアプリの Platforms\Android\Resources\xml フォルダーに追加します。 したがって、プロジェクトに対する完全な相対ファイル名は、プラットフォーム\Android\Resources\xml\microsoft_maui_essentials_fileprovider_file_paths.xmlです。 次に、必要なパスの XML をファイルに追加します。

 <?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>

ファイル プロバイダーパスの詳細については、developer.android.com の FileProvider を参照してください。

ファイルを共有する前に、オーバーライド ファイルのいずれかの場所にある sharing-root フォルダーに最初に書き込まれるようにする必要があります。

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

共有 URI で共有ルート ディレクトリが除外されている場合は、ファイルが正しく共有されていることを確認できます。 たとえば、CacheDirectory</sharing-root/mydata.txt>ファイルを共有し、共有 URI が content://com.companyname.overwritefileproviderpaths.fileProvider/internal_cache/sharing-root/mydata.txt 場合、ファイル プロバイダーは正しいパスを使用していません。 共有 URI が content://com.companyname.overwritefileproviderpaths.fileProvider/internal_cache/mydata.txt 場合、ファイル プロバイダーは正しいパスを使用しています。

警告

ファイルを共有するときに、"Failed to find configured root that contains /data/data/com.companyname.overwritefileproviderpaths/cache/some-non-sharing-path/mydata.txt" のようなメッセージが含まれる Java.Lang.IllegalArgumentExceptionを受け取った場合、あなたが共有しているファイルは共有ルートの外部にある可能性が非常に高いです。

プレゼンテーションの場所

重要

このセクションは iPadOS にのみ適用されます。

iPadOS で共有を要求したりランチャーを開いたりするときに、ポップオーバーで表示できます。 これは、ポップオーバーが表示される場所を指定し、矢印を直接ポイントします。 この場所は、多くの場合、アクションを起動したコントロールです。 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
    });

ここで説明するすべてが、ShareLauncherで同じように動作します。

ビューの境界を計算するのに役立つ拡張メソッドを次に示します。

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

これは、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
    }
}

Command がトリガーされたときに、呼び出し元の要素を渡すことができます。

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

ViewHelpers クラスの例については、GitHub でホストされている.NET MAUI サンプルを参照してください。

プラットフォームの違い

このセクションでは、共有 API とのプラットフォーム固有の違いについて説明します。