意图让您可以通过在 Intent
对象中描述您要执行的操作(例如“查看地图”或“拍照”)来在另一个应用中启动 activity。这种意图称为隐式意图,因为它不指定要启动的应用组件,而是指定*操作*并提供执行操作的*数据*。
当您调用 startActivity()
或 startActivityForResult()
并传入隐式意图时,系统会将该意图解析为一个可以处理该意图的应用,并启动其相应的 Activity
。如果有多个应用可以处理该意图,系统会向用户显示一个对话框,供其选择要使用的应用。
本页面介绍了您可用于执行常见操作的多个隐式意图,这些意图按处理该意图的应用类型进行组织。每个部分还会说明如何创建意图过滤器以宣传您的应用执行此操作的能力。
注意:如果设备上没有应用可以接收隐式意图,则应用在调用 startActivity()
时会崩溃。为验证是否存在可接收意图的应用,请先在您的 Intent
对象上调用 resolveActivity()
。如果结果非 null,则至少有一个应用可以处理该意图,并且可以安全地调用 startActivity()
。如果结果为 null,请勿使用该意图,如果可能,请停用调用该意图的功能。
如果您不熟悉如何创建意图或意图过滤器,请先阅读意图和意图过滤器。
要了解如何从开发主机触发本页面列出的意图,请参阅使用 Android 调试桥验证意图部分。
Google 语音操作
Google 语音操作会根据语音指令触发本页面列出的某些意图。如需了解详情,请参阅系统语音操作入门。
闹钟
以下是闹钟应用的常见操作,以及您创建意图过滤器以宣传您的应用执行每项操作所需的信息。
创建闹钟
要创建新闹钟,请使用 ACTION_SET_ALARM
操作,并使用以下额外数据指定闹钟详细信息(例如时间、消息)。
注意:仅小时、分钟和消息额外数据在 Android 2.3(API 级别 9)及更低版本中可用。其他额外数据在更高平台版本中可用。
- 操作
ACTION_SET_ALARM
- 数据 URI
- 无
- MIME 类型
- 无
- 额外数据
-
EXTRA_HOUR
- 闹钟的小时数。
EXTRA_MINUTES
- 闹钟的分钟数。
EXTRA_MESSAGE
- 用于识别闹钟的自定义消息。
EXTRA_DAYS
- 一个
ArrayList
,包含此闹钟重复的每周的每一天。每天都必须使用Calendar
类中的整数来声明,例如MONDAY
。对于一次性闹钟,请勿指定此额外数据。
EXTRA_RINGTONE
- 一个
content:
URI,指定闹钟要使用的铃声,或者VALUE_RINGTONE_SILENT
表示不使用铃声。要使用默认铃声,请勿指定此额外数据。
EXTRA_VIBRATE
- 一个布尔值,指定此闹钟是否振动。
EXTRA_SKIP_UI
- 一个布尔值,指定响应应用在设置闹钟时是否必须跳过其 UI。如果为 true,应用必须绕过所有确认 UI 并设置指定的闹钟。
意图示例
Kotlin
fun createAlarm(message: String, hour: Int, minutes: Int) { val intent = Intent(AlarmClock.ACTION_SET_ALARM).apply { putExtra(AlarmClock.EXTRA_MESSAGE, message) putExtra(AlarmClock.EXTRA_HOUR, hour) putExtra(AlarmClock.EXTRA_MINUTES, minutes) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void createAlarm(String message, int hour, int minutes) { Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM) .putExtra(AlarmClock.EXTRA_MESSAGE, message) .putExtra(AlarmClock.EXTRA_HOUR, hour) .putExtra(AlarmClock.EXTRA_MINUTES, minutes); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
要调用 ACTION_SET_ALARM
意图,您的应用必须拥有 SET_ALARM
权限
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.intent.action.SET_ALARM" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
创建计时器
要创建倒计时器,请使用 ACTION_SET_TIMER
操作,并使用以下额外数据指定计时器详细信息(例如持续时间)。
注意:此意图在 Android 4.4(API 级别 19)及更高版本中可用。
- 操作
ACTION_SET_TIMER
- 数据 URI
- 无
- MIME 类型
- 无
- 额外数据
-
EXTRA_LENGTH
- 计时器的时长(秒)。
EXTRA_MESSAGE
- 用于识别计时器的自定义消息。
EXTRA_SKIP_UI
- 一个布尔值,指定响应应用在设置计时器时是否必须跳过其 UI。如果为 true,应用必须绕过所有确认 UI 并启动指定的计时器。
意图示例
Kotlin
fun startTimer(message: String, seconds: Int) { val intent = Intent(AlarmClock.ACTION_SET_TIMER).apply { putExtra(AlarmClock.EXTRA_MESSAGE, message) putExtra(AlarmClock.EXTRA_LENGTH, seconds) putExtra(AlarmClock.EXTRA_SKIP_UI, true) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void startTimer(String message, int seconds) { Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER) .putExtra(AlarmClock.EXTRA_MESSAGE, message) .putExtra(AlarmClock.EXTRA_LENGTH, seconds) .putExtra(AlarmClock.EXTRA_SKIP_UI, true); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
要调用 ACTION_SET_TIMER
意图,您的应用必须拥有 SET_ALARM
权限
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.intent.action.SET_TIMER" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
显示所有闹钟
要显示闹钟列表,请使用 ACTION_SHOW_ALARMS
操作。
尽管此意图并未被太多应用调用(因为它主要由系统应用使用),但任何充当闹钟的应用都可以实现此意图过滤器,并通过显示当前闹钟列表进行响应。
注意:此意图在 Android 4.4(API 级别 19)及更高版本中可用。
- 操作
ACTION_SHOW_ALARMS
- 数据 URI
- 无
- MIME 类型
- 无
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.intent.action.SHOW_ALARMS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
日历
添加事件是日历应用的常见操作。使用以下部分中的信息创建意图过滤器,以宣传您的应用执行此操作的能力。
添加日历事件
要向用户的日历添加新事件,请使用 ACTION_INSERT
操作,并使用 Events.CONTENT_URI
指定数据 URI。然后,您可以使用以下额外数据指定各种事件详细信息。
- 操作
ACTION_INSERT
- 数据 URI
Events.CONTENT_URI
- MIME 类型
"vnd.android.cursor.dir/event"
- 额外数据
-
EXTRA_EVENT_ALL_DAY
- 一个布尔值,指定这是否为全天事件。
EXTRA_EVENT_BEGIN_TIME
- 事件的开始时间(自 epoch 以来的毫秒数)。
EXTRA_EVENT_END_TIME
- 事件的结束时间(自 epoch 以来的毫秒数)。
TITLE
- 事件标题。
DESCRIPTION
- 事件描述。
EVENT_LOCATION
- 事件地点。
EXTRA_EMAIL
- 用逗号分隔的电子邮件地址列表,用于指定受邀者。
还可以使用
CalendarContract.EventsColumns
类中定义的常量来指定更多事件详细信息。
意图示例
Kotlin
fun addEvent(title: String, location: String, begin: Long, end: Long) { val intent = Intent(Intent.ACTION_INSERT).apply { data = Events.CONTENT_URI putExtra(Events.TITLE, title) putExtra(Events.EVENT_LOCATION, location) putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin) putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void addEvent(String title, String location, long begin, long end) { Intent intent = new Intent(Intent.ACTION_INSERT) .setData(Events.CONTENT_URI) .putExtra(Events.TITLE, title) .putExtra(Events.EVENT_LOCATION, location) .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin) .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.intent.action.INSERT" /> <data android:mimeType="vnd.android.cursor.dir/event" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
相机
以下是相机应用的常见操作,以及您创建意图过滤器以宣传您的应用执行每项操作所需的信息。
拍摄照片或视频并返回
要打开相机应用并接收生成的照片或视频,请使用 ACTION_IMAGE_CAPTURE
或 ACTION_VIDEO_CAPTURE
操作。此外,请在 EXTRA_OUTPUT
额外数据中指定您希望相机保存照片或视频的 URI 位置。
- 操作
ACTION_IMAGE_CAPTURE
或
ACTION_VIDEO_CAPTURE
- 数据 URI 方案
- 无
- MIME 类型
- 无
- 额外数据
-
EXTRA_OUTPUT
- 相机应用保存照片或视频文件(作为
Uri
对象)的 URI 位置。
当相机应用成功返回焦点到您的 activity(换句话说,您的应用收到 onActivityResult()
回调)时,您可以访问您使用 EXTRA_OUTPUT
值指定的 URI 处的照片或视频。
注意:当您使用 ACTION_IMAGE_CAPTURE
拍摄照片时,相机还可能在结果 Intent
中返回照片的缩小副本或缩略图,该缩略图以 Bitmap
形式保存在名为 "data"
的额外字段中。
意图示例
Kotlin
const val REQUEST_IMAGE_CAPTURE = 1 val locationForPhotos: Uri = ... fun capturePhoto(targetFilename: String) { val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply { putExtra(MediaStore.EXTRA_OUTPUT, Uri.withAppendedPath(locationForPhotos, targetFilename)) } if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_IMAGE_CAPTURE) } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) { val thumbnail: Bitmap = data.getParcelableExtra("data") // Do other work with full size photo saved in locationForPhotos. ... } }
Java
static final int REQUEST_IMAGE_CAPTURE = 1; static final Uri locationForPhotos; public void capturePhoto(String targetFilename) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.withAppendedPath(locationForPhotos, targetFilename)); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { Bitmap thumbnail = data.getParcelableExtra("data"); // Do other work with full size photo saved in locationForPhotos. ... } }
在 Android 12(API 级别 31)或更高版本上执行此操作时,请参阅以下意图示例。
意图示例
Kotlin
val REQUEST_IMAGE_CAPTURE = 1 private fun dispatchTakePictureIntent() { val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) try { startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE) } catch (e: ActivityNotFoundException) { // Display error state to the user. } }
Java
static final int REQUEST_IMAGE_CAPTURE = 1; private void dispatchTakePictureIntent() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); try { startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } catch (ActivityNotFoundException e) { // Display error state to the user. } } </section></div>
如需详细了解如何使用此意图拍摄照片,包括如何为输出位置创建合适的 Uri
,请阅读拍摄照片或录制视频。
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.media.action.IMAGE_CAPTURE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
处理此意图时,让您的 activity 检查传入 Intent
中的 EXTRA_OUTPUT
额外数据,然后将捕获的图像或视频保存到该额外数据指定的位置,并调用 setResult()
,其中包含一个在名为 "data"
的额外数据中包含压缩缩略图的 Intent
。
在静态图像模式下启动相机应用
要在静态图像模式下打开相机应用,请使用 INTENT_ACTION_STILL_IMAGE_CAMERA
操作。
- 操作
INTENT_ACTION_STILL_IMAGE_CAMERA
- 数据 URI 方案
- 无
- MIME 类型
- 无
- 额外数据
- 无
意图示例
Kotlin
private fun dispatchTakePictureIntent() { val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) try { startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE) } catch (e: ActivityNotFoundException) { // Display error state to the user. } }
Java
public void capturePhoto(String targetFilename) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.withAppendedPath(locationForPhotos, targetFilename)); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.media.action.STILL_IMAGE_CAMERA" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
在视频模式下启动相机应用
要在视频模式下打开相机应用,请使用 INTENT_ACTION_VIDEO_CAMERA
操作。
- 操作
INTENT_ACTION_VIDEO_CAMERA
- 数据 URI 方案
- 无
- MIME 类型
- 无
- 额外数据
- 无
意图示例
Kotlin
fun capturePhoto() { val intent = Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA) if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_IMAGE_CAPTURE) } }
Java
public void capturePhoto() { Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.media.action.VIDEO_CAMERA" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
联系人/人物应用
以下是联系人管理应用的常见操作,以及您创建意图过滤器以宣传您的应用执行每项操作所需的信息。
选择联系人
要让用户选择联系人并授予您的应用访问所有联系人信息的权限,请使用 ACTION_PICK
操作,并将 MIME 类型指定为 Contacts.CONTENT_TYPE
。
传递给您的 onActivityResult()
回调的结果 Intent
包含指向所选联系人的 content:
URI。即使您的应用不包含 READ_CONTACTS
权限,该响应也会授予您的应用临时权限,以使用联系人提供程序 API 读取该联系人。
提示:如果您只需要访问特定的联系人信息,例如电话号码或电子邮件地址,请参阅下一节,了解如何选择特定的联系人数据。
- 操作
ACTION_PICK
- 数据 URI 方案
- 无
- MIME 类型
Contacts.CONTENT_TYPE
意图示例
Kotlin
const val REQUEST_SELECT_CONTACT = 1 fun selectContact() { val intent = Intent(Intent.ACTION_PICK).apply { type = ContactsContract.Contacts.CONTENT_TYPE } if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_SELECT_CONTACT) } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) { val contactUri: Uri = data.data // Do something with the selected contact at contactUri. //... } }
Java
static final int REQUEST_SELECT_CONTACT = 1; public void selectContact() { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType(ContactsContract.Contacts.CONTENT_TYPE); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_SELECT_CONTACT); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) { Uri contactUri = data.getData(); // Do something with the selected contact at contactUri. ... } }
如需了解在获取联系人 URI 后如何检索联系人详细信息,请阅读检索联系人详细信息。
当您使用此意图检索联系人 URI 时,通常不需要 READ_CONTACTS
权限即可读取该联系人的基本详细信息,例如显示名称和联系人是否已加星标。但是,如果您尝试读取给定联系人的更具体数据(例如其电话号码或电子邮件地址),则需要 READ_CONTACTS
权限。
选择特定的联系人数据
要让用户从联系人中选择特定信息(例如电话号码、电子邮件地址或其他数据类型),请使用 ACTION_PICK
操作,并将 MIME 类型指定为以下内容类型之一,例如 CommonDataKinds.Phone.CONTENT_TYPE
以获取联系人的电话号码。
注意:在许多情况下,您的应用需要拥有 READ_CONTACTS
权限才能查看特定联系人的具体信息。
如果您只需要从联系人中检索一种类型的数据,则使用 CONTENT_TYPE
从 ContactsContract.CommonDataKinds
类获取的此技术比使用 Contacts.CONTENT_TYPE
更高效,如上一节所示。结果会直接为您提供所需数据的访问权限,而无需您对联系人提供程序执行更复杂的查询。
传递给您的 onActivityResult()
回调的结果 Intent
包含指向所选联系人数据的 content:
URI。即使您的应用不包含 READ_CONTACTS
权限,该响应也会授予您的应用临时权限以读取该联系人数据。
- 操作
ACTION_PICK
- 数据 URI 方案
- 无
- MIME 类型
-
CommonDataKinds.Phone.CONTENT_TYPE
- 从包含电话号码的联系人中选择。
CommonDataKinds.Email.CONTENT_TYPE
- 从包含电子邮件地址的联系人中选择。
CommonDataKinds.StructuredPostal.CONTENT_TYPE
- 从包含邮政地址的联系人中选择。
或
ContactsContract
下的许多其他CONTENT_TYPE
值之一。
意图示例
Kotlin
const val REQUEST_SELECT_PHONE_NUMBER = 1 fun selectContact() { // Start an activity for the user to pick a phone number from contacts. val intent = Intent(Intent.ACTION_PICK).apply { type = CommonDataKinds.Phone.CONTENT_TYPE } if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER) } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == Activity.RESULT_OK) { // Get the URI and query the content provider for the phone number. val contactUri: Uri = data.data val projection: Array<String> = arrayOf(CommonDataKinds.Phone.NUMBER) contentResolver.query(contactUri, projection, null, null, null).use { cursor -> // If the cursor returned is valid, get the phone number. if (cursor.moveToFirst()) { val numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER) val number = cursor.getString(numberIndex) // Do something with the phone number. ... } } } }
Java
static final int REQUEST_SELECT_PHONE_NUMBER = 1; public void selectContact() { // Start an activity for the user to pick a phone number from contacts. Intent intent = new Intent(Intent.ACTION_PICK); intent.setType(CommonDataKinds.Phone.CONTENT_TYPE); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) { // Get the URI and query the content provider for the phone number. Uri contactUri = data.getData(); String[] projection = new String[]{CommonDataKinds.Phone.NUMBER}; Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null); // If the cursor returned is valid, get the phone number. if (cursor != null && cursor.moveToFirst()) { int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER); String number = cursor.getString(numberIndex); // Do something with the phone number. //... } } }
查看联系人
要显示已知联系人的详细信息,请使用 ACTION_VIEW
操作,并将联系人指定为具有 content:
URI 的意图数据。
获取联系人 URI 的两种主要方式
- 使用上一节中所示的
ACTION_PICK
操作返回的联系人 URI。此方法不需要任何应用权限。 - 直接访问所有联系人列表,如检索联系人列表中所述。此方法需要
READ_CONTACTS
权限。
- 操作
ACTION_VIEW
- 数据 URI 方案
content:<URI>
- MIME 类型
- 无。类型从联系人 URI 推断。
意图示例
Kotlin
fun viewContact(contactUri: Uri) { val intent = Intent(Intent.ACTION_VIEW, contactUri) if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void viewContact(Uri contactUri) { Intent intent = new Intent(Intent.ACTION_VIEW, contactUri); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
编辑现有联系人
要编辑已知联系人,请使用 ACTION_EDIT
操作,将联系人指定为具有 content:
URI 的意图数据,并将任何已知联系人信息作为由 ContactsContract.Intents.Insert
中的常量指定的额外数据。
获取联系人 URI 的两种主要方式
- 使用上一节中所示的
ACTION_PICK
操作返回的联系人 URI。此方法不需要任何应用权限。 - 直接访问所有联系人列表,如检索联系人列表中所述。此方法需要
READ_CONTACTS
权限。
- 操作
ACTION_EDIT
- 数据 URI 方案
content:<URI>
- MIME 类型
- 类型从联系人 URI 推断。
- 额外数据
ContactsContract.Intents.Insert
中定义的一个或多个额外数据,以便您可以填充联系人详细信息的字段。
意图示例
Kotlin
fun editContact(contactUri: Uri, email: String) { val intent = Intent(Intent.ACTION_EDIT).apply { data = contactUri putExtra(ContactsContract.Intents.Insert.EMAIL, email) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void editContact(Uri contactUri, String email) { Intent intent = new Intent(Intent.ACTION_EDIT); intent.setData(contactUri); intent.putExtra(Intents.Insert.EMAIL, email); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
如需详细了解如何编辑联系人,请阅读使用意图修改联系人。
插入联系人
要插入新联系人,请使用 ACTION_INSERT
操作,将 Contacts.CONTENT_TYPE
指定为 MIME 类型,并将任何已知联系人信息作为由 ContactsContract.Intents.Insert
中的常量指定的额外数据。
- 操作
ACTION_INSERT
- 数据 URI 方案
- 无
- MIME 类型
Contacts.CONTENT_TYPE
- 额外数据
ContactsContract.Intents.Insert
中定义的一个或多个额外数据。
意图示例
Kotlin
fun insertContact(name: String, email: String) { val intent = Intent(Intent.ACTION_INSERT).apply { type = ContactsContract.Contacts.CONTENT_TYPE putExtra(ContactsContract.Intents.Insert.NAME, name) putExtra(ContactsContract.Intents.Insert.EMAIL, email) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void insertContact(String name, String email) { Intent intent = new Intent(Intent.ACTION_INSERT); intent.setType(Contacts.CONTENT_TYPE); intent.putExtra(Intents.Insert.NAME, name); intent.putExtra(Intents.Insert.EMAIL, email); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
如需详细了解如何插入联系人,请阅读使用意图修改联系人。
电子邮件
撰写带有可选附件的电子邮件是电子邮件应用的常见操作。使用以下部分中的信息创建意图过滤器,以宣传您的应用执行此操作的能力。
撰写带有可选附件的电子邮件
要撰写电子邮件,请根据您是否要包含附件,使用以下操作之一,并使用列出的额外数据键包含电子邮件详细信息(例如收件人和主题)。
- 操作
ACTION_SENDTO
(无附件)或
ACTION_SEND
(一个附件)或
ACTION_SEND_MULTIPLE- 数据 URI 方案
- 无
- MIME 类型
-
"text/plain"
"*/*"
- 额外数据
-
Intent.EXTRA_EMAIL
- 所有“收件人”电子邮件地址的字符串数组。
Intent.EXTRA_CC
- 所有“抄送”收件人电子邮件地址的字符串数组。
Intent.EXTRA_BCC
- 所有“密送”收件人电子邮件地址的字符串数组。
Intent.EXTRA_SUBJECT
- 带有电子邮件主题的字符串。
Intent.EXTRA_TEXT
- 带有电子邮件正文的字符串。
Intent.EXTRA_STREAM
- 指向附件的
Uri
。如果使用ACTION_SEND_MULTIPLE
操作,则此项是包含多个Uri
对象的ArrayList
。
意图示例
Kotlin
fun composeEmail(addresses: Array<String>, subject: String, attachment: Uri) { val intent = Intent(Intent.ACTION_SEND).apply { type = "*/*" putExtra(Intent.EXTRA_EMAIL, addresses) putExtra(Intent.EXTRA_SUBJECT, subject) putExtra(Intent.EXTRA_STREAM, attachment) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void composeEmail(String[] addresses, String subject, Uri attachment) { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("*/*"); intent.putExtra(Intent.EXTRA_EMAIL, addresses); intent.putExtra(Intent.EXTRA_SUBJECT, subject); intent.putExtra(Intent.EXTRA_STREAM, attachment); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
如果您想确保您的意图仅由电子邮件应用处理,而不是由短信或社交应用处理,请使用 ACTION_SENDTO
操作并包含 "mailto:"
数据方案,如以下示例所示
Kotlin
fun composeEmail(addresses: Array<String>, subject: String) { val intent = Intent(Intent.ACTION_SENDTO).apply { data = Uri.parse("mailto:") // Only email apps handle this. putExtra(Intent.EXTRA_EMAIL, addresses) putExtra(Intent.EXTRA_SUBJECT, subject) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void composeEmail(String[] addresses, String subject) { Intent intent = new Intent(Intent.ACTION_SENDTO); intent.setData(Uri.parse("mailto:")); // Only email apps handle this. intent.putExtra(Intent.EXTRA_EMAIL, addresses); intent.putExtra(Intent.EXTRA_SUBJECT, subject); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.intent.action.SEND" /> <data android:type="*/*" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SENDTO" /> <data android:scheme="mailto" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
文件存储
以下是文件存储应用的常见操作,以及您创建意图过滤器以宣传您的应用执行每项操作所需的信息。
检索特定类型的文件
要请求用户选择文件(例如文档或照片)并向您的应用返回引用,请使用 ACTION_GET_CONTENT
操作并指定您想要的 MIME 类型。返回给您的应用的文件引用对于您的 activity 当前生命周期而言是临时的,因此如果您以后想访问它,则必须导入一个副本以便以后读取。
此意图还允许用户在此过程中创建新文件。例如,用户可以拍摄新照片而不是选择现有照片。
传递到您的 onActivityResult()
方法的结果 Intent 包含指向文件的 URI 数据。该 URI 可以是任何类型,例如 http:
URI、file:
URI 或 content:
URI。但是,如果您希望将可选文件限制为只能从内容提供程序(content:
URI)访问的文件,并且可以通过 openFileDescriptor()
作为文件流使用,请将 CATEGORY_OPENABLE
类别添加到您的 Intent 中。
在 Android 4.3(API 级别 18)及更高版本上,您还可以通过将 EXTRA_ALLOW_MULTIPLE
添加到 Intent 并将其设置为 true
来让用户选择多个文件。然后,您可以在 getClipData()
返回的 ClipData
对象中访问每个选定的文件。
- 操作
ACTION_GET_CONTENT
- 数据 URI 方案
- 无
- MIME 类型
- 与用户需要选择的文件类型对应的 MIME 类型。
- 额外数据
-
EXTRA_ALLOW_MULTIPLE
- 一个布尔值,声明用户是否可以一次选择多个文件。
EXTRA_LOCAL_ONLY
- 一个布尔值,声明返回的文件是否必须直接从设备获取,而不是需要从远程服务下载。
- 类别 (可选)
-
CATEGORY_OPENABLE
- 仅返回可以使用
openFileDescriptor()
表示为文件流的“可打开”文件。
获取照片的 Intent 示例
Kotlin
const val REQUEST_IMAGE_GET = 1 fun selectImage() { val intent = Intent(Intent.ACTION_GET_CONTENT).apply { type = "image/*" } if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_IMAGE_GET) } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { if (requestCode == REQUEST_IMAGE_GET && resultCode == Activity.RESULT_OK) { val thumbnail: Bitmap = data.getParcelableExtra("data") val fullPhotoUri: Uri = data.data // Do work with photo saved at fullPhotoUri. ... } }
Java
static final int REQUEST_IMAGE_GET = 1; public void selectImage() { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_IMAGE_GET); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) { Bitmap thumbnail = data.getParcelable("data"); Uri fullPhotoUri = data.getData(); // Do work with photo saved at fullPhotoUri. ... } }
返回照片的 Intent 过滤器示例
<activity ...> <intent-filter> <action android:name="android.intent.action.GET_CONTENT" /> <data android:type="image/*" /> <category android:name="android.intent.category.DEFAULT" /> <!-- The OPENABLE category declares that the returned file is accessible from a content provider that supportsOpenableColumns
andContentResolver.openFileDescriptor()
. --> <category android:name="android.intent.category.OPENABLE" /> </intent-filter> </activity>
打开特定类型的文件
无需使用 ACTION_GET_CONTENT
操作来检索必须导入到应用的文件副本,而是在 Android 4.4 或更高版本上运行时,您可以使用 ACTION_OPEN_DOCUMENT
操作并指定 MIME 类型,请求打开由其他应用管理的文件。要同时允许用户创建应用可以写入的新文档,请改用 ACTION_CREATE_DOCUMENT
操作。
例如,ACTION_CREATE_DOCUMENT
Intent 允许用户选择创建新文档的位置(例如在管理文档存储的其他应用中),而不是从现有 PDF 文档中进行选择。您的应用随后会收到可以写入新文档的 URI 位置。
尽管从 ACTION_GET_CONTENT
操作传递到您的 onActivityResult()
方法的 Intent 可能会返回任何类型的 URI,但 ACTION_OPEN_DOCUMENT
和 ACTION_CREATE_DOCUMENT
的结果 Intent 始终将所选文件指定为由 DocumentsProvider
支持的 content:
URI。您可以使用 openFileDescriptor()
打开文件,并使用 DocumentsContract.Document
中的列查询其详细信息。
返回的 URI 授予您的应用对文件的长期读取权限,也可能包含写入权限。当您想要读取现有文件而无需在应用中创建副本,或者想要就地打开和编辑文件时,ACTION_OPEN_DOCUMENT
操作特别有用。
您还可以通过向 Intent 添加 EXTRA_ALLOW_MULTIPLE
并将其设置为 true
来让用户选择多个文件。如果用户只选择一个项目,则可以从 getData()
中检索该项目。如果用户选择多个项目,则 getData()
返回 null,您必须转而从 getClipData()
返回的 ClipData
对象中检索每个项目。
注意:您的 Intent 必须指定 MIME 类型,并且必须声明 CATEGORY_OPENABLE
类别。如果适用,您可以通过添加包含 EXTRA_MIME_TYPES
Extra 的 MIME 类型数组来指定多个 MIME 类型——如果这样做,您必须将 setType()
中的主要 MIME 类型设置为 "*/*"
。
- 操作
ACTION_OPEN_DOCUMENT
或
ACTION_CREATE_DOCUMENT
- 数据 URI 方案
- 无
- MIME 类型
- 与用户需要选择的文件类型对应的 MIME 类型。
- 额外数据
-
EXTRA_MIME_TYPES
- 与您的应用请求的文件类型对应的 MIME 类型数组。当您使用此 Extra 时,您必须将
setType()
中的主要 MIME 类型设置为"*/*"
。 EXTRA_ALLOW_MULTIPLE
- 一个布尔值,声明用户是否可以一次选择多个文件。
EXTRA_TITLE
- 与
ACTION_CREATE_DOCUMENT
配合使用,用于指定初始文件名。 EXTRA_LOCAL_ONLY
- 一个布尔值,声明返回的文件是否必须直接从设备获取,而不是需要从远程服务下载。
- 类别
-
CATEGORY_OPENABLE
- 仅返回可以使用
openFileDescriptor()
表示为文件流的“可打开”文件。
获取照片的 Intent 示例
Kotlin
const val REQUEST_IMAGE_OPEN = 1 fun selectImage2() { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { type = "image/*" addCategory(Intent.CATEGORY_OPENABLE) } // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test. startActivityForResult(intent, REQUEST_IMAGE_OPEN) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { if (requestCode == REQUEST_IMAGE_OPEN && resultCode == Activity.RESULT_OK) { val fullPhotoUri: Uri = data.data // Do work with full size photo saved at fullPhotoUri. ... } }
Java
static final int REQUEST_IMAGE_OPEN = 1; public void selectImage() { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.setType("image/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test. startActivityForResult(intent, REQUEST_IMAGE_OPEN); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) { Uri fullPhotoUri = data.getData(); // Do work with full size photo saved at fullPhotoUri. ... } }
第三方应用无法响应带有 ACTION_OPEN_DOCUMENT
操作的 Intent。相反,系统会接收此 Intent 并在统一的用户界面中显示来自各种应用的所有可用文件。
要在此 UI 中提供您的应用文件并允许其他应用打开它们,您必须实现一个 DocumentsProvider
并包含一个 PROVIDER_INTERFACE
("android.content.action.DOCUMENTS_PROVIDER"
) 的 Intent 过滤器,如以下示例所示。
<provider ... android:grantUriPermissions="true" android:exported="true" android:permission="android.permission.MANAGE_DOCUMENTS"> <intent-filter> <action android:name="android.content.action.DOCUMENTS_PROVIDER" /> </intent-filter> </provider>
有关如何使您的应用管理的文件可以从其他应用打开的更多信息,请阅读使用存储访问框架打开文件。
本地操作
叫车是一种常见的本地操作。使用以下部分中的信息创建 Intent 过滤器,以宣传您的应用执行此操作的能力。
叫车
要叫出租车,请使用 ACTION_RESERVE_TAXI_RESERVATION
操作。
注意:应用在完成此操作之前必须征求用户的确认。
- 操作
ACTION_RESERVE_TAXI_RESERVATION
- 数据 URI
- 无
- MIME 类型
- 无
- 额外数据
- 无
意图示例
Kotlin
fun callCar() { val intent = Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION) if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void callCar() { Intent intent = new Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="com.google.android.gms.actions.RESERVE_TAXI_RESERVATION" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
地图
在地图上显示位置是地图应用常见的操作。使用以下部分中的信息创建 Intent 过滤器,以宣传您的应用执行此操作的能力。
在地图上显示位置
要打开地图,请使用 ACTION_VIEW
操作并在 Intent 数据中指定位置信息,使用以下方案之一。
- 操作
ACTION_VIEW
- 数据 URI 方案
-
geo:纬度,经度
- 在给定经纬度显示地图。
示例:
"geo:47.6,-122.3"
geo:纬度,经度?z=缩放级别
- 在给定经纬度以特定缩放级别显示地图。缩放级别 1 显示以给定纬度、经度为中心的全地球。最高(最近)缩放级别为 23。
示例:
"geo:47.6,-122.3?z=11"
geo:0,0?q=纬度,经度(标签)
- 在给定经纬度显示带有字符串标签的地图。
示例:
"geo:0,0?q=34.99,-106.61(Treasure)"
geo:0,0?q=我的街道地址
- 显示“我的街道地址”的位置,这可以是特定地址或位置查询。
示例:
"geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA"
注意:
geo
URI 中传递的所有字符串都必须经过编码。例如,字符串1st & Pike, Seattle
变为1st%20%26%20Pike%2C%20Seattle
。字符串中的空格使用%20
进行编码,或替换为加号(+
)。
- MIME 类型
- 无
意图示例
Kotlin
fun showMap(geoLocation: Uri) { val intent = Intent(Intent.ACTION_VIEW).apply { data = geoLocation } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void showMap(Uri geoLocation) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(geoLocation); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.intent.action.VIEW" /> <data android:scheme="geo" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
音乐或视频
以下是音乐和视频应用的常见操作,包括创建 Intent 过滤器以宣传您的应用执行每个操作的能力所需的信息。
播放媒体文件
要播放音乐文件,请使用 ACTION_VIEW
操作并在 Intent 数据中指定文件的 URI 位置。
- 操作
ACTION_VIEW
- 数据 URI 方案
-
file:<URI>
content:<URI>
http:<URL>
- MIME 类型
-
"audio/*"
"application/ogg"
"application/x-ogg"
"application/itunes"
- 或您的应用所需的任何其他类型。
意图示例
Kotlin
fun playMedia(file: Uri) { val intent = Intent(Intent.ACTION_VIEW).apply { data = file } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void playMedia(Uri file) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(file); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.intent.action.VIEW" /> <data android:type="audio/*" /> <data android:type="application/ogg" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
根据搜索查询播放音乐
要根据搜索查询播放音乐,请使用 INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
Intent。应用可能会响应用户的语音命令来播放音乐,从而触发此 Intent。接收此 Intent 的应用会在其库存中执行搜索,以将现有内容与给定查询匹配,并开始播放该内容。
在此 Intent 中,包含 EXTRA_MEDIA_FOCUS
字符串 extra,它指定了预期的搜索模式。例如,搜索模式可以指定搜索是针对艺术家姓名还是歌曲名称。
- 操作
INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
- 数据 URI 方案
- 无
- MIME 类型
- 无
- 额外数据
-
MediaStore.EXTRA_MEDIA_FOCUS
(必填)-
指示搜索模式:用户是在寻找特定艺术家、专辑、歌曲还是播放列表。大多数搜索模式都接受额外的 Extras。例如,如果用户有兴趣听某首特定歌曲,Intent 可能有三个额外的 Extras:歌曲标题、艺术家和专辑。此 Intent 支持
EXTRA_MEDIA_FOCUS
的每个值对应的以下搜索模式任意 -
"vnd.android.cursor.item/*"
-
播放任意音乐。接收应用会根据智能选择播放一些音乐,例如用户上次听的播放列表。
附加 Extras
QUERY
(必填):一个空字符串。此 Extra 始终提供,以实现向后兼容性。不知道搜索模式的现有应用可以将此 Intent 作为非结构化搜索进行处理。
非结构化 -
"vnd.android.cursor.item/*"
-
从非结构化搜索查询中播放特定歌曲、专辑或流派。当应用无法识别用户想听的内容类型时,可以使用此搜索模式生成 Intent。如果可能,请使用更具体的搜索模式。
附加 Extras
QUERY
(必填):一个字符串,包含艺术家、专辑、歌曲名称或流派的任意组合。
-
播放特定流派的音乐。
附加 Extras
"android.intent.extra.genre"
(必填) - 流派。QUERY
(必填):流派。此 Extra 始终提供,以实现向后兼容性。不知道搜索模式的现有应用可以将此 Intent 作为非结构化搜索进行处理。
-
播放特定艺术家的音乐。
附加 Extras
EXTRA_MEDIA_ARTIST
(必填):艺术家。"android.intent.extra.genre"
:流派。QUERY
(必填):一个字符串,包含艺术家或流派的任意组合。此 Extra 始终提供,以实现向后兼容性。不知道搜索模式的现有应用可以将此 Intent 作为非结构化搜索进行处理。
-
播放特定专辑的音乐。
附加 Extras
EXTRA_MEDIA_ALBUM
(必填):专辑。EXTRA_MEDIA_ARTIST
:艺术家。"android.intent.extra.genre"
:流派。QUERY
(必填):一个字符串,包含专辑或艺术家的任意组合。此 Extra 始终提供,以实现向后兼容性。不知道搜索模式的现有应用可以将此 Intent 作为非结构化搜索进行处理。
歌曲 -
"vnd.android.cursor.item/audio"
-
播放特定歌曲。
附加 Extras
EXTRA_MEDIA_ALBUM
:专辑。EXTRA_MEDIA_ARTIST
:艺术家。"android.intent.extra.genre"
:流派。EXTRA_MEDIA_TITLE
(必填):歌曲名称。QUERY
(必填):一个字符串,包含专辑、艺术家、流派或标题的任意组合。此 Extra 始终提供,以实现向后兼容性。不知道搜索模式的现有应用可以将此 Intent 作为非结构化搜索进行处理。
-
播放特定播放列表或与附加 Extras 指定的某些条件匹配的播放列表。
附加 Extras
EXTRA_MEDIA_ALBUM
:专辑。EXTRA_MEDIA_ARTIST
:艺术家。"android.intent.extra.genre"
:流派。"android.intent.extra.playlist"
:播放列表。EXTRA_MEDIA_TITLE
:播放列表所基于的歌曲名称。QUERY
(必填):一个字符串,包含专辑、艺术家、流派、播放列表或标题的任意组合。此 Extra 始终提供,以实现向后兼容性。不知道搜索模式的现有应用可以将此 Intent 作为非结构化搜索进行处理。
意图示例
如果用户想听某个特定艺术家的音乐,搜索应用可能会生成以下 Intent
Kotlin
fun playSearchArtist(artist: String) { val intent = Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH).apply { putExtra(MediaStore.EXTRA_MEDIA_FOCUS, MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist) putExtra(SearchManager.QUERY, artist) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void playSearchArtist(String artist) { Intent intent = new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH); intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS, MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE); intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist); intent.putExtra(SearchManager.QUERY, artist); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
在您的 activity 中处理此 Intent 时,请检查传入 Intent
中 EXTRA_MEDIA_FOCUS
Extra 的值,以确定搜索模式。一旦您的 activity 识别出搜索模式,请读取该特定搜索模式的附加 Extras 值。有了这些信息,您的应用就可以在其库存中执行搜索,以播放与搜索查询匹配的内容。这在以下示例中有所体现。
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... if (intent.action.compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) { val mediaFocus: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS) val query: String? = intent.getStringExtra(SearchManager.QUERY) // Some of these extras might not be available depending on the search mode. val album: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM) val artist: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST) val genre: String? = intent.getStringExtra("android.intent.extra.genre") val playlist: String? = intent.getStringExtra("android.intent.extra.playlist") val title: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE) // Determine the search mode and use the corresponding extras. when { mediaFocus == null -> { // 'Unstructured' search mode (backward compatible) playUnstructuredSearch(query) } mediaFocus.compareTo("vnd.android.cursor.item/*") == 0 -> { if (query?.isNotEmpty() == true) { // 'Unstructured' search mode. playUnstructuredSearch(query) } else { // 'Any' search mode. playResumeLastPlaylist() } } mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0 -> { // 'Genre' search mode. playGenre(genre) } mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0 -> { // 'Artist' search mode. playArtist(artist, genre) } mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0 -> { // 'Album' search mode. playAlbum(album, artist) } mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0 -> { // 'Song' search mode. playSong(album, artist, genre, title) } mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0 -> { // 'Playlist' search mode. playPlaylist(album, artist, genre, playlist, title) } } } }
Java
protected void onCreate(Bundle savedInstanceState) { //... Intent intent = this.getIntent(); if (intent.getAction().compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) { String mediaFocus = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS); String query = intent.getStringExtra(SearchManager.QUERY); // Some of these extras might not be available depending on the search mode. String album = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM); String artist = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST); String genre = intent.getStringExtra("android.intent.extra.genre"); String playlist = intent.getStringExtra("android.intent.extra.playlist"); String title = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE); // Determine the search mode and use the corresponding extras. if (mediaFocus == null) { // 'Unstructured' search mode (backward compatible). playUnstructuredSearch(query); } else if (mediaFocus.compareTo("vnd.android.cursor.item/*") == 0) { if (query.isEmpty()) { // 'Any' search mode. playResumeLastPlaylist(); } else { // 'Unstructured' search mode. playUnstructuredSearch(query); } } else if (mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0) { // 'Genre' search mode. playGenre(genre); } else if (mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0) { // 'Artist' search mode. playArtist(artist, genre); } else if (mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0) { // 'Album' search mode. playAlbum(album, artist); } else if (mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0) { // 'Song' search mode. playSong(album, artist, genre, title); } else if (mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0) { // 'Playlist' search mode. playPlaylist(album, artist, genre, playlist, title); } } }
新笔记
创建笔记是笔记应用常见的操作。使用以下部分中的信息创建 Intent 过滤器,以宣传您的应用执行此操作的能力。
创建笔记
要创建新笔记,请使用 ACTION_CREATE_NOTE
操作并使用以下 Extras 指定笔记详细信息,例如主题和文本。
注意:应用在完成此操作之前必须征求用户的确认。
- 操作
-
ACTION_CREATE_NOTE
- 数据 URI 方案
- 无
- MIME 类型
-
PLAIN_TEXT_TYPE
- "*/*"
- 额外数据
-
-
EXTRA_NAME
- 一个字符串,指示笔记的标题或主题。
-
EXTRA_TEXT
- 一个字符串,指示笔记的文本。
-
- 操作
-
ACTION_DIAL
- 打开拨号器或电话应用。ACTION_CALL
- 拨打电话(需要CALL_PHONE
权限)
- 数据 URI 方案
-
tel:<电话号码>
voicemail:<电话号码>
- MIME 类型
- 无
tel:2125551212
tel:(212) 555 1212
- 操作
-
"com.google.android.gms.actions.SEARCH_ACTION"
- 支持来自 Google 语音操作的搜索查询。
- 额外数据
-
QUERY
- 包含搜索查询的字符串。
- 操作
ACTION_WEB_SEARCH
- 数据 URI 方案
- 无
- MIME 类型
- 无
- 额外数据
-
SearchManager.QUERY
- 搜索字符串。
- 操作
-
ACTION_SETTINGS
ACTION_WIRELESS_SETTINGS
ACTION_AIRPLANE_MODE_SETTINGS
ACTION_WIFI_SETTINGS
ACTION_APN_SETTINGS
ACTION_BLUETOOTH_SETTINGS
ACTION_DATE_SETTINGS
ACTION_LOCALE_SETTINGS
ACTION_INPUT_METHOD_SETTINGS
ACTION_DISPLAY_SETTINGS
ACTION_SECURITY_SETTINGS
ACTION_LOCATION_SOURCE_SETTINGS
ACTION_INTERNAL_STORAGE_SETTINGS
ACTION_MEMORY_CARD_SETTINGS
有关可用的其他设置屏幕,请参阅
Settings
文档。 - 数据 URI 方案
- 无
- MIME 类型
- 无
- 操作
ACTION_SENDTO
或
ACTION_SEND
或
ACTION_SEND_MULTIPLE
- 数据 URI 方案
-
sms:<电话号码>
smsto:<电话号码>
mms:<电话号码>
mmsto:<电话号码>
这些方案的处理方式都相同。
- MIME 类型
-
"text/plain"
"image/*"
"video/*"
- 额外数据
-
"subject"
- 消息主题的字符串(通常仅适用于彩信)。
"sms_body"
- 文本消息的字符串。
EXTRA_STREAM
- 指向要附加的图片或视频的
Uri
。如果使用ACTION_SEND_MULTIPLE
操作,此 Extra 是指向要附加的图片或视频的Uri
对象的ArrayList
。
- 操作
ACTION_VIEW
- 数据 URI 方案
http:<URL>
https:<URL>
- MIME 类型
-
"text/plain"
"text/html"
"application/xhtml+xml"
"application/vnd.wap.xhtml+xml"
- 设置 Android 设备进行开发,或使用虚拟设备。
- 安装处理您想要支持的 Intent 的应用版本。
- 使用
adb
触发 Intentadb shell am start -a <ACTION> -t <MIME_TYPE> -d <DATA> \ -e <EXTRA_NAME> <EXTRA_VALUE> -n <ACTIVITY>
例如
adb shell am start -a android.intent.action.DIAL \ -d tel:555-5555 -n org.example.MyApp/.MyActivity
- 如果您定义了所需的 Intent 过滤器,则处理该 Intent。
意图示例
Kotlin
fun createNote(subject: String, text: String) { val intent = Intent(NoteIntents.ACTION_CREATE_NOTE).apply { putExtra(NoteIntents.EXTRA_NAME, subject) putExtra(NoteIntents.EXTRA_TEXT, text) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void createNote(String subject, String text) { Intent intent = new Intent(NoteIntents.ACTION_CREATE_NOTE) .putExtra(NoteIntents.EXTRA_NAME, subject) .putExtra(NoteIntents.EXTRA_TEXT, text); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="com.google.android.gms.actions.CREATE_NOTE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="*/*" /> </intent-filter> </activity>
电话
发起呼叫是电话应用常见的操作。使用以下部分中的信息创建 Intent 过滤器,以宣传您的应用执行此操作的能力。
发起电话呼叫
要打开电话应用并拨打电话号码,请使用 ACTION_DIAL
操作并使用以下 URI 方案指定电话号码。当电话应用打开时,它会显示电话号码,用户必须点击呼叫按钮才能开始电话呼叫。
要直接拨打电话,请使用 ACTION_CALL
操作并使用以下 URI 方案指定电话号码。当电话应用打开时,它会开始电话呼叫。用户无需点击呼叫按钮。
ACTION_CALL
操作要求您在清单文件中添加 CALL_PHONE
权限
<uses-permission android:name="android.permission.CALL_PHONE" />
有效的电话号码是 IETF RFC 3966 中定义的号码。有效示例如下:
电话应用的拨号器擅长规范化方案,例如电话号码。因此,在 Uri.parse()
方法中,并非严格要求所描述的方案。但是,如果您尚未尝试某种方案,或不确定它是否可以处理,请改用 Uri.fromParts()
方法。
意图示例
Kotlin
fun dialPhoneNumber(phoneNumber: String) { val intent = Intent(Intent.ACTION_DIAL).apply { data = Uri.parse("tel:$phoneNumber") } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void dialPhoneNumber(String phoneNumber) { Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("tel:" + phoneNumber)); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
搜索
以下是搜索应用的常见操作,包括创建 Intent 过滤器以宣传您的应用执行每个操作的能力所需的信息。
使用特定应用进行搜索
为了支持您应用内的搜索,请在您的应用中声明一个带有 SEARCH_ACTION
操作的 Intent 过滤器,如以下 Intent 过滤器示例所示。
注意:我们不建议将 SEARCH_ACTION
用于应用搜索。相反,请实现 GET_THING
操作,以利用 Google Assistant 对应用内搜索的内置支持。有关更多信息,请参阅 Google Assistant App Actions 文档。
意图过滤器示例
<activity android:name=".SearchActivity"> <intent-filter> <action android:name="com.google.android.gms.actions.SEARCH_ACTION"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
执行网页搜索
要发起网页搜索,请使用 ACTION_WEB_SEARCH
操作并在 SearchManager.QUERY
Extra 中指定搜索字符串。
意图示例
Kotlin
fun searchWeb(query: String) { val intent = Intent(Intent.ACTION_WEB_SEARCH).apply { putExtra(SearchManager.QUERY, query) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void searchWeb(String query) { Intent intent = new Intent(Intent.ACTION_WEB_SEARCH); intent.putExtra(SearchManager.QUERY, query); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
设置
当您的应用需要用户更改某些内容时,要打开系统“设置”应用中的某个屏幕,请使用以下 Intent 操作之一:
意图示例
Kotlin
fun openWifiSettings() { val intent = Intent(Settings.ACTION_WIFI_SETTINGS) if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void openWifiSettings() { Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
短信/彩信
撰写带附件的短信/彩信是短信应用常见的操作。使用以下部分中的信息创建 Intent 过滤器,以宣传您的应用执行此操作的能力。
撰写带附件的短信/彩信
要发起短信或彩信,请使用以下 Intent 操作之一,并使用以下 Extra 键指定消息详细信息,例如电话号码、主题和消息正文。
意图示例
Kotlin
fun composeMmsMessage(message: String, attachment: Uri) { val intent = Intent(Intent.ACTION_SENDTO).apply { type = HTTP.PLAIN_TEXT_TYPE putExtra("sms_body", message) putExtra(Intent.EXTRA_STREAM, attachment) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void composeMmsMessage(String message, Uri attachment) { Intent intent = new Intent(Intent.ACTION_SENDTO); intent.setType(HTTP.PLAIN_TEXT_TYPE); intent.putExtra("sms_body", message); intent.putExtra(Intent.EXTRA_STREAM, attachment); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
如果您希望确保您的 Intent 仅由短信应用处理,而不是其他电子邮件或社交应用处理,那么请使用 ACTION_SENDTO
操作并包含 "smsto:"
数据方案,如以下示例所示:
Kotlin
fun composeMmsMessage(message: String, attachment: Uri) { val intent = Intent(Intent.ACTION_SEND).apply { data = Uri.parse("smsto:") // Only SMS apps respond to this. putExtra("sms_body", message) putExtra(Intent.EXTRA_STREAM, attachment) } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void composeMmsMessage(String message, Uri attachment) { Intent intent = new Intent(Intent.ACTION_SEND); intent.setData(Uri.parse("smsto:")); // Only SMS apps respond to this. intent.putExtra("sms_body", message); intent.putExtra(Intent.EXTRA_STREAM, attachment); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.intent.action.SEND" /> <data android:type="text/plain" /> <data android:type="image/*" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
注意:如果您正在开发短信/彩信应用,则必须为多个附加操作实现 Intent 过滤器,以便在 Android 4.4 及更高版本上可用作默认短信应用。有关更多信息,请参阅 Telephony
文档。
网络浏览器
加载网页 URL 是网络浏览器应用常见的操作。使用以下部分中的信息创建 Intent 过滤器,以宣传您的应用执行此操作的能力。
加载网页 URL
要打开网页,请使用 ACTION_VIEW
操作并在 Intent 数据中指定网页 URL。
意图示例
Kotlin
fun openWebPage(url: String) { val webpage: Uri = Uri.parse(url) val intent = Intent(Intent.ACTION_VIEW, webpage) if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } }
Java
public void openWebPage(String url) { Uri webpage = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW, webpage); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
意图过滤器示例
<activity ...> <intent-filter> <action android:name="android.intent.action.VIEW" /> <!-- Include the host attribute if you want your app to respond only to URLs with your app's domain. --> <data android:scheme="http" android:host="www.example.com" /> <category android:name="android.intent.category.DEFAULT" /> <!-- The BROWSABLE category is required to get links from web pages. --> <category android:name="android.intent.category.BROWSABLE" /> </intent-filter> </activity>
提示:如果您的 Android 应用提供与您的网站类似的功能,请为指向您网站的 URL 添加 Intent 过滤器。这样,如果用户安装了您的应用,则来自电子邮件或其他指向您网站的网页的链接将打开您的 Android 应用,而不是您的网页。在处理 Android App Link 中了解更多信息。
从 Android 12 (API 级别 31) 开始,通用网页 Intent 仅当您的应用被批准用于该网页 Intent 中包含的特定域时,才会解析为您的应用中的 activity。如果您的应用未被批准用于该域,则网页 Intent 将解析为用户的默认浏览器应用。
使用 Android 调试桥验证 Intent
要验证您的应用是否响应您想要支持的 Intent,您可以使用 adb
工具通过以下方式触发特定 Intent:
有关更多信息,请参阅发出 shell 命令。