他のアプリにシンプルなデータを送信する

Android では、インテントとそれに関連付けられたエクストラを使用して、ユーザーがお気に入りのアプリを使用して情報をすばやく簡単に共有できるようにします。

Android では、ユーザーがアプリ間でデータを共有するのに、2 つの方法があります。

  • Android Sharesheet は主に、コンテンツをアプリ外に送信したり、コンテンツを直接別のユーザーに送信したりするために設計されています。たとえば、友人との URL の共有などです。
  • Android インテント リゾルバは、明確に定義されたタスクの次のステージにデータを渡すのに最適です。たとえば、アプリから PDF を開き、ユーザーが好みのビューアを選択できるようにします。

インテントを作成するときに、インテントに実行させるアクションを指定します。Android はアクション ACTION_SEND を使用して、あるアクティビティから別のアクティビティにデータを送信します。これはプロセスの境界を越える場合も同様です。データとそのタイプを指定する必要があります。システムにより、データを受信できる互換性のあるアクティビティが自動的に識別され、ユーザーに表示されます。インテント リゾルバの場合、1 つのアクティビティのみがインテントを処理できる場合、そのアクティビティが直ちに開始されます。

Android Sharesheet を使用する理由

アプリ間でのユーザーの一貫性を保つために、Android Sharesheet を使用することを強くおすすめします。アプリ独自の共有ターゲットのリストを表示したり、独自の Sharesheet のバリエーションを作成しないでください。

Android Sharesheet を使用すると、ユーザーは適切な相手と情報を共有し、関連するアプリの提案を 1 回のタップで共有できます。Sharesheet は、カスタム ソリューションでは利用できないターゲットを提案し、一貫したランキングを使用します。これは、Sharesheet が、システムでのみ利用可能なアプリとユーザーのアクティビティに関する情報を考慮できるためです。

また、Android Sharesheet には、デベロッパーにとって便利な機能が多数あります。たとえば、次の操作を行います。

Android Sharesheet を使用する

すべての種類の共有について、インテントを作成し、そのアクションを Intent.ACTION_SEND に設定します。Android Sharesheet を表示するには、Intent.createChooser() を呼び出して Intent オブジェクトを渡します。Android Sharesheet を常に表示するバージョンのインテントが返されます。

テキスト コンテンツを送信する

Android Sharesheet の最も簡単で一般的な使用方法は、あるアクティビティから別のアクティビティにテキスト コンテンツを送信することです。たとえば、ほとんどのブラウザでは、現在表示されているページの URL をテキストとして別のアプリと共有できます。これは、メールやソーシャル ネットワークで記事やウェブサイトを友だちと共有する場合に便利です。以下はその方法の例です。

Kotlin

val sendIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
    type = "text/plain"
}

val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)

Java

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");

Intent shareIntent = Intent.createChooser(sendIntent, null);
startActivity(shareIntent);

必要に応じて、メールの受信者(EXTRA_EMAILEXTRA_CCEXTRA_BCC)やメールの件名(EXTRA_SUBJECT)などの詳細情報を追加できます。

注: Gmail などの一部のメールアプリでは、EXTRA_EMAILEXTRA_CC などのエクストラに String[] が必要です。これらをインテントに追加するには、putExtra(String, String[]) を使用します。

バイナリ コンテンツを送信する

ACTION_SEND アクションを使用してバイナリデータを共有します。次の例に示すように、適切な MIME タイプを設定し、エクストラ EXTRA_STREAM にデータの URI を配置します。これは、画像の共有によく使用されますが、あらゆる種類のバイナリ コンテンツの共有にも使用できます。

Kotlin

val shareIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    // Example: content://com.google.android.apps.photos.contentprovider/...
    putExtra(Intent.EXTRA_STREAM, uriToImage)
    type = "image/jpeg"
}
startActivity(Intent.createChooser(shareIntent, null))

Java

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
// Example: content://com.google.android.apps.photos.contentprovider/...
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, null));

受信側アプリには、Uri が指すデータにアクセスする権限が必要です。推奨される方法は次の 2 つです。

  • データを独自の ContentProvider に保存し、他のアプリがプロバイダにアクセスするための正しい権限を得られるようにします。アクセスを提供する際の推奨メカニズムは、URI ごとの権限を使用することです。これは一時的なものであり、受信側アプリケーションにのみアクセスを許可します。このような ContentProvider を簡単に作成するには、FileProvider ヘルパークラスを使用します。
  • システムの MediaStore を使用します。MediaStore は主に、動画、音声、画像の MIME タイプ用です。ただし、Android 3.0(API レベル 11)以降では、メディア以外のタイプも保存できるようになりました。詳細については、MediaStore.Files をご覧ください。ファイルは、scanFile() を使用して MediaStore に挿入できます。その後、共有に適した content:// スタイルの Uri が、指定された onScanCompleted() コールバックに渡されます。コンテンツがシステム MediaStore に追加されると、デバイス上のどのアプリからでもコンテンツにアクセスできるようになります。

正しい MIME タイプを使用する

送信するデータに使用できる最も具体的な MIME タイプを指定します。たとえば、書式なしテキストを共有する場合は text/plain を使用します。Android で単純なデータを送信する際の一般的な MIME タイプは次のとおりです。

受取人は 送信者が送信
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
`image/*`
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
サポートされているファイル拡張子 application/pdf

MIME タイプの詳細については、MIME メディアタイプの IANA 公式レジストリをご覧ください。

Android Sharesheet は、指定された MIME タイプに応じてコンテンツ プレビューを表示する場合があります。一部のプレビュー機能は、特定のタイプでのみ使用できます。

複数のコンテンツを共有する

複数のコンテンツを共有するには、ACTION_SEND_MULTIPLE アクションをそのコンテンツを指す URI のリストとともに使用します。MIME タイプは、共有するコンテンツの組み合わせによって異なります。たとえば、3 つの JPEG 画像を共有する場合は、タイプ "image/jpg" を使用します。画像タイプが混在している場合は、"image/*" を使用して、任意のタイプの画像を処理するアクティビティと一致させます。複数のタイプを混在させて共有することは可能ですが、受信側にとって何を送信するのかが不明確であるため、この方法はおすすめしません。複数のタイプを送信する必要がある場合は、"*/*" を使用します。データの解析と処理は受信側のアプリケーションが行います。次の例をご覧ください。

Kotlin

val imageUris: ArrayList<Uri> = arrayListOf(
        // Add your image URIs here
        imageUri1,
        imageUri2
)

val shareIntent = Intent().apply {
    action = Intent.ACTION_SEND_MULTIPLE
    putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris)
    type = "image/*"
}
startActivity(Intent.createChooser(shareIntent, null))

Java

ArrayList<Uri> imageUris = new ArrayList<Uri>();
imageUris.add(imageUri1); // Add your image URIs here
imageUris.add(imageUri2);

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, null));

提供された Uri オブジェクトが、受信側アプリがアクセスできるデータを指していることを確認してください。

テキスト プレビューにリッチ コンテンツを追加する

Android 10(API レベル 29)以降では、共有テキストのプレビューが Android Sharesheet に表示されます。場合によっては、共有されているテキストが理解しにくいことがあります。https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4 のような複雑な URL を共有することを検討してください。内容が充実したプレビューで、何が共有されるかをユーザーが安心できます。

テキストをプレビューする場合は、タイトルまたはサムネイル画像、あるいはその両方を設定できます。Intent.createChooser() を呼び出す前に Intent.EXTRA_TITLE に説明を追加し、ClipData を使用して関連するサムネイルを追加します。

注: 画像コンテンツ URI は、FileProvider(通常は構成された <cache-path>)から提供されます。詳細については、ファイルの共有をご覧ください。サムネイルとして使用する画像を読み取るための適切な権限を Sharesheet に付与してください。詳しくは、Intent.FLAG_GRANT_READ_URI_PERMISSION をご覧ください。

次の例をご覧ください。

Kotlin

 val share = Intent.createChooser(Intent().apply {
      action = Intent.ACTION_SEND
      putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/")

      // (Optional) Here you're setting the title of the content
      putExtra(Intent.EXTRA_TITLE, "Introducing content previews")

      // (Optional) Here you're passing a content URI to an image to be displayed
      data = contentUri
      flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
  }, null)
  startActivity(share)

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/");

// (Optional) Here you're setting the title of the content
sendIntent.putExtra(Intent.EXTRA_TITLE, "Introducing content previews");

// (Optional) Here you're passing a content URI to an image to be displayed
sendIntent.setData(contentUri);
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

// Show the Sharesheet
startActivity(Intent.createChooser(sendIntent, null));

プレビューは次のようになります。

Sharesheet にカスタム アクションを追加する

Android Sharesheet のカスタム アクションのスクリーンショット。

Android 14(API レベル 34)以降では、アプリは Android Sharesheet にカスタム アクションを追加できます。カスタム アクションは、Android Sharesheet の上部に小さなアクション アイコンとして表示され、アイコンがクリックされたときに呼び出されるアクションとして Intent をアプリで指定できます。

Android Sharesheet にカスタム アクションを追加するには、まず ChooserAction.Builder を使用して ChooserAction を作成します。アイコンがクリックされたときに呼び出されるアクションとして PendingIntent を指定できます。すべてのカスタム アクションを含む配列を作成し、共有 IntentEXTRA_CHOOSER_CUSTOM_ACTIONS として指定します。

Kotlin

val sendIntent = Intent(Intent.ACTION_SEND)
    .setType("text/plain")
    .putExtra(Intent.EXTRA_TEXT, text)
val shareIntent = Intent.createChooser(sendIntent, null)
val customActions = arrayOf(
    ChooserAction.Builder(
        Icon.createWithResource(context, R.drawable.ic_custom_action),
        "Custom",
        PendingIntent.getBroadcast(
            context,
            1,
            Intent(Intent.ACTION_VIEW),
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
        )
    ).build()
)
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions)
context.startActivity(shareIntent)

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND)
        .setType("text.plain")
        .putExtra(Intent.EXTRA_TEXT, text);
Intent shareIntent = Intent.createChooser(sendIntent, null);
ChooserAction[] actions = new ChooserAction[]{
        new ChooserAction.Builder(
                Icon.createWithResource(context, R.drawable.ic_custom_action),
                "Custom",
                PendingIntent.getBroadcast(
                        context,
                        1,
                        new Intent(Intent.ACTION_VIEW),
                        PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT
                )
        ).build()
};
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions);
context.startActivity(shareIntent);

カスタム ターゲットを追加する

Android Sharesheet では、最大 2 つの ChooserTarget オブジェクトを指定できます。これらのオブジェクトは、ChooserTargetServices から共有ショートカットと選択ツールのターゲットを読み込む前に表示されます。また、アプリの候補の前に一覧表示されるアクティビティを指すインテントを 2 つまで指定することもできます。

Intent.createChooser() を呼び出した後に、共有インテントに Intent.EXTRA_CHOOSER_TARGETSIntent.EXTRA_INITIAL_INTENTS を追加します。

Kotlin

val share = Intent.createChooser(myShareIntent, null).apply {
    putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray)
    putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray)
}

Java

Intent shareIntent = Intent.createChooser(sendIntent, null);
share.putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray);
share.putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray);

この機能の使用には注意が必要です。カスタムの IntentChooserTarget を追加するたびに、システムによって提案される数値が少なくなります。通常、カスタム ターゲットの追加はおすすめしません。Intent.EXTRA_INITIAL_INTENTS を追加する一般的な適切な例は、共有コンテンツに対してユーザーが実行できるその他のアクションを提供することです。たとえば、ユーザーが画像を共有し、Intent.EXTRA_INITIAL_INTENTS を使用してリンクを送信できるようにします。Intent.EXTRA_CHOOSER_TARGETS を追加する一般的な適切な例としては、アプリが提供する関連性の高いユーザーやデバイスを表示する場合が挙げられます。

コンポーネントごとに特定のターゲットを除外する

特定のターゲットを除外するには、Intent.EXTRA_EXCLUDE_COMPONENTS を指定します。この操作は、自身が管理するターゲットを削除する場合にのみ行ってください。一般的なユースケースでは、ユーザーがアプリ内から共有する場合、インテントがアプリ外で共有する可能性が高いため、アプリの共有ターゲットを非表示にします。

Intent.createChooser() を呼び出した後、インテントに Intent.EXTRA_EXCLUDE_COMPONENTS を追加します。

Kotlin

  val share = Intent.createChooser(Intent(), null).apply {
    // Only use for components you have control over
    val excludedComponentNames = arrayOf(ComponentName("com.example.android", "ExampleClass"))
    putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames)
  }

Java

  Intent shareIntent = Intent.createChooser(new Intent(), null);
  // Only use for components you have control over
  ComponentName[] excludedComponentNames = {
          new ComponentName("com.example.android", "ExampleClass")
  };
  shareIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames);

共有に関する情報を取得する

ユーザーが共有するタイミングや、ユーザーが選択したターゲットを把握すると便利です。Android Sharesheet では、ユーザーが選択したターゲットの ComponentNameIntentSender を使用して提供することで、この情報を取得できます。

まず、BroadcastReceiverPendingIntent を作成し、その IntentSenderIntent.createChooser() に指定します。

Kotlin

var share = Intent(Intent.ACTION_SEND)
// ...
val pi = PendingIntent.getBroadcast(
    myContext, requestCode,
    Intent(myContext, MyBroadcastReceiver::class.java),
    PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
share = Intent.createChooser(share, null, pi.intentSender)

Java

Intent share = new Intent(ACTION_SEND);
...
PendingIntent pi = PendingIntent.getBroadcast(myContext, requestCode,
        new Intent(myContext, MyBroadcastReceiver.class),
        PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
share = Intent.createChooser(share, null, pi.getIntentSender());

MyBroadcastReceiver でコールバックを受け取り、Intent.EXTRA_CHOSEN_COMPONENT を確認します。

Kotlin

override fun onReceive(context: Context, intent: Intent) {
  ...
  val clickedComponent : ComponentName = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}

Java

@Override public void onReceive(Context context, Intent intent) {
  ...
  ComponentName clickedComponent = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}

Sharesheet にカスタム アクションを追加する

Android 14(API レベル 34)以降では、アプリは Android Sharesheet にカスタム アクションを追加できます。ChooserAction.Builder を使用して ChooserAction を作成します。アイコンがクリックされたときに呼び出されるアクションとして PendingIntent を指定できます。すべてのカスタム アクションを含む配列を作成し、共有 IntentEXTRA_CHOOSER_CUSTOM_ACTIONS として指定します。

Kotlin

val sendIntent = Intent(Intent.ACTION_SEND)
    .setType("text/plain")
    .putExtra(Intent.EXTRA_TEXT, text)
val shareIntent = Intent.createChooser(sendIntent, null)
val customActions = arrayOf(
    ChooserAction.Builder(
        Icon.createWithResource(context, R.drawable.ic_custom_action),
        "Custom",
        PendingIntent.getBroadcast(
            context,
            1,
            Intent(Intent.ACTION_VIEW),
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
        )
    ).build()
)
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions)
context.startActivity(shareIntent)

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND)
        .setType("text.plain")
        .putExtra(Intent.EXTRA_TEXT, text);
Intent shareIntent = Intent.createChooser(sendIntent, null);
ChooserAction[] actions = new ChooserAction[]{
        new ChooserAction.Builder(
                Icon.createWithResource(context, R.drawable.ic_custom_action),
                "Custom",
                PendingIntent.getBroadcast(
                        context,
                        1,
                        new Intent(Intent.ACTION_VIEW),
                        PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT
                )
        ).build()
};
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions);
context.startActivity(shareIntent);

Android インテント リゾルバを使用する

ACTION_SEND インテント リゾルバのスクリーンショット

Android インテント リゾルバが最もよく使われるのは、明確に定義されたタスクフローの一部として別のアプリにデータを渡す場合です。

Android インテント リゾルバを使用するには、Android Sharesheet を呼び出す場合と同様に、インテントを作成し、エクストラを追加します。ただし、Intent.createChooser()呼び出さないでください

ACTION_SEND と MIME タイプに一致するフィルタを持つアプリが複数インストールされている場合は、「インテント リゾルバ」と呼ばれる確認ダイアログが表示され、ユーザーは共有ターゲットを選択できます。1 つのアプリが一致すると そのアプリが実行されます

Android インテント リゾルバを使用してテキストを送信する例を以下に示します。

Kotlin

val sendIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
    type = "text/plain"
}
startActivity(sendIntent)

Java

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);

さらに詳しく

データの送信の詳細については、インテントとインテント フィルタをご覧ください。