他のアプリからシンプルなデータを受信する

1 つのアプリから別のアプリへデータを送信できるのと同様に、他のアプリからデータを受信することもできます。ユーザーがアプリをどのように操作するのか、他のアプリからどのデータタイプを受け取るのかを検討する必要があります。たとえば、ソーシャル ネットワーキング アプリの場合、興味深いウェブ URL など、テキスト コンテンツを他のアプリから受信できると便利です。

他のアプリのユーザーは、Android Sharesheet やインテント リゾルバを通じてアプリにデータを送信することがよくあります。アプリにデータを送信するアプリは、そのデータの MIME タイプを設定する必要があります。アプリは、次の方法で他のアプリから送信されたデータを受信できます。

  • マニフェスト内の intent-filter タグに合致する Activity
  • アプリが公開している共有ショートカット。

ダイレクト シェア ターゲットは、アプリ内の特定のアクティビティへのディープリンクです。多くの場合、このようなディープリンクはユーザーまたはグループを指し示し、Android Sharesheet に表示されます。たとえば、メッセージ アプリの場合、各ユーザーを対象とするダイレクト シェア ターゲットを提供すると便利です。ダイレクト シェア ターゲットをタップすると、ディープリンクの機能により、直接そのユーザーとのスレッドを開始できます。詳細な手順については、直接共有ターゲットを提供するをご覧ください。

MIME タイプをサポートする

理想的には、アプリは可能な限り幅広い MIME タイプを受信できる必要があります。たとえば、テキスト、画像、動画の送信に設計されたメッセージ アプリは、text/*image/*video/* の受信をサポートする必要があります。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 メディアタイプの IANA 公式レジストリをご覧ください。

適切な共有ターゲットを作成する

特定のアクティビティに関連付けられた共有ターゲットをユーザーがタップしたときは、共有コンテンツの使用を開始する前に、その確認や編集が可能になっている必要があります。この機能は、特にテキストデータの場合に重要になります。

アクティビティを使用してデータを受信する

アクティビティでデータを受信するには、マニフェストの更新、受信コンテンツの処理、ユーザーがアプリを認識できるようにすることが必要になります。

マニフェストを更新する

インテント フィルタは、アプリ コンポーネントが受け入れるインテントをシステムに通知します。レッスン「他のアプリにシンプルなデータを送信する」で ACTION_SEND アクションを使用してインテントを作成した方法と同じように、このアクションを使用してインテントを受信できるようにインテント フィルタを作成します。<intent-filter> 要素を使用して、マニフェスト内でインテント フィルタを定義します。たとえば、アプリがテキスト コンテンツの受信を処理する場合、任意のタイプの画像を 1 つ以上含むマニフェストは次のスニペットのように記述します。

<activity android:name=".ui.MyActivity" >
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND_MULTIPLE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
</activity>

別のアプリがインテントを作成して startActivity() に渡すことで、上記のデータタイプのいずれかを共有しようとすると、受信側アプリのリストが Android Sharesheet またはインテント リゾルバ内に表示されます。ユーザーがアプリを選択すると、対応するアクティビティ(上記の例では .ui.MyActivity)が開始されます。その後、受信側アプリが、コードや UI 内でコンテンツを適切に処理します。

受信コンテンツを処理する

Intent によって配信されたコンテンツを処理するには、getIntent() を呼び出して Intent オブジェクトを取得します。オブジェクトを取得したら、そのコンテンツを調査して、次に何をすべきかを判断します。システム内の別の場所(ランチャーなど)からこのアクティビティを起動できる場合は、インテントを調査する際にこの点を考慮してください。

受信データをチェックする場合は特に注意してください。他のアプリから何が送信されたのかを事前に知ることは決してできません。たとえば、MIME タイプが誤って設定されている場合や、送信された画像が極端に大きい場合などがあります。必ず、メイン(「UI」)スレッドではなく、別個のスレッドでバイナリデータを処理するようにしてください。

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    when {
        intent?.action == Intent.ACTION_SEND -> {
            if ("text/plain" == intent.type) {
                handleSendText(intent) // Handle text being sent
            } else if (intent.type?.startsWith("image/") == true) {
                handleSendImage(intent) // Handle single image being sent
            }
        }
        intent?.action == Intent.ACTION_SEND_MULTIPLE
                && intent.type?.startsWith("image/") == true -> {
                handleSendMultipleImages(intent) // Handle multiple images being sent
        }
        else -> {
            // Handle other intents, such as being started from the home screen
        }
    }
    ...
}

private fun handleSendText(intent: Intent) {
    intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
        // Update UI to reflect text being shared
    }
}

private fun handleSendImage(intent: Intent) {
    (intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as? Uri)?.let {
        // Update UI to reflect image being shared
    }
}

private fun handleSendMultipleImages(intent: Intent) {
    intent.getParcelableArrayListExtra<Parcelable>(Intent.EXTRA_STREAM)?.let {
        // Update UI to reflect multiple images being shared
    }
}

Java

void onCreate (Bundle savedInstanceState) {
    ...
    // Get intent, action and MIME type
    Intent intent = getIntent();
    String action = intent.getAction();
    String type = intent.getType();

    if (Intent.ACTION_SEND.equals(action) && type != null) {
        if ("text/plain".equals(type)) {
            handleSendText(intent); // Handle text being sent
        } else if (type.startsWith("image/")) {
            handleSendImage(intent); // Handle single image being sent
        }
    } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
        if (type.startsWith("image/")) {
            handleSendMultipleImages(intent); // Handle multiple images being sent
        }
    } else {
        // Handle other intents, such as being started from the home screen
    }
    ...
}

void handleSendText(Intent intent) {
    String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
    if (sharedText != null) {
        // Update UI to reflect text being shared
    }
}

void handleSendImage(Intent intent) {
    Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
    if (imageUri != null) {
        // Update UI to reflect image being shared
    }
}

void handleSendMultipleImages(Intent intent) {
    ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
    if (imageUris != null) {
        // Update UI to reflect multiple images being shared
    }
}

データを受信した後の UI の更新としては、EditText を指定するだけのシンプルなケースもあれば、魅力的な写真フィルタを画像に適用するような高度なケースもあります。その後の処理方法は、アプリによって異なります。

アプリがユーザーに認識されるようにする

アプリは、Android Sharesheet やインテント リゾルバ内でアイコンラベルで示されます。これらはいずれもマニフェスト内で定義します。アクティビティ ラベルやインテント フィルタ ラベルを設定すると、詳細なコンテキストを提供できます。

Android 10(API レベル 29)以降、Android Sharesheet が使用するアイコンは、マニフェスト内で application タグに対して設定されたアイコンに限られるようになりました。Android では、intent-filter タグと activity タグに設定されたアイコンは無視されます。