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

Intent は、別のアプリ コンポーネントからのアクションをリクエストするために使用できるメッセージング オブジェクトです。インテントがコンポーネント間の通信を促進する方法はいくつかありますが、以下の 3 つがあります。 基本的なユースケース:

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

    Activity はアプリ内の 1 つの画面を表します。新しい P-MAX キャンペーンを Activity のインスタンスを作成し、Intent 宛先: startActivity()Intent 起動するアクティビティを記述し、必要なデータを格納します。

    アクティビティの完了時に結果を受け取る場合は、startActivityForResult() を呼び出します。アクティビティが結果を受け取る アクティビティの onActivityResult() コールバック内で、独立した Intent オブジェクトとして渡します。 詳しくは、アクティビティ ガイドをご覧ください。

  • サービスの起動

    Service はバックグラウンドでオペレーションを実行するコンポーネントである ユーザーインターフェースはありませんAndroid 5.0(API レベル 21)以降では、 JobScheduler で。JobScheduler の詳細については、API-reference documentation をご覧ください。

    Android 5.0(API レベル 21)より前のバージョンでは、Service クラスのメソッドを使用してサービスを開始できます。Cloud Shell から 1 回限りのオペレーションを (ファイルのダウンロードなど)を、Intent 宛先: startService()Intent 起動するサービスを記述し、必要なデータを格納します。

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

  • ブロードキャストの配信

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

このページの残りの部分では、インテントの仕組みと使用方法について説明します。 関連情報については、以下をご覧ください。 他のアプリとの連携 およびコンテンツの共有をご覧ください。

インテントのタイプ

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

  • 明示的インテントでは、完全な ComponentName を指定することで、インテントを満たすアプリのコンポーネントを指定します。通常は開始するアクティビティやサービスのクラス名がわかっているため、明示的インテントを使用してアプリ内のコンポーネントを開始します。たとえば、ユーザー操作に応答してアプリ内で新しいアクティビティを開始したり、バックグラウンドでファイルをダウンロードするサービスを開始したりできます。
  • 暗黙的インテントでは、特定のコンポーネントを指定せず、代わりに実行する全般的な動作を宣言することで、他のアプリからコンポーネントを処理できるようにします。たとえば ユーザーに地図上の場所を示すために、暗黙的インテントを使用して、別の機能 地図上に指定された場所を表示します。

図 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 コンストラクタを使って指定できます。

独自のアクションを定義する場合は、必ずアプリのパッケージ名を含めます。 を使用します。

KotlinJava
const val ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL"
static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
データ
データを参照する URI(Uri オブジェクト) 対処が必要な そのデータの MIME タイプ。提供されるデータタイプは、インテントのアクションによって決まります。対象 たとえば、アクションが ACTION_EDIT の場合、データには 編集するドキュメントの URI。

インテントを作成する際は、 多くの場合、URI に加えてデータの型(MIME タイプ)も指定することが重要です。 たとえば、画像を表示できるアクティビティは、 URI 形式が類似していても、音声ファイルを再生できる場合があります。 データの MIME タイプを指定すると、Android システムがインテントを受け取るのに最適なコンポーネントを見つけやすくなります。ただし、MIME タイプは URI から推測できる場合があります。特にデータが content: URI。content: URI は、データがデバイス上にあることを示します。 Kubernetes によって制御され、 ContentProvider: データの MIME タイプをシステムに公開します。

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

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

カテゴリ
インテントを処理するコンポーネントの種類に関する追加情報が含まれた文字列です。カテゴリの説明はいくつでも追加できます が、ほとんどのインテントにカテゴリは必要ありません。 一般的なカテゴリは次のとおりです。 <ph type="x-smartling-placeholder">
</ph>
CATEGORY_BROWSABLE
ターゲット アクティビティ自体をウェブブラウザで起動してデータを表示できるようにする 画像やメール メッセージなどのリンクで参照されます。
CATEGORY_LAUNCHER
このアクティビティはタスクの初期のアクティビティで、システムのアプリケーション ランチャーの一覧に表示されます。

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

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

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

おまけ
達成に必要な追加情報を運ぶ Key-Value ペア リクエストアクションを返します。 一部のアクションでは特定の種類のデータ URI を使用しますが、一部のアクションでは特定のエクストラ値を使用します。

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

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

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

KotlinJava
const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"
static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";

注意: 別のアプリが受信することを想定したインテントを送信する場合は、Parcelable データまたは Serializable データを使用しないでください。アプリが Bundle オブジェクトのデータにアクセスしようとしたが、パーセル化されたクラスまたはシリアル化されたクラスにアクセスできない場合、システムは RuntimeException を発生させます。

フラグ
フラグは、インテントのメタデータとして機能する Intent クラスで定義されます。フラグを使用すると、Android システムにアクティビティの起動方法( タスク アクティビティは リリース後の扱い方(たとえば、最近使用したアイテムのリストに できます。

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

明示的インテントの例

明示的インテントとは、特定のアプリ コンポーネントを起動するために使用するものです。たとえば、 アプリ内の特定のアクティビティまたはサービス明示的インテントを作成するには、 Intent オブジェクトのコンポーネント名(すべて) その他のインテント プロパティは省略可能です。

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

KotlinJava
// 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)
// 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() に設定すると、ユーザーは次のことができます。 コンテンツを共有するアプリを選択します。

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

// Try to invoke the intent.
try {
    startActivity(sendIntent)
} catch (e: ActivityNotFoundException) {
    // Define what your app should do if no activity can handle the intent.
}
// 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");

// Try to invoke the intent.
try {
    startActivity(sendIntent);
} catch (ActivityNotFoundException e) {
    // Define what your app should do if no activity can handle the intent.
}

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

他のアプリの起動に関する詳細もガイドで紹介 ユーザーを 他のアプリ

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

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

暗黙的インテントに応答するアプリが複数ある場合は、 ユーザーは使用するアプリを選択でき、そのアプリを Google Chat でのデフォルトの できます。デフォルトを選択する機能は、ユーザーが実行するアクションを実行する際に便利です。 ウェブページを開くとき(ユーザーが 1 つのウェブブラウザのみを使用することがほとんどです)。

ただし、インテントに応答するアプリが複数あって、ユーザーが毎回別のアプリを使用する可能性がある場合は、チューザのダイアログを明示的に表示する必要があります。選択ツールのダイアログで ユーザーがアクションに使用するアプリを選択できる(ユーザーはアプリのデフォルト アプリを できます。たとえば、アプリが「共有」を実行したときにACTION_SEND アクションを使用すると、ユーザーは、 そのため、図 2 に示すように、常に選択ツール ダイアログを使用する必要があります。

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

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

安全でないインテントの起動を検出する

アプリは、アプリ内のコンポーネント間を移動するため、または別のアプリに代わってアクションを実行するため、インテントを起動することがあります。Android 12(API レベル 31)以降では、プラットフォームのセキュリティを強化するため、アプリがインテントの安全でない起動を実行したときに警告するデバッグ機能が導入されました。たとえば、お客様のアプリは ネストされたインテント(渡されたインテント)の安全でない起動を実行する 別のインテントにエクストラとして渡されます。

アプリが次のアクションの両方を実行すると、システムによってインテントの安全でない起動が検出され、StrictMode 違反が発生します。

  1. 配信されたインテントのエクストラから、ネストされたインテントを取り出した。
  2. そのネストされたインテントを使用して(たとえば startActivity()startService()、または bindService() にインテントを渡して)、アプリ コンポーネントを直ちに開始した。

この状況を識別してアプリに変更を加える方法について詳しくは、Medium の Android のネスト インテント に関するブログ記事をご覧ください。

安全でないインテントの起動を確認する

アプリでの安全でないインテントの起動を確認するには、VmPolicy を構成する際に detectUnsafeIntentLaunch() を呼び出します。次のコード スニペットをご覧ください。アプリで StrictMode 違反が検出された場合は、機密に該当する可能性がある情報を保護するために、アプリの実行を停止することをおすすめします。

KotlinJava
fun onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build())
}
protected void onCreate() {
    StrictMode.setVmPolicy(new VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build());
}

より厳格なインテントの使い方

安全でないインテントの起動や StrictMode 違反の発生を最小限に抑えるには、次のベスト プラクティスに従ってください。

インテント内の必須のエクストラのみをコピーして、必要なサニタイズと検証を行います。アプリは、あるインテントから、新しいコンポーネントの起動に使用される別のインテントに、エクストラをコピーすることがあります。これは、アプリが putExtras(Intent) または putExtras(Bundle) を呼び出したときに発生します。アプリがこれらのオペレーションのいずれかを実行する場合、受信コンポーネントで想定されるエクストラのみをコピーします。コピーを受信するインテントがエクスポートされていないコンポーネントを起動する場合は、エクストラをサニタイズして検証してから、コンポーネントを起動するインテントにコピーします。

アプリのコンポーネントを不必要にエクスポートしないでください。たとえば、内部ネストされたインテントを使用してアプリ コンポーネントを起動する場合は、そのコンポーネントの android:exported 属性を false に設定します。

ネストされたインテントではなく PendingIntent を使用してください。こうすることで、別のアプリがそのアプリの PendingIntent をパーセル解除したときに、 Intent を含む場合、もう一方のアプリはPendingIntent 自動的に識別されます。この設定により、他のアプリは安全に起動できます。 エクスポートされていないコンポーネントを含む、アプリ内の任意のコンポーネント。

図 2 の図は、システムが(クライアント)から制御を渡す方法を示しています。 アプリから別の(サービス)アプリへ、そしてアプリに戻るには:

  1. アプリは、別のアプリのアクティビティを呼び出すインテントを作成します。そのインテント内に、PendingIntent オブジェクトをエクストラとして追加します。このペンディング インテントは、アプリ内のコンポーネントを呼び出します。このコンポーネントはエクスポートされていません。
  2. アプリのインテントを受け取ると、他のアプリはネストされた PendingIntent オブジェクトを抽出します。
  3. 他のアプリが PendingIntent オブジェクトで send() メソッドを呼び出します。
  4. 制御をアプリに戻した後、システムはアプリのコンテキストを使用して保留中のインテントを呼び出します。

図 2.ネストされたペンディング インテントを使用する場合のアプリ間通信の図。

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

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

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

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

各インテント フィルタは、アプリのマニフェスト ファイルの <intent-filter> 要素で定義され、これは対応するアプリのコンポーネント(<activity> 要素など)にネストされます。

<intent-filter> 要素を含む各アプリ コンポーネントで、 値を明示的に設定し、 android:exported。 この属性は、アプリ コンポーネントが他のアプリからアクセスできるかどうかを示します。一部の (たとえば、インテント フィルタに特定の文字列を含む) LAUNCHER この属性は true に設定すると便利です。それ以外の場合は、この属性を false に設定することをおすすめします。

警告: アクティビティ、サービス、ブロードキャストが アプリのレシーバがインテント フィルタを使用しており、値を明示的に設定していない場合 android:exported のため、アプリは次のデバイスにはインストールできません Android 12 以降を搭載している。

<intent-filter> 内で、次の 3 つの要素のなかで 1 つ以上を使用して、受け入れるインテントのタイプを指定できます。

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

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

次に、データ タイプがテキストの場合に、ACTION_SEND インテントを受け取るインテント フィルタを使用したアクティビティ宣言の例を示します。

<activity android:name="ShareActivity" android:exported="false">
    <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> の複数のインスタンスが含まれるフィルタを作成できます。その場合、コンポーネントがあらゆるデータを処理できることを確認する必要があります。 組み合わせることもできます。

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

暗黙的インテントは、それぞれのインテントと比較することで、フィルタに対してテストされます。 3 つの要素で構成されます。コンポーネントに配信されるには、インテントが 3 つのテストすべてに合格する必要があります。 どれも一致しない場合、Android システムはインテントを 説明します。ただし、コンポーネントは複数のインテント フィルタを保持していることもあるため、1 つのインテント フィルタを通過できなかったインテントでも、別のフィルタを通過できる場合があります。システムがインテントを解決する方法について詳しくは、インテントの解決のセクションをご覧ください。

注意: インテント フィルタを使用して他のアプリでコンポーネントを開始できないようにする方法は安全ではありません。インテント フィルタは、リクエストに対する応答のみを 使用している場合、別のアプリからあなたのアプリ コンポーネントが起動される可能性がある コンポーネント名がデベロッパーが決めている場合は、明示的インテントを使用します。 独自のアプリのみがコンポーネントを起動できるようにすることが重要である場合は、マニフェストでインテント フィルタを宣言しないでください。代わりに、 exported 属性 を "false" に設定します。

同様に、別のアプリのコードを誤って実行しないように、 Service の場合は、常に明示的インテントを使用して、独自のサービスを開始します。

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

フィルタの例

インテント フィルタの動作を説明するために、次の例をご覧ください。 次のように、ソーシャル共有アプリのマニフェスト ファイルから抽出できます。

<activity android:name="MainActivity" android:exported="true">
    <!-- 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" android:exported="false">
    <!-- 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 からこのアクティビティに移動してこのアクティビティに入る可能性がありますが、 また、暗黙的なトークンを発行する別のアプリから直接 ShareActivity を入力することもできます。 2 つのインテントフィルタのいずれかに一致する

注: MIME タイプ application/vnd.google.panorama360+jpg は、リソースの種類を指定する パノラマ写真も、Google パノラマ API を使用します。

インテントと他のアプリのインテント フィルタを一致させる

Android 13(API レベル 33)以降をターゲットとする別のアプリは、 インテントが一致する場合にのみ、そのインテントに その他のアプリの <intent-filter> 要素。システムで 次がスローされます。 ActivityNotFoundException。 送信側のアプリは 使用します。

同様に、Android 13 をターゲットとするようにアプリを更新した場合 以上の場合、外部アプリから発信されるすべてのインテントが そのインテントがアクションと合致する場合にのみ、エクスポートされた アプリが宣言する <intent-filter> 要素のカテゴリ。この動作は、送信元アプリのターゲット SDK バージョンに関係なく発生します。

次のケースでは、インテント マッチングは適用されません。

  • インテント フィルタを宣言していないコンポーネントに配信されるインテント。
  • 同じアプリからのインテント。
  • システムからのインテント、つまり「システム UID」(uid=1000)から送信されるインテント。システムアプリとしては、system_server と、android:sharedUserIdandroid.uid.system に設定するアプリがあります。
  • ルートからのインテント。

詳しくは、インテントのマッチングをご覧ください。

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

PendingIntent オブジェクトは、Intent オブジェクトのラッパーです。PendingIntent の主な目的 国外のアプリに権限を付与することです。 含まれている Intent を、 プロセスです。

ペンディング インテントの主なユースケースは次のとおりです。

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

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

アプリが他のアプリからペンディング インテントを受け取っている場合を除き、 PendingIntent を作成する上記のメソッドがおそらく 必要になる PendingIntent メソッド。

各メソッドは現在のアプリの Context、 ラップする Intent、および指定する 1 つ以上のフラグ インテントの使用方法(インテントを複数回使用できるかどうかなど)を指定します。

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

可変性を指定する

Android 12 以降をターゲットとするアプリの場合、 アプリが作成する各 PendingIntent オブジェクトの可変性。これを宣言するには、 特定の PendingIntent オブジェクトが可変または不変である場合は、 PendingIntent.FLAG_MUTABLE または PendingIntent.FLAG_IMMUTABLE 設定されます。

アプリがどちらの可変性フラグも設定せずに PendingIntent オブジェクトを作成しようとすると、IllegalArgumentException がスローされ、logcat に次のメッセージが表示されます。

PACKAGE_NAME: Targeting S+ (version 31 and above) requires that one of \
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \
some functionality depends on the PendingIntent being mutable, e.g. if \
it needs to be used with inline replies or bubbles.

可能な限り不変のペンディング インテントを作成する

ほとんどの場合において、アプリでは不変の PendingIntent オブジェクトを作成するようにしてください(次のコード スニペットを参照)。PendingIntent オブジェクトが不変の場合、他のアプリはそのインテントを変更して、インテント呼び出しの結果を調整することはできません。

KotlinJava
val pendingIntent = PendingIntent.getActivity(applicationContext,
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE)
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE);

ただし、次のユースケースでは可変の PendingIntent オブジェクトが必要です。

  • 通知のダイレクト返信アクションのサポート。ダイレクト返信では、返信に関連付けられた PendingIntent オブジェクト内のクリップデータの変更が必要です。通常、この変更をリクエストするには、 フラグとしての FILL_IN_CLIP_DATA fillIn() メソッドを呼び出します。
  • 以下のインスタンスを使用して、通知を Android Auto フレームワークに関連付ける CarAppExtender
  • インスタンスを使用して会話をバブルに配置する /PendingIntent。可変の PendingIntent オブジェクトを使用すると、システムは FLAG_ACTIVITY_MULTIPLE_TASKFLAG_ACTIVITY_NEW_DOCUMENT などの正しいフラグを適用できます。
  • requestLocationUpdates() などの API を呼び出して、デバイスの位置情報をリクエストする。可変の PendingIntent オブジェクトを使用すると、 位置情報のライフサイクル イベントを表すインテント エクストラ。これらのイベントには プロバイダが利用可能になります
  • AlarmManager を使用したアラームのスケジュール 可変の PendingIntent オブジェクトを使用すると、 EXTRA_ALARM_COUNT インテント エクストラ。この追加情報は、繰り返しアラートがトリガーされた回数を表します。この追加情報を含めることで、デバイスがスリープ状態のときなど、アラームが複数回トリガーされたかどうかをアプリに正確に通知できます。

アプリで可変の PendingIntent オブジェクトを作成する場合は、明示的インテントを使用して ComponentName の値をフィルインすることを強くおすすめします。そうすれば、別のアプリが PendingIntent を呼び出してアプリに制御を戻すたびに、常にアプリ内の同じコンポーネントが開始されます。

ペンディング インテント内で明示的インテントを使用する

他のアプリがアプリのペンディング インテントをどのように使用できるかを明確に定義するには、常にペンディング インテントを明示的インテントでラップします。このベスト プラクティスに従うには、次の操作を行います。

  1. ベース インテントのアクション、パッケージ、コンポーネントの各フィールドが設定されていることを確認します。
  2. Android 6.0(API レベル 23)で追加された FLAG_IMMUTABLE を使用して、保留中のインテントを作成します。このフラグにより、PendingIntent を受信したアプリが未入力プロパティを入力するのを防ぐことができます。アプリの minSdkVersion22 以下の場合は、次のコードを使用して安全性と互換性を同時に提供できます。

    if (Build.VERSION.SDK_INT >= 23) {
      // Create a PendingIntent using FLAG_IMMUTABLE.
    } else {
      // Existing code that creates a PendingIntent.
    }

インテントの解決

システムは、アクティビティを開始するための暗黙的インテントを受け取ると、 次の 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 つのアクションが含まれていればテストに合格します。

カテゴリのテスト

受け入れるインテントのカテゴリを指定するには、インテント フィルタでゼロ個以上の <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" のカテゴリを含める必要があります。

データテスト

受け入れるインテント データを指定するには、インテント フィルタでゼロ個以上の <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 の各部分は、各 URL が 属性: schemehostport、 および path:

<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 タイプの部分が渡される場合にのみ、 タイプがフィルタにリストされているタイプに一致する場合。テストの URI 部分に合格する その URI がフィルタ内の URI と一致するか、content: が含まれているかのいずれかです。 または 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>

インテント マッチング

インテントは、ターゲットを検出するだけでなく、インテント フィルタと照合されます。 一連のコンポーネントについて 構成されます。たとえば、Google Home アプリからアプリ ランチャーが自動的に入力されます。 アクティビティを指定するインテント フィルタを使用して、 ACTION_MAIN アクションと CATEGORY_LAUNCHER カテゴリ。 一致は、インテントのアクションとカテゴリが一致する場合にのみ成功します。 フィルタに対して適用できます。詳しくは、IntentFilter のドキュメントをご覧ください。 クラスです。

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