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

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 ごとの権限を使用することです。これは一時的なものであり、受信側アプリケーションにのみアクセスを許可します。FileProvider ヘルパークラスを使用すると、このような ContentProvider を簡単に作成できます。
  • システム MediaStore を使用する。MediaStore は主に、動画、音声、画像の MIME タイプ用です。ただし、Android 3.0(API レベル 11)以降では、メディア以外のタイプも保存できるようになりました。詳細については、MediaStore.Files をご覧ください。scanFile() を使用してファイルを MediaStore に挿入でき、その後、与えられた onScanCompleted() コールバックに、共有に適した content:// スタイルの Uri が渡されます。コンテンツがシステム 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 タイプに応じてコンテンツのプレビューを表示する場合があります。一部のプレビュー機能は、特定のタイプでのみ使用できます。

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

複数のコンテンツを共有するには、コンテンツを指す URI のリストを添えて、ACTION_SEND_MULTIPLE アクションを使用します。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 の共有シートのカスタム アクションのスクリーンショット。

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

共有シートにカスタム アクションを追加する

Android 14(API レベル 34)以降では、アプリは Android Sharesheet にカスタム アクションを追加できます。ChooserAction.BuilderChooserAction を作成します。アイコンがクリックされたときに呼び出されるアクションとして 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);

詳細

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