他のアプリからのアクティビティの開始を許可する

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

自分のアプリが実行するアクションが、他のアプリにとっても役に立つ可能性がある場合、自分のアプリがアクション リクエストに応答できるようにすることをおすすめします。その場合、アクティビティで適切なインテント フィルタを指定してください。

たとえば、メッセージや写真をユーザーの友達と共有できるソーシャル アプリを作成する場合、ACTION_SEND インテントをサポートする必要があります。すると、ユーザーが別のアプリで「共有」アクションを開始したとき、図 1 のようなチューザ ダイアログ(「確認ダイアログ」)内に、自分のアプリが選択肢の 1 つとして表示されます。

図 1. チューザ ダイアログ

別のアプリでアクティビティを開始できるようにするには、マニフェスト ファイル内で、対応する <activity> 要素に <intent-filter> 要素を追加する必要があります。

アプリがデバイスにインストールされると、システムがインテント フィルタを識別し、その情報を、すべてのインストール済みアプリがサポートするインテントを登録した内部カタログに追加します。あるアプリが暗黙的インテントを使用して startActivity() または startActivityForResult() を呼び出すと、システムは、そのインテントに応じることができるアクティビティを検出します。

インテント フィルタを追加する

アクティビティが処理可能なインテントを適切に定義するためには、追加するインテント フィルタごとに、アクティビティが受け入れるアクションやデータのタイプをできるだけ具体的に指定する必要があります。

システムがアクティビティに対して所定の Intent を送信するには、そのアクティビティのインテント フィルタが、以下に示す Intent オブジェクトの条件を満たす必要があります。

アクション
実行するアクション名を示す文字列。通常は、ACTION_SENDACTION_VIEW などのプラットフォーム定義値です。

この値は、インテント フィルタ内で <action> 要素を使用して指定します。この要素で指定する値は、API 定数ではなく、アクションを示す完全文字列名にする必要があります(下記の例を参照)。

データ
インテントに関連付けられるデータの説明。

この値は、インテント フィルタ内で <data> 要素を使用して指定します。この要素内で 1 つまたは複数の属性を使用することで、MIME タイプのみ、URI プレフィックスのみ、URI スキームのみ、あるいは受け入れ可能なデータタイプを示す各種属性の組み合わせを指定できます。

注: Uri データに関する詳細を宣言する必要がない場合(たとえば、アクティビティが URI ではなく別の種類の「エクストラ」データを処理する場合)は、text/plainimage/jpeg など、アクティビティが処理するデータタイプを宣言する android:mimeType 属性のみを指定することをおすすめします。

カテゴリ
インテントを処理するアクティビティの性質(通常はユーザー ジェスチャーやアクションが開始された場所に関連)を示すもう一つの方法です。システムがサポートするカテゴリがいくつか用意されていますが、大半のカテゴリはほとんど使用されません。例外的に、暗黙的インテントはすべて、デフォルトで CATEGORY_DEFAULT を使用して定義されます。

この値は、インテント フィルタ内で <category> 要素を使用して指定します。

アクティビティが受け入れる条件をインテント フィルタ内で宣言するには、各条件に対応する XML 要素を <intent-filter> 要素内にネストします。

データタイプがテキストか画像の場合に ACTION_SEND インテントを処理するインテント フィルタが追加されたアクティビティの例を以下に示します。

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

ヒント: チューザ ダイアログに表示されるアイコンを、アクティビティのデフォルト アイコンとは別のものにする場合は、<intent-filter> 要素の中に android:icon を追加します。

受信する各インテントには、それぞれ 1 つのアクションと 1 つのデータタイプだけを指定します。ただし、各 <intent-filter> 内で、<action> 要素、<category> 要素、<data> 要素の複数のインスタンスを宣言することは可能です。

アクションとデータのペアが 2 つあり、それぞれの動作において相互に排他的である場合は、それぞれ別個のインテント フィルタを作成して、どのデータタイプと組み合わせたときにどのアクションが受け入れ可能になるのかを指定することをおすすめします。

たとえば、ACTION_SENDACTION_SENDTO の両方のインテントに対し、アクティビティでテキストと画像の両方を処理することにします。この場合、ACTION_SENDTO インテントの方は、データ Uri を使用し、send または sendto の URI スキームを使用して受信者アドレスを指定する必要があるため、2 つのアクション用に 2 つのインテント フィルタを定義する必要があります。次に例を示します。

<activity android:name="ShareActivity">
    <!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms" />
        <data android:scheme="smsto" />
    </intent-filter>
    <!-- filter for sending text or images; accepts SEND action and text or image data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

注: 暗黙的インテントを受け取るには、インテント フィルタ内に CATEGORY_DEFAULT カテゴリを含める必要があります。startActivity() メソッドと startActivityForResult() メソッドは、CATEGORY_DEFAULT カテゴリを宣言しているものとして、すべてのインテントを処理します。インテント フィルタ内で宣言していない場合、暗黙的インテントはアクティビティに変換されません。

ソーシャル共有動作を実行する ACTION_SEND インテントの送受信方法については、他のアプリからシンプルなデータを受信するをご覧ください。また、データの共有については、シンプルなデータを共有するファイルの共有もご覧ください。

アクティビティ内でインテントを処理する

アクティビティ内で実行するアクションを決定するには、アクティビティの開始時に使用された Intent を読み取ります。

アクティビティが開始したら、getIntent() を呼び出して、アクティビティを開始した Intent を取得します。この処理は、アクティビティのライフサイクル中であれば、いつでも行うことができますが、通常は、onCreate()onStart() など、早い段階のコールバックの間に行うことをおすすめします。

次に例を示します。

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.main)

    val data: Uri? = intent?.data

    // Figure out what to do based on the intent type
    if (intent?.type?.startsWith("image/") == true) {
        // Handle intents with image data ...
    } else if (intent?.type == "text/plain") {
        // Handle intents with text ...
    }
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // Get the intent that started this activity
    Intent intent = getIntent();
    Uri data = intent.getData();

    // Figure out what to do based on the intent type
    if (intent.getType().indexOf("image/") != -1) {
        // Handle intents with image data ...
    } else if (intent.getType().equals("text/plain")) {
        // Handle intents with text ...
    }
}

結果を返す

呼び出し元のアクティビティに結果を返す場合は、setResult() を呼び出して、結果コードと結果 Intent を指定します。処理の完了後にユーザーを元のアクティビティに戻す場合は、finish() を呼び出して、アクティビティを閉じます(その後破棄します)。次に例を示します。

Kotlin

// Create intent to deliver some kind of result data
Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result ->
    setResult(Activity.RESULT_OK, result)
}
finish()

Java

// Create intent to deliver some kind of result data
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
setResult(Activity.RESULT_OK, result);
finish();

結果に対しては、常に結果コードを指定する必要があります。通常は、RESULT_OKRESULT_CANCELED です。必要に応じて、Intent を使用することで、追加のデータを指定できます。

注: 結果は、デフォルトでは RESULT_CANCELED に設定されています。そのため、アクションが完了する前にユーザーが「戻る」ボタンを押し、結果コードの設定が行われなかった場合、元のアクティビティは「キャンセルされた」結果を受け取ります。

結果オプションが複数あり、そのいずれかを示す整数を返す必要がある場合は、結果コードを 0 よりも大きい任意の値に設定できます。結果コードを使用して整数を返す場合に、Intent を含める必要がなければ、setResult() を呼び出すことで、結果コードだけを渡すことができます。次に例を示します。

Kotlin

setResult(RESULT_COLOR_RED)
finish()

Java

setResult(RESULT_COLOR_RED);
finish();

この場合、可能性のある結果の数はわずかであるため、結果コードは、ローカルに定義されている整数(0 より大きい)になります。この方法は、自分のアプリ内のアクティビティに結果を返す場合に適しています。結果を受け取ったアクティビティがパブリック定数を参照して、結果コードの値を判断できるからです。

注: 自分のアクティビティを開始したのが startActivity() であるのか startActivityForResult() であるのかをチェックする必要はありません。アクティビティを開始したインテントに結果を返す必要がある場合は、単純に setResult() を呼び出します。元のアクティビティがあらかじめ startActivityForResult() を呼び出していた場合は、setResult() に提供した結果が自動的に配信されます。そうでない場合、結果は無視されます。