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

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 に挿入できます。その後、共有に適した 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));

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

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

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 を使用すると、ChooserTargetServices から共有ショートカットと選択ツール ターゲットを読み込む前に表示される ChooserTarget オブジェクトを 2 つまで指定できます。アプリの候補の前にリストされているアクティビティを指すインテントも 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 では、IntentSender を使用してユーザーが選択するターゲットの ComponentName を指定することで、この情報を取得できます。

まず、BroadcastReceiverPendingIntent を作成し、Intent.createChooser() でその IntentSender を指定します。

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

詳細

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