他のアプリへの単純なデータの送信

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
        putExtra(Intent.EXTRA_STREAM, uriToImage)
        type = "image/jpeg"
    }
    startActivity(Intent.createChooser(shareIntent, resources.getText(R.string.send_to)))
    

Java

    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
    shareIntent.setType("image/jpeg");
    startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
    

受信アプリケーションには、Uri が指すデータへのアクセス権が必要です。以下は、これを行うためのおすすめの方法です。

  • 自分の 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/plaintext/rtftext/htmltext/json: 受信者は text/* に登録する必要があります
  • image/jpgimage/pngimage/gif: 受信者は image/* に登録する必要があります
  • video/mp4video/3gp: 受信者は video/* に登録する必要があります
  • application/pdf: 受信者はサポートされているファイル拡張子に登録する必要があります
  • */* という MIME タイプは使用しないことを強くおすすめします。この使用が適しているのは、汎用データ ストリームを処理できるアクティビティだけです。

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

MIME メディアタイプの IANA 公式レジストリをご覧ください。

複数コンテンツの共有

複数のコンテンツを共有するには、コンテンツを指す 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, "Share images to.."))
    

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, "Share images to.."));
    

与えられた URIs は、受信アプリケーションがアクセスできるデータを指していることに注意してください。

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

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

テキストをプレビューする場合は、タイトルまたはサムネイル画像、あるいはその両方を設定できます。Intent.EXTRA_TITLE に説明を追加してから、Intent.createChooser() を呼び出します。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 we're setting the title of the content
          putExtra(Intent.EXTRA_TITLE, "Introducing content previews")

          // (Optional) Here we're passing a content URI to an image to be displayed
          setClipData(contentUri);
          setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
      }, null)
      startActivity(share)
    

Java

    Intent sendIntent = new Intent(Intent.ACTION_SEND);
    sendIntent.putExtra(Intent.EXTRA_TEXT, "Hello!");

    // (Optional) Here we're setting the title of the content
    sendIntent.putExtra(Intent.EXTRA_TITLE, "Send message");

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

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

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

カスタム ターゲットの追加

Android Sharesheet では、ChooserTargetServices から読み込んだ共有ショートカットと ChooserTarget の前に表示する、限られた数の ChooserTarget オブジェクトを指定できます。また、アプリの候補の前に一覧表示されるアクティビティを指す、限られた数のインテントも指定できます。

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

Kotlin

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

Java

    val share = Intent.createChooser(myShareIntent, 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.EXTRA_EXCLUDE_COMPONENTS を、Intent.createChooser() を呼び出した後で、インテントに追加します。

Kotlin

    val share = Intent.createChooser(myShareIntent, null).apply {
      // Only use components you have control over
      share.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, myComponentArray)
    }
    

Java

    share = Intent.createChooser(myShareIntent, null);
    // Only use components you have control over
    share.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, myComponentArray);
    

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

ユーザーが共有しようとするタイミングと、どのターゲットを選択したのかがわかると便利です。Android Sharesheet では、ユーザーがクリックするターゲットの ComponentNameIntentSender を介して提供することにより、これが実現されています。

最初に BroadcastReceiverPendingIntent を作成して、その IntentSenderIntent.createChooser() に与えます。

Kotlin

    var share = new Intent(Intent.ACTION_SEND);
    ...
    val pi = PendingIntent.getBroadcast(myContext, requestCode, Intent(myContext, MyBroadcastReceiver.class),
    Intent.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),
                    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 インテント リゾルバを使用する

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

詳細

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