The Android Developer Challenge is back! Submit your idea before December 2.

インテントとインテント フィルタ

Intent は、別のアプリ コンポーネントからのアクションをリクエストするときに使用できるメッセージング オブジェクトです。インテントはコンポーネント間のコミュニケーションをいくつかの方法で円滑化しますが、基本的な使用例は次の 3 つです。

  • アクティビティを開始する

    Activity はアプリ内の 1 つの画面を表しています。Activity の新しいインスタンスを開始するには、IntentstartActivity() に渡します。Intent には、開始するアクティビティが記述され、必要なデータがすべて含まれています。

    アクティビティの完了時に結果を受け取りたい場合は、startActivityForResult() を呼び出します。アクティビティは、結果を別個の Intent オブジェクトとして、アクティビティの onActivityResult() callback で受け取ります。詳細については、アクティビティのガイドをご覧ください。

  • サービスを開始する

    Service は、ユーザー インターフェースを持たず、バックグラウンドで操作を実行するコンポーネントです。Android 5.0(API レベル 21)以降では、JobScheduler を使用してサービスを開始できます。JobScheduler の詳細については、API-reference documentation をご覧ください。

    Android 5.0(API レベル 21)より前のバージョンでは、Service クラスのメソッドを使用してサービスを開始できます。1 回限りの操作を実行する(ファイルのダウンロードなど)サービスを開始するには、IntentstartService() に渡します。Intent には、開始するサービスが記述され、必要なデータがすべて含まれています。

    サービスのデザインにクライアントサーバーのインターフェースがある場合、IntentbindService() に渡して、他のコンポーネントからのサービスにバインドできます。詳細については、サービスのガイドをご覧ください。

  • ブロードキャストを配信する

    ブロードキャストは、どんなアプリでも受け取ることができるメッセージです。システムは、システムの起動や端末の充電開始など、さまざまなシステム イベントに関するブロードキャストを配信します。他のアプリにブロードキャストを配信するには、IntentsendBroadcast() または sendOrderedBroadcast() に渡します。

これから、インテントの仕組みと使用方法について説明します。他のアプリとの連携処理コンテンツの共有にも関連する情報がありますのでご覧ください。

インテントのタイプ

インテントには次の 2 つのタイプがあります。

  • 明示的インテントは、ターゲット アプリのパッケージ名またはコンポーネントの完全修飾クラス名を指定して、インテントを実行するアプリを指定します。たいてい明示的インテントを使って自分のアプリのコンポーネントを開始します。開始したいアクティビティやサービスのクラス名を知っているからです。たとえば、ユーザー操作に応答して自分のアプリ内で新しいアクティビティを開始したり、バックグラウンドでファイルをダウンロードするサービスを開始したりします。
  • 暗黙的インテントでは、特定のコンポーネントを指名するのではなく、実行する一般的な操作を宣言することで、別のアプリのコンポーネントが処理できるようにします。たとえば、ユーザーに地図上のある場所を示したい場合、暗黙的インテントを使って別のアプリが指定された場所を地図上に表示するようリクエストします。

図 1 は、アクティビティを開始するときにインテントがどのように使用されるかを示しています。Intent オブジェクトで特定のアクティビティ コンポーネントが明示的に指定されていると、そのコンポーネントが即座に開始されます。

図 1 別のアクティビティを開始する暗黙的インテントがシステム内でどのように配信されるかを表しています。[1] Activity A がアクションを記述した Intent を作成し、それを startActivity() に渡します。[2] Android システムがすべてのアプリを検索し、そのインテントに一致するインテント フィルタを探します。一致するものが見つかったら、[3] システムが onCreate() メソッドを呼び出して、Intent に渡すことで、その一致したアクティビティ(Activity B)を開始します。

暗黙的インテントを使用すると、Android システムはインテントの内容を、端末上の他のアプリのマニフェスト ファイルで定義されたインテント フィルタと比較して、開始する適切なコンポーネントを見つけます。インテントがインテント フィルタに一致した場合、システムがそのコンポーネントを開始して、それに Intent オブジェクトを配信します。互換性のあるインテント フィルタが複数ある場合、ユーザーが使用するアプリを選択できるダイアログが表示されます。

インテント フィルタは、コンポーネントが受け取りたいインテントのタイプを指定する式で、アプリのマニフェスト ファイルに含まれています。たとえば、アクティビティのインテント フィルタを宣言すると、特定の種類のインテントを使って、アクティビティを他のアプリから直接開始できるようになります。同様に、アクティビティのインテント フィルタを宣言しない場合は、明示的インテントでのみアクティビティを開始できます。

注意:アプリの安全性を保つため、Service を開始するときは常に明示的インテントを使用し、サービスのインテント フィルタは宣言しないでください。暗黙的インテントを使ってサービスを開始すると、どのサービスがインテントに応答するかを把握できず、どのサービスが開始するのかがユーザーにもわからないため、セキュリティ上の危険があります。Android 5.0(API レベル 21)以降では、暗黙的インテントで bindService() を呼び出すと、システムから例外がスローされます。

インテントをビルドする

Intent オブジェクトには、Android システムが開始するコンポーネントを判断する際に使用する情報(インテントを受け取る正確なコンポーネント名やコンポーネントのカテゴリなど)に加えて、受け取る側のコンポーネントがアクションを適切に実行するために使用する情報(実行するアクションと、実行対象のデータなど)が含まれています。

Intent に含まれる主な情報は次のとおりです。

コンポーネント名
開始するコンポーネントの名前。

これは任意ですが、インテントを明示的にするためには不可欠な情報です。つまり、コンポーネント名で定義されたアプリ コンポーネントにのみインテントが配信されます。コンポーネント名がない場合、インテントは暗黙的になり、他のインテント情報(アクション、データ、カテゴリなど — 下記で説明)に基づいて、インテントを受け取るコンポーネントをシステムが決定します。そのため、自分のアプリの特定のコンポーネントを開始する必要がある場合は、コンポーネント名を指定してください。

注:Service を開始するときは、必ずコンポーネント名を指定してください。指定しない場合、どのサービスがインテントに応答するかが把握できず、どのサービスが開始するのかがユーザーにも見えません。

Intent のこの項目は ComponentName オブジェクトです。アプリのパッケージ名など、ターゲット コンポーネントの完全修飾クラス名を使用して指定できます(例: com.example.ExampleActivity)。コンポーネント名は、setComponent()setClass()setClassName()、または Intent コンストラクタのいずれかを使用して設定できます。

アクション
実行する一般的なアクション(表示選択など)を指定する文字列です。

ブロードキャスト インテントの場合、これは発生済みで報告済みのアクションになります。アクションによって、残りのインテントがどのように構成されるか — 特にデータやエクストラに含まれる情報がだいたい決まります。

自分のアプリ内でインテントにより使用される(または他のアプリで使用される、自分のアプリのコンポーネントを呼び出す)独自のアクションを指定できますが、普通は Intent クラスや他のフレームワーク クラスで定義されたアクション定数を指定します。アクティビティを開始するための一般的なアクションをいくつかご紹介します。

ACTION_VIEW
ギャラリー アプリで表示する写真や、マップアプリで表示する住所など、アクティビティがユーザーに表示できる情報がある場合は、インテントにこのアクションを使用し、startActivity() に渡します。
ACTION_SEND
これは共有インテントとしても知られており、メールアプリやソーシャル シェアリング アプリなどの別のアプリからユーザーが共有できるデータがある場合、インテントにこれを使用し、startActivity() に渡します。

一般的なアクションを定義するその他の定数については、Intent クラスのリファレンスをご覧ください。他のアクションは Android フレームワークの別の場所で定義されています。たとえば、システムの設定アプリの特定の画面を開くアクションは Settings で定義されます。

インテントのアクションは、setAction()Intent コンストラクタを使って指定できます。

独自のアクションを定義したら、次の例に示されているように、接頭辞としてアプリのパッケージ名を必ず含めてください。

Kotlin

const val ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL"

Java

static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
データ
アクションの実行対象であるデータや、データの MIME タイプを参照する URI(Uri オブジェクト)。指定されるデータのタイプは、通常インテントのアクションによって決まります。たとえば、アクションが ACTION_EDIT の場合、データには編集するドキュメントの URI が含まれます。

インテントの作成時、URI だけでなくデータのタイプ(MINE タイプ)も指定することがしばしば重要になります。たとえば、画像を表示できるアクティビティの場合、URI 形式は似ていてもオーディオ ファイルは再生できません。データの MIME タイプを指定することで、Android システムがインテントを受け取るのに最適なコンポーネントを見つけることができます。ただし、MIME タイプは URI から推測できることもあります。— 特にデータが content: URI の場合はそうです。content: URI は、データが端末上にあり、ContentProvider により制御されていることを示してます。それで、システムがデータの MIME タイプを判別することができます。

データ URI のみを設定するには、setData() を呼び出します。MIME タイプのみを設定するには、setType() を呼び出します。必要であれば、setDataAndType() で、両方を明示的に設定することもできます。

注意:URI と MIME タイプの両方を設定する場合は、お互いの値を無効にしてしまわないよう、setData()setType()呼び出さないでください。URI と MIME タイプの両方を設定する場合は、常に setDataAndType() を使用してください。

カテゴリ
インテントを処理するコンポーネントの種類に関する追加情報が含まれた文字列です。カテゴリの記述はインテントにいくつでも含めることができますが、ほとんどのインテントではカテゴリは必須ではありません。よく使われるカテゴリの例を次に示します。
CATEGORY_BROWSABLE
ターゲットのアクティビティは、ウェブブラウザから開始してリンクで参照されているデータ(画像やメール メッセージなど)を表示できます。
CATEGORY_LAUNCHER
このアクティビティはタスクの初期アクティビティで、システムのアプリケーション ランチャーの一覧に表示されます。

カテゴリの全一覧は、Intent クラスの記述をご覧ください。

カテゴリは addCategory() で指定できます。

上記のプロパティ(コンポーネント名、アクション、データ、カテゴリ)は、インテントを定義付ける特性を表しています。これらのプロパティを読み取ることで、Android システムはどのアプリ コンポーネントを開始すべきかを解決できます。しかし、アプリ コンポーネントの解決に影響を与えない追加情報をインテントに含めることもできます。インテントに含めることのできる情報は次のとおりです。

エクストラ
リクエストされたアクションの実行に必要な追加情報が入っているキー/値のペアです。特定の種類のデータ URI を使用するアクションもあれば、特定のエクストラを使用するアクションもあります。

エクストラ データはさまざまな putExtra() メソッドを使って追加でき、それぞれキー名と値の 2 つのパラメータを受け入れます。また、すべてのエクストラ データを含む Bundle オブジェクトを作成し、putExtras() を使って BundleIntent に挿入することもできます。

たとえば、ACTION_SEND を使ってメールを送信するインテントを作成するとき、EXTRA_EMAIL キーを使って宛先の受信者を指定したり、EXTRA_SUBJECT キーを使って件名を指定したりできます。

Intent クラスは、標準化されたデータタイプの EXTRA_* 定数を複数指定できます。独自のエクストラ キーを(あなたのアプリが受け取るインテント用に)宣言する必要がある場合は、次の例のように、アプリのパッケージ名を接頭辞として必ず含めてください。

Kotlin

const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"

Java

static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";

注意:他のアプリが受信するインテントを送信する場合は、ParcelableSerializable を使用しないでください。アプリが Bundle オブジェクトのデータにアクセスしようとして、パーセル化クラスまたはシリアル化クラスにアクセスできなかった場合、システムは RuntimeException を出します。

フラグ
フラグは Intent クラスで定義され、インテントのメタデータとして機能します。フラグは、Android システムにアクティビティの起動方法(アクティビティがどのタスクに属するかなど)や、起動後の取り扱い方法(最近のアクティビティの一覧に含めるかどうかなど)を指示します。

詳細については、setFlags() メソッドをご覧ください。

明示的インテントの例

明示的インテントは、自分のアプリの特定のアクティビティやサービスなど、特定のアプリ コンポーネントを起動する際に使用するものです。明示的インテントを作成するには、Intent オブジェクトでコンポーネント名を定義します — 他のインテント プロパティはすべて省略可能です。

たとえば、ウェブからファイルをダウンロードする DownloadService というサービスをアプリに作成した場合、次のコードでそれを開始できます。

Kotlin

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
val downloadIntent = Intent(this, DownloadService::class.java).apply {
    data = Uri.parse(fileUrl)
}
startService(downloadIntent)

Java

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);

Intent(Context, Class) コンストラクタが、アプリに Context を、コンポーネントに Class オブジェクトを供給します。このようにして、このインテントはアプリの DownloadService クラスを明示的に開始します。

サービスのビルドと開始について詳しくは、サービスのガイドをご覧ください。

暗黙的インテントの例

暗黙的インテントは、アクションを指定し、それを実行できる端末上のアプリを起動させます。暗黙的インテントは、自分のアプリではそのアクションを実行できないが、他のアプリでは実行可能であり、どのアプリを使うかをユーザーに選ばせたい場合に便利です。

たとえば、ユーザーに他の人と共有してほしいコンテンツがある場合は、ACTION_SEND アクションを使ってインテントを作成し、共有するコンテンツを指定するエクストラを追加します。そのインテントを使って startActivity() を呼び出すと、ユーザーはどのアプリでコンテンツを共有するかを選択できます。

注意:startActivity() に送る暗黙的インテントを処理できるアプリをユーザーが持っていない場合があります。あるいは、管理者が敷いたプロファイル上の制限や設定により、アプリがアクセス不可になっている場合があります。そのような場合、呼び出しが失敗し、あなたのアプリはクラッシュします。アクティビティがインテントを受け取ることを確かめるには、Intent オブジェクトで resolveActivity() を呼び出してください。結果が null 以外の場合は、インテントを処理できるアプリが少なくとも 1 つあるということなので、startActivity() を安全に呼び出すことができます。結果が null の場合は、そのインテントは使用しないでください。可能であればそのインテントを発行する機能を無効にしてください。次の例は、インテントがアクティビティを解決することを確かめる方法を示しています。この例では URI を使用せず、インテントのデータタイプを宣言することで、エクストラの内容を指定しています。

Kotlin

// Create the text message with a string
val sendIntent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, textMessage)
    type = "text/plain"
}

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(packageManager) != null) {
    startActivity(sendIntent)
}

Java

// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(sendIntent);
}

startActivity() が呼び出されると、システムはすべてのインストール済みアプリを調べ、どのアプリがこの種類のインテント(ACTION_SEND アクションと「テキスト / プレーン」データが含まれるインテント)を処理できるかを判別します。インテントを処理できるアプリが 1 つしかない場合は、そのアプリがすぐに開いてインテントを受け取ります。インテントを処理できるアクティビティが複数ある場合、図 2 のような、使用するアプリをユーザーが選択できるダイアログが表示されます。

他のアプリの起動に関しては、別のアプリにユーザーを送信するもご覧ください。

図 2 チューザ ダイアログ。

アプリチューザを表示する

暗黙的インテントに応答するアプリが 2 つ以上ある場合、ユーザーは使用するアプリを選択でき、そのアプリをアクションのデフォルトの選択肢にすることができます。このようなデフォルトを選択する機能は、ウェブページを開くといったアクションの実行時に、ユーザーが今後同じアプリの使用を希望するような場合に便利です(ユーザーは常に同じウェブブラウザを使用する傾向があります)。

ただし、インテントに応答するアプリが複数あって、ユーザーが毎回別のアプリを使用する可能性がある場合は、チューザ ダイアログを明示的に表示させてください。チューザ ダイアログで、ユーザーがアクションに使用するアプリを選択することができます(アクションのデフォルトのアプリは選択できません)。たとえば、あなたのアプリが ACTION_SEND アクションで「共有」を実行するとき、ユーザーはその時の状況によっては別のアプリを使用して共有したいと思うかもしれません。それで、図 2 のようなチューザ ダイアログを常に使用してください。

チューザを表示するには、次の例のように、createChooser() を使用して Intent を作成し、startActivity() に渡します。この例では、createChooser() メソッドに渡されたインテントに応答するアプリのリストがダイアログに表示され、ダイアログのタイトルに指定されたテキストが使用されています。

Kotlin

val sendIntent = Intent(Intent.ACTION_SEND)
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
val title: String = resources.getString(R.string.chooser_title)
// Create intent to show the chooser dialog
val chooser: Intent = Intent.createChooser(sendIntent, title)

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(packageManager) != null) {
    startActivity(chooser)
}

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

暗黙的インテントを受け取る

あなたのアプリが受け取ることのできる暗黙的インテントを告知するには、マニフェスト ファイル<intent-filter> 要素を使って、それぞれのアプリ コンポーネントに対して 1 つ以上のインテント フィルタを宣言します。各インテント フィルタは、インテントのアクション、データ、カテゴリに基づいて、受け入れるインテントのタイプを指定します。インテントがいずれかのインテント フィルタを通過した場合のみ、システムが暗黙的インテントをあなたのアプリ コンポーネントに配信します。

注:明示的インテントは、コンポーネントが宣言しているインテント フィルタに関係なく、常にターゲットに配信されます。

アプリ コンポーネントは、実行できる固有のジョブに対してそれぞれ個別にフィルタを宣言する必要があります。たとえば、画像ギャラリーのアプリの 1 つのアクティビティには、画像を表示するフィルタと画像を編集するフィルタが 2 つある場合があります。このアクティビティが開始すると、Intent を調べ、Intent にある情報に基づいてどのように動作するかを決定します(編集コントロールを表示するかどうかなど)。

各インテント フィルタは、アプリのマニフェスト ファイルの <intent-filter> 要素で定義されていて、対応するアプリ コンポーネント(<activity> 要素など)にネストされます。<intent-filter> 内で、次の 3 つの要素の中から 1 つ以上を使用して、受け入れるインテントのタイプを指定できます。

<action>
name 属性で、受け入れるインテントのアクションを宣言します。値は、クラス定数ではなく、アクションのリテラル文字列値である必要があります。
<data>
データ URI(schemehostportpath)と MIME タイプのさまざまな側面を指定する 1 つ以上の属性を使用して、受け入れるデータのタイプを宣言します。
<category>
name 属性で、受け入れるインテント カテゴリを宣言します。値は、クラス定数ではなく、アクションのリテラル文字列値である必要があります。

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

例として、データ タイプがテキストの場合に 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"/>
    </intent-filter>
</activity>

<action><data><category> のうち 2 つ以上のインスタンスを含むフィルタを作成することもできます。そうする場合、コンポーネントがそれらのフィルタ要素のいかなる組み合わせも処理できることを確認しておく必要があります。

複数の種類のインテントに対応し、かつアクション、データ、カテゴリのタイプの特定の組み合わせのみを処理したい場合は、複数のインテント フィルタを作成する必要があります。

暗黙的インテントは、これらの 3 つの各要素とインテントを比較することで、フィルタに照らしてテストされます。コンポーネントに配信されるには、インテントが 3 つのテストすべてをパスする必要があります。一致しないものが 1 つでもある場合、Android システムはインテントをコンポーネントに配信しません。ただし、1 つのコンポーネントに複数のインテント フィルタがある場合もあるため、コンポーネントのいずれかのフィルタをパスできなかったインテントでも、別のフィルタをパスする場合があります。システムによるインテント解決の詳細は、次のセクションのインテントの解決で説明します。

注意:インテント フィルタを使用して、他のアプリが自分のコンポーネントを開始できないようにするのは安全な方法ではありません。インテント フィルタは特定の種類の暗黙的インテントにのみ応答するようコンポーネントを制限しますが、別のアプリのデベロッパーがあなたのコンポーネント名を見極めて明示的インテントを使用するなら、その別のアプリがあなたのアプリ コンポーネントを開始できる可能性があります。自分のアプリ コンポーネントを開始できるのは自分のアプリのみにしたい場合は、マニフェストにインテント フィルタを宣言しないでください。代わりに、そのコンポーネントの exported 属性を "false" に設定します。

他のアプリの Service を誤って実行しないように、自分のサービスは常に明示的インテントを使用して開始してください。

注:すべてのアクティビティにおいて、マニフェスト ファイルでインテント フィルタを宣言する必要があります。ただし、ブロードキャスト レシーバのフィルタは、registerReceiver() を呼び出すことで動的に登録できます。その後、レシーバの登録を解除するには、unregisterReceiver() を使用します。これにより、アプリが実行中の特定の期間だけ、アプリが特定のブロードキャストをリッスンできるようになります。

フィルタの例

インテント フィルタの動作の一部を説明するために、ここではソーシャル シェアリング アプリのマニフェスト ファイルを例として示します。

<activity android:name="MainActivity">
    <!-- This activity is the main entry, should appear in app launcher -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="ShareActivity">
    <!-- This activity handles "SEND" actions with text data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SEND_MULTIPLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="application/vnd.google.panorama360+jpg"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

1 つ目のアクティビティである MainActivity は、アプリのメイン エントリ ポイントです — これはユーザーがランチャー アイコンから初めてアプリを起動したときに開くアクティビティです。

  • ACTION_MAIN アクションにより、これがメインのエントリ ポイントで、インテント データはないことが示されています。
  • CATEGORY_LAUNCHER カテゴリにより、このアクティビティのアイコンをシステムのアプリ ランチャーに配置するべきことが示されています。<activity> 要素が icon でアイコンを指定していない場合、システムは <application> 要素のアイコンを使用します。

このアクティビティをアプリ ランチャーに表示するには、この 2 つをペア設定する必要があります。

2 つ目のアクティビティである ShareActivity は、テキストやメディア コンテンツの共有を円滑化するものです。ユーザーは MainActivity から移動することでこのアクティビティに入ることもありますが、2 つのインテント フィルタのいずれかに一致する暗黙的インテントを発行する別のアプリから直接 ShareActivity に入ることもできます。

注:application/vnd.google.panorama360+jpg の MIME タイプは、パノラマ写真を指定する特別なデータタイプで、Google パノラマ API で処理できます。

ペンディング インテントを使用する

PendingIntent オブジェクトは Intent オブジェクトのラッパーです。PendingIntent の主な目的は、あなたのアプリのプロセスから実行されたかのように、包含している Intent を使用する許可を別のアプリに付与することです。

ペンディング インテントの主な使用例には、次のようなものがあります。

  • 通知を使って、ユーザーがアクションを実行するときに実行するインテントを宣言する(Android システムの NotificationManagerIntent を実行します)。
  • アプリのウィジェットを使って、ユーザーがアクションを実行するときに実行するインテントを宣言する(ホーム画面のアプリが Intent を実行します)。
  • 将来の指定された時間に実施するインテントを宣言する(Android システムの AlarmManagerIntent を実行します)。

Intent オブジェクトはアプリの特定のタイプのコンポーネント(ActivityServiceBroadcastReceiver のいずれか)で処理されることを前提としているため、PendingIntent も同様の前提で作成する必要があります。ペンディング インテントを使用すると、startActivity() などの呼び出しであなたのアプリがインテントを実行することはありません。代わりに、次のクリエーター メソッドをそれぞれ呼び出して、PendingIntent の作成時に目的のコンポーネント タイプを宣言しなければなりません。

あなたのアプリが他のアプリからペンディング インテントを受け取る場合を除いて、PendingIntent の作成時に必要となる PendingIntent メソッドは、ほぼ上記の 3 つのみです。

各メソッドが、現在のアプリの Context、ラップしたい Intent、インテントの使用方法を指定する 1 つ以上のフラグ(インテントを 2 回以上使用できるかどうかなど)を受け取ります。

ペンディング インテントの使用に関する詳細については、通知アプリ ウィジェット の API ガイドなどのドキュメンテーションで、それぞれの使用例をご覧ください。

インテントの解決

システムがアクティビティを開始する暗黙的インテントを受け取ると、次の 3 つの側面に基づいてインテントをインテント フィルタと比較し、そのインテントに最適なアクティビティを探します。

  • アクション。
  • データ(URI とデータタイプの両方)。
  • カテゴリ。

以降のセクションでは、アプリのマニフェスト ファイルのインテント フィルタの宣言に応じて、インテントがどのように適切なコンポーネントにマッチングされるかを説明します。

アクションのテスト

受け入れるインテントのアクションを指定するには、次の例に示すように、インテント フィルタで 0 個以上の <action> 要素を宣言します。

<intent-filter>
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.VIEW" />
    ...
</intent-filter>

このフィルタをパスするには、Intent で指定されたアクションが、フィルタにリストされたいずれかのアクション一致する必要があります。

フィルタのリストにアクションが 1 つもない場合は、インテントに一致するものがないため、すべてのインテントがテストに失敗します。ただし、Intent がアクションを指定していない場合、フィルタに少なくとも 1 つのアクションが含まれている限り、テストに合格します。

カテゴリのテスト

受け入れるインテントのカテゴリを指定するには、次の例に示すように、インテント フィルタで 0 個以上の <category> 要素を宣言します。

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    ...
</intent-filter>

インテントがカテゴリのテストに合格するには、Intent のすべてのカテゴリが、フィルタ内のカテゴリに一致する必要があります。逆はそうとは限りません — インテント フィルタが Intent で指定されているカテゴリよりも多くのカテゴリを宣言していて、Intent が合格する場合があります。つまり、カテゴリのないインテントは、フィルタで宣言されているカテゴリに関係なく、常にこのテストに合格することになります。

注:Android では、startActivity()startActivityForResult() に渡されるすべての暗黙的インテントに CATEGORY_DEFAULT カテゴリを自動的に適用します。自分のアクティビティが暗黙的インテントを受け取るようにしたい場合は、前出の <intent-filter> の例のように、インテント フィルタに "android.intent.category.DEFAULT" のカテゴリを含める必要があります。

データのテスト

受け入れるインテントのデータを指定するには、次の例に示すように、インテント フィルタで 0 個以上の <data> 要素を宣言します。

<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http" ... />
    <data android:mimeType="audio/mpeg" android:scheme="http" ... />
    ...
</intent-filter>

<data> 要素で、URI 構造とデータタイプ(MIME メディア タイプ)を指定できます。URI は、次のように schemehostportpath という 4 つの属性で構成されます。

<scheme>://<host>:<port>/<path>

次の例で、これらの属性で可能な値を示します。

content://com.example.project:200/folder/subfolder/etc

この URI では、スキームが content、ホストが com.example.project、ポートが 200、パスが folder/subfolder/etc になります。

これらの各属性は <data> 要素では省略可能ですが、一次従属性があります。

  • スキームが指定されていない場合、ホストは無視されます。
  • ホストが指定されていない場合、ポートは無視されます。
  • スキームとホストの両方が指定されていない場合、パスは無視されます。

インテントの URI をフィルタの URI 指定と比較するときは、フィルタに含まれる URI の一部のみと比較されます。たとえば次のようになります。

  • フィルタでスキームのみが指定されている場合、そのスキームを持つすべての URI がフィルタに一致します。
  • フィルタでスキームと認証局が指定されていて、パスが指定されていない場合、パスにかかわらず、同じスキームと認証局を持つすべての URI がフィルタをパスします。
  • フィルタでスキーム、認証局、パスが指定されている場合、同じスキーム、認証局、パスを持つ URI のみがフィルタをパスします。

注:パスの仕様により、ワイルドカードのアスタリスク(*)を含めて、パス名の部分一致のみを要求することもできます。

データのテストでは、インテントの URI と MIME タイプの両方を、フィルタで指定された URI と MIME タイプと比較します。次のようなルールになっています。

  1. URI も MIME タイプも含まないインテントは、フィルタで URI や MIME タイプが指定されていない場合のみテストをパスします。
  2. URI を含んでいて MIME タイプを含んでいないインテント(明示的にも含まれておらず、URI からも推測できない)場合は、URI がフィルタの URI 形式に一致し、フィルタが MIME タイプを指定していない場合のみテストをパスします。
  3. MIME タイプを含んでいて、URI を含んでいないインテントは、フィルタのリストに同じ MIME タイプがあり、URI 形式が指定されていない場合のみテストをパスします。
  4. URI と MIME タイプの両方を含む(明示的または URI からの推測)インテントは、MIME タイプがフィルタにリストされているタイプに一致した場合のみ、テストの MIME タイプのパートをパスします。テストの URI のパートは、URI がフィルタの URI に一致するか、content: URI または file: URI があって、フィルタで URI が指定されていない場合にパスできます。つまり、フィルタが MIME タイプのみをリストしている場合、コンポーネントは content: データと file: データをサポートすると推定されます。

注:インテントで URI または MIME タイプが指定されている場合、<intent-filter><data> 要素がなければデータのテストは失敗します。

この最後のルール(d)は、コンポーネントがファイルやコンテンツ プロバイダからのローカル データを取得できるという想定を反映しています。そのため、フィルタにはデータタイプのみをリストして、content: スキームや file: スキームを明示的に指名する必要はありません。次の例は、<data> 要素が Android に、コンポーネントがコンテンツ プロバイダからの画像データを取得し、それを表示できることを伝えている、典型的なケースを示しています。

<intent-filter>
    <data android:mimeType="image/*" />
    ...
</intent-filter>

利用可能なデータはほとんどコンテンツ プロバイダによって用意されるため、データタイプが指定されていて URI が指定されていないフィルタが最もよく使用されます。

別のよくある構成は、スキームとデータタイプがあるフィルタです。たとえば、次の <data> 要素は Android に、コンポーネントがネットワークから動画データを取得でき、アクションを実行できることを伝えています。

<intent-filter>
    <data android:scheme="http" android:mimeType="video/*" />
    ...
</intent-filter>

インテントのマッチング

インテントとインテント フィルタのマッチングには、アクティベートするターゲット コンポーネントを見つけるだけでなく、端末上の一部のコンポーネントに関する情報を見つけるという目的もあります。たとえばホームアプリは、ACTION_MAIN アクションと CATEGORY_LAUNCHER カテゴリを指定しているインテント フィルタを持つすべてのアクティビティを見つけることで、アプリ ランチャーにデータを入力します。IntentFilter クラスのドキュメントで説明されているように、インテントのアクションとカテゴリが、フィルタのそれと一致した場合のみマッチングが成立します。

あなたのアプリも、ホームアプリが行うのと同じような方法で、インテントのマッチングを使用できます。PackageManager には特定のインテントを受け入れることのできるすべてのコンポーネントを返す一連の query...() メソッドと、同様にインテントに応答するのに最適なコンポーネントを判断する一連の resolve...() メソッドがあります。たとえば、queryIntentActivities() は引数として渡されたインテントを実行できるすべてのアクティビティの一覧を返し、queryIntentServices() は同様のサービスの一覧を返します。いずれのメソッドでもコンポーネントのアクティベートは行われず、応答できるものをリストするだけです。ブロードキャスト レシーバにも、同様のメソッド queryBroadcastReceivers() があります。