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

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

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

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

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

  • サービスの起動

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

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

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

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

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

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

インテントのタイプ

インテントには次の 2 種類があります。

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

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

図 1. 暗黙的インテントの仕組み 別のアクティビティを開始することもできます。[1] アクティビティ 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 コンストラクタ。

操作
実行する一般的なアクション(viewpick など)を指定する文字列。

ブロードキャスト インテントの場合、これは実行されてレポートされるアクションです。 アクションによって、インテントの残りの部分の構造、特に データおよびエクストラに含まれる情報です。

アプリ内のインテントで使用する(または他のインテントで使用するために)独自のアクションを指定できます。 (アプリ内のコンポーネントを呼び出せます)が、通常はアクション定数を 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";
データ
データを参照する 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() です。これらは互いの値を無効化するためです。 URI と MIME タイプの両方を設定する場合は、必ず setDataAndType() を使用してください。

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

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

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

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

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

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

たとえば、メールアドレスを使用してメールを送信するインテントを ACTION_SEND では、宛先を EXTRA_EMAIL キーを押し、subjectEXTRA_SUBJECT キー

Intent クラスは多数の EXTRA_* 定数を指定します。 標準化されたデータ型に対応しています独自の追加キーを宣言する必要がある場合は、 必ずアプリのパッケージ名を含めてください を使用します。

Kotlin

const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"

Java

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

注意: Parcelable または 期待するインテントを送信する際の Serializable データ 受信します。アプリが 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() を呼び出すと、ユーザーはどのアプリでコンテンツを共有するかを選択できます。

Kotlin

// 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.
}

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");

// 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. チューザ ダイアログ

アプリチューザを強制的に適用する

暗黙的インテントに応答するアプリが 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);
}

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

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

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

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

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

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

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

Kotlin

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

Java

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.ネストされた保留中を使用する場合のアプリ間通信の図 使用します。

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

アプリが受け取る暗黙的インテントをアドバタイズするには、対象のインテント フィルタを 1 つ以上宣言します。 <intent-filter> を使用して各アプリ コンポーネントを 要素を追加します。 各インテント フィルタは、そのインテントのアクションに基づいて受け入れるインテントのタイプを指定します。 分析できます暗黙的インテントがアプリ コンポーネントに配信されるのは、 インテント フィルタのいずれかを通過できます。

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

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

各インテント フィルタは <intent-filter> で定義されます。 要素を、対応するアプリ コンポーネント( (<activity> として) 要素です)。

<intent-filter> 要素を含む各アプリ コンポーネントで、 値を明示的に設定し、 android:exported。 この属性は、他のアプリがアプリ コンポーネントにアクセスできるかどうかを示します。インテント フィルタに LAUNCHER カテゴリが含まれているアクティビティなど、この属性を true に設定すると便利な場合があります。それ以外の場合は、この属性を false に設定することをおすすめします。

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

<intent-filter> 内で、 受け入れるインテントのタイプを、1 つ以上の 3 つの要素があります

<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 つのテストすべてを通過する必要があります。一致しないものが 1 つでも場合、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 を使用できる権限を付与することです。

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

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

Intent オブジェクトが特定の API によって処理されるよう設計されているのと同様に、 アプリ コンポーネントのタイプ(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 オブジェクトが不変の場合、 その場合、他のアプリはインテントを変更して、 使用します。

Kotlin

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

Java

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

ただし、特定のユースケースでは、代わりに可変の PendingIntent オブジェクトが必要になります。

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

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

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

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

  1. ベース インテントのアクション、パッケージ、コンポーネントの各フィールドを確認する 設定されます。
  2. FLAG_IMMUTABLE を使用する。 Android 6.0(API レベル 23)で追加され、ペンディング インテントを作成します。このフラグ 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 で指定されたアクションを使用します。 フィルタにリストされているアクションのいずれかに一致する必要があります。

フィルタにアクションが一覧表示されていない場合は、 すべてのインテントがテストに失敗します。ただし、Intent が アクションを指定していない場合、フィルタが設定されている限り、テストに合格 アクションが 1 つ以上含まれています。

カテゴリテスト

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

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

インテントがカテゴリテストに合格するには、Intent 内のすべてのカテゴリ フィルタのカテゴリと一致する必要があります。その逆は必要なく、インテント フィルタによって IntentIntent はまだ合格しています。そのため、カテゴリのないインテントは、フィルタで宣言されているカテゴリに関係なく、常にこのテストに合格することになります。

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

データテスト

受け入れるインテント データを指定するには、インテント フィルタで 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 の各部分は、各 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 タイプがフィルタのリストにあるタイプに一致した場合のみ、テストの MIME タイプのパートをパスします。テストの URI 部分に合格する その URI がフィルタ内の URI と一致するか、content: が含まれているかのいずれかです。 または file: URI を指定し、フィルタで URI が指定されていない場合。つまり 次の場合、コンポーネントは content: データと file: データをサポートすると推定されます。 そのフィルタには MIME タイプのみが一覧表示されます。

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

この最後のルール、ルール (d) は、 コンポーネントがファイルまたはコンテンツ プロバイダからローカルデータを取得できることを確認します。 そのため、フィルタではデータ型を列挙でき、明示的に指定しなくてもよい content: スキームと file: スキームに名前を付けます。 次の例は、一般的なケースで <data> 要素が コンポーネントがコンテンツから画像データを取得できることを Android に伝えます 表示します。

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

次に一致するフィルタ データ型は指定しているが URI を指定していない場合が、おそらく最も一般的な方法です。 コンテンツ プロバイダによって提供されます。

もう 1 つの一般的な構成は、スキームとデータ型を持つフィルタです。対象 (<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() があります。