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

アプリが他のアプリにデータを送信できるのと同様に、他のアプリからデータを受信することもできます。ユーザーがアプリをどのように操作するか、また他のアプリからどのデータタイプを受信するかを検討します。たとえば、ソーシャル ネットワーキング アプリケーションで、興味深いウェブ 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 タグで設定されたアイコンを無視します。