Android アプリの最も重要な特長の 1 つとして、実行する「アクション」に基づいて、別のアプリにユーザーを送信する機能があります。たとえば、アプリが保存しているお店やサービスの住所データを地図上に表示しようとする場合に、そのアプリ内に地図を表示するアクティビティをビルドする必要はありません。代わりに、Intent
使用して、住所を表示するリクエストを作成することができます。これに基づいて、Android システムが、地図上に住所を表示できるアプリを起動します。
最初のクラスの初めてのアプリを作成するで説明したように、自分のアプリ内のアクティビティ間を移動する際に、インテントを使用する必要があります。この場合は通常、起動するコンポーネントの正確なクラス名を定義する「明示的インテント」を使用します。しかし、「地図を表示する」など、別のアプリにアクションを実行させる場合は、「暗黙的インテント」を使用する必要があります。
このレッスンでは、特定のアクションを対象とする暗黙的インテントを作成する方法や、暗黙的インテントを使用して、別のアプリ内でアクションを実行するアクティビティを起動する方法について説明します。また、暗黙的インテント用のランタイム チェックを組み込む理由については、下記の動画をご覧ください。
暗黙的インテントをビルドする
暗黙的インテントは、開始するコンポーネントのクラス名を宣言せず、代わりに実行するアクションを宣言します。アクションは、表示、編集、送信、取得など、実行する処理を指定します。また、インテントには、表示を目的とする住所や、送信を目的とするメールなど、アクションに関連付けられたデータが格納されることもよくあります。作成するインテントに応じて、Uri
など、各種のデータタイプが格納されます。インテントによっては、データをまったく必要としない場合もあります。
データが Uri
である場合は、シンプルな Intent()
コンストラクタを使用して、アクションとデータを定義できます。
たとえば、電話番号を指定する Uri
データを使用して、通話を開始するインテントを作成する方法を以下に示します。
Kotlin
val callIntent: Intent = Uri.parse("tel:5551234").let { number -> Intent(Intent.ACTION_DIAL, number) }
Java
Uri number = Uri.parse("tel:5551234"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
自分のアプリが startActivity()
を呼び出すことでインテントを呼び出すと、別の電話アプリが、指定された電話番号への通話を開始します。
ほかに 2 つのインテント(およびそのアクションと Uri
データのペア)の例を以下に示します。
- 地図を表示する:
Kotlin
// Map point based on address val mapIntent: Intent = Uri.parse( "geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California" ).let { location -> // Or map point based on latitude/longitude // Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level Intent(Intent.ACTION_VIEW, location) }
Java
// Map point based on address Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); // Or map point based on latitude/longitude // Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
- ウェブページを表示する:
Kotlin
val webIntent: Intent = Uri.parse("http://www.android.com").let { webpage -> Intent(Intent.ACTION_VIEW, webpage) }
Java
Uri webpage = Uri.parse("http://www.android.com"); Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
他の種類の暗黙的インテントは、文字列など、さまざまなデータタイプを提供する「エクストラ」データを必要とします。さまざまな putExtra()
メソッドを使用することで、エクストラ データを 1 つまたは複数追加することができます。
デフォルトでは、インテント内に格納されている Uri
データに基づいて、インテントに必要とされる適切な MIME タイプが自動的に決定されます。インテント内に Uri
を格納していない場合、通常は setType()
を使用して、インテントに関連付けられるデータタイプを指定することをおすすめします。MIME タイプを詳細に設定することで、インテントが受け取るアクティビティの種類を指定できます。
ここでは、目的のアクションを指定するための特別データを追加しているインテントの例を示します。
- 添付ファイル付きのメールを送信する:
Kotlin
Intent(Intent.ACTION_SEND).apply { // The intent does not have a URI, so declare the "text/plain" MIME type type = HTTP.PLAIN_TEXT_TYPE putExtra(Intent.EXTRA_EMAIL, arrayOf("jon@example.com")) // recipients putExtra(Intent.EXTRA_SUBJECT, "Email subject") putExtra(Intent.EXTRA_TEXT, "Email message text") putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment")) // You can also attach multiple items by passing an ArrayList of Uris }
Java
Intent emailIntent = new Intent(Intent.ACTION_SEND); // The intent does not have a URI, so declare the "text/plain" MIME type emailIntent.setType(HTTP.PLAIN_TEXT_TYPE); emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject"); emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text"); emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment")); // You can also attach multiple items by passing an ArrayList of Uris
- カレンダー イベントを作成する:
Kotlin
Intent(Intent.ACTION_INSERT, Events.CONTENT_URI).apply { val beginTime: Calendar = Calendar.getInstance().apply { set(2012, 0, 19, 7, 30) } val endTime = Calendar.getInstance().apply { set(2012, 0, 19, 10, 30) } putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.timeInMillis) putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.timeInMillis) putExtra(Events.TITLE, "Ninja class") putExtra(Events.EVENT_LOCATION, "Secret dojo") }
Java
Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI); Calendar beginTime = Calendar.getInstance(); beginTime.set(2012, 0, 19, 7, 30); Calendar endTime = Calendar.getInstance(); endTime.set(2012, 0, 19, 10, 30); calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis()); calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis()); calendarIntent.putExtra(Events.TITLE, "Ninja class"); calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
注: カレンダー イベント用のこのインテントは、API レベル 14 以降に限りサポートされます。
注: できる限り具体的に Intent
を定義するようにしてください。たとえば、ACTION_VIEW
インテントを使用して画像を表示する場合、image/*
の MIME タイプを指定することをおすすめします。これにより、他のタイプのデータを「表示」できるアプリ(地図アプリなど)がインテントによってトリガーされることを防ぐことができます。
インテントを受け取るアプリがあるか確認する
Android プラットフォームは、特定のインテント(電話、メール、カレンダー アプリなど)が内蔵のアプリのいずれかへ解決することを保証しますが、インテントを呼び出す前に常に検証の手順を含める必要があります。
注: インテントを呼び出したときに、インテントを処理できるアプリがデバイス上になかった場合、呼び出し元アプリはクラッシュします。
インテントに応答できるアクティビティが利用可能かどうかを検証するには、queryIntentActivities()
を呼び出して、Intent
を処理できるアクティビティのリストを取得します。返された List
が空でなかった場合は、安全にインテントを使用することができます。たとえば、次のようになります。
Kotlin
val activities: List<ResolveInfo> = packageManager
.queryIntentActivities(
intent,
PackageManager.MATCH_DEFAULT_ONLY
)
val isIntentSafe: Boolean = activities.isNotEmpty()
Java
PackageManager packageManager = getPackageManager()
;
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;
isIntentSafe
が true
の場合は、少なくとも 1 つのアプリがインテントに応答します。false
の場合は、インテントを処理するアプリが存在しません。
注: アクティビティが最初に起動するときに、このチェックを実行するようにしてください。インテントを処理できるアプリがなかった場合、ユーザーが使用する前に、インテントを使用する機能を無効化する必要があります。インテントを処理できるアプリが具体的にわかっている場合は、当該アプリをダウンロードするリンクを提示することもできます(Google Play 上の自分のプロダクトにリンクする方法を参照)。
インテントを使用してアクティビティを起動する

図 1: インテントを処理できるアプリが複数あるときに表示される選択ダイアログの例
Intent
を作成し、エクストラ情報を設定したら、startActivity()
を呼び出してシステムに送信します。インテントを処理できるアクティビティが複数あると判明した場合、図 1 に示すように、使用するアプリを選択できるダイアログ(別名「確認ダイアログ」)が表示されます。インテントを処理できるアクティビティが 1 つのみの場合、システムはすぐにそのアクティビティを起動します。
Kotlin
startActivity(intent)
Java
startActivity(intent);
次に、マップを表示するためのインテントを作成し、そのインテントを処理するアプリが存在するかを確認してから起動する、一連の方法について例を示します。
Kotlin
// Build the intent
val location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California")
val mapIntent = Intent(Intent.ACTION_VIEW, location)
// Verify it resolves
val activities: List<ResolveInfo> = packageManager
.queryIntentActivities(mapIntent, 0)
val isIntentSafe: Boolean = activities.isNotEmpty()
// Start an activity if it's safe
if (isIntentSafe) {
startActivity(mapIntent)
}
Java
// Build the intent
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
// Verify it resolves
PackageManager packageManager = getPackageManager()
;
List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
boolean isIntentSafe = activities.size() > 0;
// Start an activity if it's safe
if (isIntentSafe) {
startActivity(mapIntent);
}
アプリチューザを表示する

図 2: チューザ ダイアログ
Intent
を startActivity()
に渡してアクティビティを起動したときに、インテントに応答できるアプリが複数あった場合、ユーザーは、デフォルトで使用するアプリを選択できます(ダイアログの下部にあるチェックボックスをオンにします。図 1 を参照)。この機能は、対象のアクションを実行するときにユーザーが毎回同じアプリを使用することを希望している場合に便利です。たとえば、多くのユーザーは、ウェブページを開くときは 1 つのウェブブラウザだけを使用し、また、写真を撮影するときは 1 つのカメラアプリだけを使用します。
一方、実行対象のアクションが複数のアプリによって処理できる場合、ユーザーは毎回異なるアプリを選ぶかもしれません。たとえば「共有」アクションにおいては、アイテムの共有に使用するアプリが複数ある可能性があります。この場合、図 2 に示すように、チューザのダイアログを明示的に表示する必要があります。チューザ ダイアログの場合、ユーザーは、アクションごとに、使用するアプリを毎回選択する必要があります(アクション用のデフォルト アプリを選択することはできません)。
チューザを表示するには、createChooser()
を使用して Intent
を作成し、startActivity()
に渡します。たとえば、次のようになります。
Kotlin
val intent = Intent(Intent.ACTION_SEND) ... // Always use string resources for UI text. // This says something like "Share this photo with" val title = resources.getString(R.string.chooser_title) // Create intent to show chooser val chooser = Intent.createChooser(intent, title) // Verify the intent will resolve to at least one activity if (intent.resolveActivity(packageManager) != null) { startActivity(chooser) }
Java
Intent intent = 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 chooser Intent chooser = Intent.createChooser(intent, title); // Verify the intent will resolve to at least one activity if (intent.resolveActivity(getPackageManager()) != null) { startActivity(chooser); }
これにより、createChooser()
メソッドに渡されたインテントに応答できるアプリのリストがダイアログに表示され、指定したテキストがダイアログのタイトルとして使用されます。