常用意图

意图允许您通过描述您想要执行的操作(例如,在 Intent 对象中“查看地图”或“拍照”)来启动另一个应用中的活动。此类意图称为隐式意图,因为它没有指定要启动的应用组件,而是指定了一个操作并提供了一些用于执行该操作的数据

当您调用 startActivity()startActivityForResult() 并将其传递给隐式意图时,系统会解析意图到可以处理该意图的应用并启动其相应的 Activity。如果有多个应用可以处理该意图,则系统会向用户显示一个对话框以选择要使用的应用。

此页面描述了您可以用来执行常见操作的几个隐式意图,并按处理该意图的应用类型进行组织。每个部分还显示了如何创建意图过滤器来宣传您的应用执行该操作的能力。

注意:如果设备上没有可以接收隐式意图的应用,则应用在调用 startActivity() 时会崩溃。要首先验证是否存在应用可以接收该意图,请在您的 Intent 对象上调用 resolveActivity()。如果结果非空,则至少有一个应用可以处理该意图,并且可以安全地调用 startActivity()。如果结果为空,则不要使用该意图,并且如果可能,请禁用调用该意图的功能。

如果您不熟悉如何创建意图或意图过滤器,请先阅读意图和意图过滤器

要了解如何从您的开发主机触发此页面上列出的意图,请参阅使用 Android 调试桥验证意图部分。

Google 语音操作

Google 语音操作响应语音命令触发此页面上列出的一些意图。有关更多信息,请参阅开始使用系统语音操作

闹钟

以下是闹钟应用的常见操作,包括您需要创建意图过滤器以宣传您的应用执行每个操作的能力的信息。

创建闹钟

Google 语音操作

  • "设置早上 7 点的闹钟"

要创建新的闹钟,请使用 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>

创建计时器

Google 语音操作

  • "设置 5 分钟计时器"

要创建倒计时计时器,请使用 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
事件的开始时间(自纪元以来的毫秒数)。
EXTRA_EVENT_END_TIME
事件的结束时间(自纪元以来的毫秒数)。
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_CAPTUREACTION_VIDEO_CAPTURE 操作。此外,请在 EXTRA_OUTPUT 额外信息中指定您希望相机保存图片或视频的 URI 位置。

操作
ACTION_IMAGE_CAPTURE
ACTION_VIDEO_CAPTURE
数据 URI 方案
MIME 类型
额外信息
EXTRA_OUTPUT
相机应用程序保存图片或视频文件的 URI 位置(作为 Uri 对象)。

当相机应用程序成功将焦点返回到您的活动时——换句话说,您的应用程序接收 onActivityResult() 回调——您可以访问使用 EXTRA_OUTPUT 值指定的 URI 处的图片或视频。

注意: 当您使用 ACTION_IMAGE_CAPTURE 拍摄照片时,相机也可能会在结果 Intent 中返回照片的缩小副本或缩略图,并将其保存为名为 "data" 的额外字段中的 Bitmap

示例意图

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>

在处理此意图时,让您的活动检查传入 Intent 中的 EXTRA_OUTPUT 额外信息,然后将捕获的图片或视频保存在该额外信息指定的 location 并调用 setResult(),其中包含一个 Intent,该 Intent 在名为 "data" 的额外信息中包含压缩的缩略图。

以静止图像模式启动相机应用程序

Google 语音操作

  • "拍照"

要以静止图像模式打开相机应用程序,请使用 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>

以视频模式启动相机应用程序

Google 语音操作

  • "录制视频"

要以视频模式打开相机应用程序,请使用 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 权限才能查看有关特定联系人的特定信息。

如果您只需要从联系人中检索一种数据类型,则使用来自 ContactsContract.CommonDataKinds 类的 CONTENT_TYPE 使用此技术比使用上一节中所示的 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 类型。返回到您的应用的文件引用对您活动当前的生命周期是临时的,因此,如果您想稍后访问它,则必须导入一个副本,以便您以后可以读取它。

此意图还允许用户在此过程中创建新文件。例如,用户可以使用相机拍摄新照片,而不是选择现有照片。

传递到您的 onActivityResult() 方法的结果意图包含带有指向文件 URI 的数据。URI 可以是任何内容,例如 http: URI、file: URI 或 content: URI。但是,如果您希望将可选择的文件限制为仅那些可从内容提供程序(content: URI)访问的文件,并且可以通过 openFileDescriptor() 作为文件流使用,请将 CATEGORY_OPENABLE 类别添加到您的意图中。

在 Android 4.3(API 级别 18)及更高版本上,您还可以通过将 EXTRA_ALLOW_MULTIPLE 添加到意图并将其设置为 true 来允许用户选择多个文件。然后,您可以访问 getClipData() 返回的 ClipData 对象中的每个选定文件。

操作
ACTION_GET_CONTENT
数据 URI 方案
MIME 类型
与用户需要选择的的文件类型相对应的 MIME 类型。
额外信息
EXTRA_ALLOW_MULTIPLE
一个布尔值,声明用户是否可以一次选择多个文件。
EXTRA_LOCAL_ONLY
一个布尔值,声明返回的文件是否必须直接从设备中获取,而不是需要从远程服务下载。
类别(可选)
CATEGORY_OPENABLE
仅返回可以使用 openFileDescriptor() 表示为文件流的“可打开”文件。

获取照片的示例意图

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

返回照片的示例意图过滤器

<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 supports OpenableColumns
             and ContentResolver.openFileDescriptor(). -->
        <category android:name="android.intent.category.OPENABLE" />
    </intent-filter>
</activity>

打开特定类型的文件

在 Android 4.4 或更高版本上运行时,您可以通过使用 ACTION_OPEN_DOCUMENT 操作并指定 MIME 类型来请求打开由另一个应用管理的文件,而不是使用 ACTION_GET_CONTENT 操作检索必须导入到您的应用的文件副本。要让用户创建您的应用可以写入的新文档,请改用 ACTION_CREATE_DOCUMENT 操作。

例如,ACTION_CREATE_DOCUMENT 意图允许用户选择他们希望在何处创建新文档(例如,在管理文档存储的其他应用中),而不是从现有的 PDF 文档中进行选择。然后,您的应用会收到它可以在其中写入新文档的 URI 位置。

来自 ACTION_GET_CONTENT 操作传递到您的 onActivityResult() 方法的意图可能会返回任何类型的 URI,而来自 ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT 的结果意图始终将所选文件指定为由 DocumentsProvider 支持的 content: URI。您可以使用 openFileDescriptor() 打开文件,并使用来自 DocumentsContract.Document 的列查询其详细信息。

返回的 URI 会授予您的应用对文件的长期读取访问权限,也可能具有写入访问权限。ACTION_OPEN_DOCUMENT 操作在您想要读取现有文件而不将其复制到您的应用中或想要就地打开和编辑文件时特别有用。

您还可以通过将 EXTRA_ALLOW_MULTIPLE 添加到意图并将其设置为 true 来允许用户选择多个文件。如果用户仅选择一个项目,则您可以从 getData() 中检索该项目。如果用户选择多个项目,则 getData() 返回 null,您必须改为从 getClipData() 返回的 ClipData 对象中检索每个项目。

注意:您的意图必须指定 MIME 类型,并且必须声明 CATEGORY_OPENABLE 类别。如果合适,您可以通过使用 EXTRA_MIME_TYPES 额外数据添加 MIME 类型数组来指定多个 MIME 类型——如果您这样做,则必须将 setType() 中的主 MIME 类型设置为 "*/*"

操作
ACTION_OPEN_DOCUMENT
ACTION_CREATE_DOCUMENT
数据 URI 方案
MIME 类型
与用户需要选择的的文件类型相对应的 MIME 类型。
额外信息
EXTRA_MIME_TYPES
与您的应用请求的文件类型相对应的 MIME 类型数组。当您使用此额外数据时,必须将 setType() 中的主 MIME 类型设置为 "*/*"
EXTRA_ALLOW_MULTIPLE
一个布尔值,声明用户是否可以一次选择多个文件。
EXTRA_TITLE
ACTION_CREATE_DOCUMENT 一起使用,以指定初始文件名。
EXTRA_LOCAL_ONLY
一个布尔值,声明返回的文件是否必须直接从设备中获取,而不是需要从远程服务下载。
类别
CATEGORY_OPENABLE
仅返回可以使用 openFileDescriptor() 表示为文件流的“可打开”文件。

获取照片的示例意图

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 操作的意图。相反,系统会接收此意图,并在统一的用户界面中显示来自各种应用的所有可用文件。

要在该 UI 中提供应用的文件并允许其他应用打开这些文件,您必须实现一个DocumentsProvider,并包含一个针对PROVIDER_INTERFACE ("android.content.action.DOCUMENTS_PROVIDER") 的意图过滤器,如下例所示。

<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>

有关如何使应用管理的文件可供其他应用打开的更多信息,请阅读使用存储访问框架打开文件

本地操作

呼叫网约车是一种常见的本地操作。使用以下部分中的信息创建意图过滤器,以宣传您的应用执行此操作的能力。

呼叫网约车

Google 语音操作

  • "帮我叫一辆出租车"
  • "帮我叫一辆车"

(仅限 Wear OS)

要呼叫出租车,请使用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>

地图

在地图上显示位置是地图应用的常见操作。使用以下部分中的信息创建意图过滤器,以宣传您的应用执行此操作的能力。

在地图上显示位置

要打开地图,请使用ACTION_VIEW 操作,并在意图数据中使用以下方案之一指定位置信息。

操作
ACTION_VIEW
数据 URI 方案
geo:纬度,经度
在给定的经度和纬度处显示地图。

示例:"geo:47.6,-122.3"

geo:纬度,经度?z=缩放级别
在给定的经度和纬度处以某个缩放级别显示地图。缩放级别 1 显示整个地球,以给定的latlng 为中心。最高(最近)缩放级别为 23。

示例:"geo:47.6,-122.3?z=11"

geo:0,0?q=lat,lng(标签)
在地图上显示给定的经度和纬度,并带有一个字符串标签。

示例:"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>

音乐或视频

以下是音乐和视频应用的常见操作,包括创建意图过滤器以宣传您的应用执行每个操作的能力所需的信息。

播放媒体文件

要播放音乐文件,请使用ACTION_VIEW 操作,并在意图数据中指定文件的 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>

根据搜索查询播放音乐

Google 语音操作

  • "播放迈克尔·杰克逊的比莉·简"

要根据搜索查询播放音乐,请使用INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH 意图。应用可能会响应用户的语音命令来播放音乐而触发此意图。接收此意图的应用在其库存中执行搜索以将现有内容与给定的查询匹配,并开始播放该内容。

在此意图中,包含EXTRA_MEDIA_FOCUS 字符串额外信息,它指定了预期的搜索模式。例如,搜索模式可以指定搜索是针对艺术家姓名还是歌曲名称。

操作
INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
数据 URI 方案
MIME 类型
额外信息
MediaStore.EXTRA_MEDIA_FOCUS(必需)

指示搜索模式:用户是在查找特定艺术家、专辑、歌曲还是播放列表。大多数搜索模式都需要其他额外信息。例如,如果用户有兴趣收听特定歌曲,则意图可能包含三个其他额外信息:歌曲标题、艺术家和专辑。此意图支持以下搜索模式,对应于EXTRA_MEDIA_FOCUS 的每个值。

任意 - "vnd.android.cursor.item/*"

播放任何音乐。接收应用会根据智能选择播放一些音乐,例如用户上次收听的播放列表。

其他额外信息

  • QUERY(必需):空字符串。此额外信息始终用于向后兼容性。不知道搜索模式的现有应用可以将此意图处理为非结构化搜索。

非结构化 - "vnd.android.cursor.item/*"

从非结构化搜索查询中播放特定歌曲、专辑或流派。当应用无法识别用户想要收听的内容类型时,可以生成具有此搜索模式的意图。尽可能使用更具体的搜索模式。

其他额外信息

  • QUERY(必需):包含艺术家、专辑、歌曲名称或流派的任何组合的字符串。

流派 - Audio.Genres.ENTRY_CONTENT_TYPE

播放特定流派的音乐。

其他额外信息

  • "android.intent.extra.genre"(必需) - 流派。
  • QUERY(必需):流派。此额外信息始终用于向后兼容性。不知道搜索模式的现有应用可以将此意图处理为非结构化搜索。

艺术家 - Audio.Artists.ENTRY_CONTENT_TYPE

播放特定艺术家的音乐。

其他额外信息

  • EXTRA_MEDIA_ARTIST(必需):艺术家。
  • "android.intent.extra.genre":流派。
  • QUERY(必需):包含艺术家或流派的任何组合的字符串。此额外信息始终用于向后兼容性。不知道搜索模式的现有应用可以将此意图处理为非结构化搜索。

专辑 - Audio.Albums.ENTRY_CONTENT_TYPE

播放特定专辑的音乐。

其他额外信息

  • EXTRA_MEDIA_ALBUM(必需):专辑。
  • EXTRA_MEDIA_ARTIST:艺术家。
  • "android.intent.extra.genre":流派。
  • QUERY(必需):包含专辑或艺术家的任何组合的字符串。此额外信息始终用于向后兼容性。不知道搜索模式的现有应用可以将此意图处理为非结构化搜索。

歌曲 - "vnd.android.cursor.item/audio"

播放特定歌曲。

其他额外信息

  • EXTRA_MEDIA_ALBUM:专辑。
  • EXTRA_MEDIA_ARTIST:艺术家。
  • "android.intent.extra.genre":流派。
  • EXTRA_MEDIA_TITLE(必需):歌曲名称。
  • QUERY(必需):包含专辑、艺术家、流派或标题的任何组合的字符串。此额外信息始终用于向后兼容性。不知道搜索模式的现有应用可以将此意图处理为非结构化搜索。

播放列表 - Audio.Playlists.ENTRY_CONTENT_TYPE

播放特定播放列表或与其他额外信息指定的某些条件匹配的播放列表。

其他额外信息

  • EXTRA_MEDIA_ALBUM:专辑。
  • EXTRA_MEDIA_ARTIST:艺术家。
  • "android.intent.extra.genre":流派。
  • "android.intent.extra.playlist":播放列表。
  • EXTRA_MEDIA_TITLE:播放列表基于的歌曲名称。
  • QUERY(必需):包含专辑、艺术家、流派、播放列表或标题的任何组合的字符串。此额外信息始终用于向后兼容性。不知道搜索模式的现有应用可以将此意图处理为非结构化搜索。

示例意图

如果用户想要收听特定艺术家的音乐,搜索应用可能会生成以下意图。

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>

在您的活动中处理此意图时,请检查传入IntentEXTRA_MEDIA_FOCUS 额外信息的 value,以确定搜索模式。您的活动确定搜索模式后,请读取该特定搜索模式的其他额外信息的 value。有了这些信息,您的应用就可以在其库存中执行搜索,以播放与搜索查询匹配的内容。以下示例说明了这一点。

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

新建笔记

创建笔记是笔记应用的常见操作。使用以下部分中的信息创建意图过滤器,以宣传您的应用执行此操作的能力。

创建笔记

要创建新笔记,请使用 ACTION_CREATE_NOTE 操作,并使用以下额外信息指定笔记详细信息(如主题和文本)。

注意:应用必须在完成此操作之前征得用户的确认。

操作
ACTION_CREATE_NOTE
数据 URI 方案
MIME 类型
PLAIN_TEXT_TYPE
"*/*"
额外信息
EXTRA_NAME
指示笔记标题或主题的字符串。
EXTRA_TEXT
指示笔记文本的字符串。

示例意图

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>

电话

发起呼叫是电话应用的常见操作。使用以下部分中的信息创建意图过滤器,以宣传您的应用执行此操作的能力。

发起电话呼叫

要打开电话应用并拨打电话号码,请使用ACTION_DIAL操作,并使用以下URI方案指定电话号码。当电话应用打开时,它会显示电话号码,用户必须点击呼叫按钮才能开始通话。

Google 语音操作

  • "呼叫 555-5555"
  • "呼叫 bob"
  • "呼叫 语音邮件"

要直接拨打电话,请使用ACTION_CALL操作,并使用以下URI方案指定电话号码。当电话应用打开时,它会开始通话。用户无需点击呼叫按钮。

ACTION_CALL操作需要您在清单文件中添加CALL_PHONE权限

<uses-permission android:name="android.permission.CALL_PHONE" />
操作
数据 URI 方案
  • tel:<电话号码>
  • voicemail:<电话号码>
MIME 类型

有效的电话号码是在IETF RFC 3966中定义的。有效的示例包括以下内容

  • tel:2125551212
  • tel:(212) 555 1212

电话应用的拨号器擅长规范化方案,例如电话号码。因此,在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);
    }
}

以下是搜索应用的常见操作,包括创建意图过滤器以宣传您的应用执行每个操作的能力所需的信息。

使用特定应用搜索

Google 语音操作

  • "在我的视频应用中搜索猫的视频"

要支持在应用上下文中进行搜索,请在您的应用中使用SEARCH_ACTION操作声明一个意图过滤器,如下面的意图过滤器示例所示。

注意:我们不建议将SEARCH_ACTION用于应用搜索。相反,请实现GET_THING操作以利用 Google 助理对应用内搜索的内置支持。有关更多信息,请参阅 Google 助理应用操作文档。

操作
"com.google.android.gms.actions.SEARCH_ACTION"
支持来自 Google 语音操作的搜索查询。
额外信息
QUERY
包含搜索查询的字符串。

示例意图过滤器

<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额外信息中指定搜索字符串。

操作
ACTION_WEB_SEARCH
数据 URI 方案
MIME 类型
额外信息
SearchManager.QUERY
搜索字符串。

示例意图

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

设置

当您的应用需要用户更改某些内容时,要打开系统设置应用中的屏幕,请使用以下意图操作之一

操作
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 类型

示例意图

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

短信

撰写带有附件的短信/彩信是短信应用的常见操作。使用以下部分中的信息创建意图过滤器,以宣传您的应用执行此操作的能力。

撰写带有附件的短信/彩信

要启动短信或彩信,请使用以下意图操作之一,并使用以下额外键指定消息详细信息,例如电话号码、主题和消息正文。

操作
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操作,则此额外信息是ArrayList,其中包含指向要附加的图片或视频的Uri对象。

示例意图

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

如果您想确保您的意图仅由短信应用处理,而不是其他电子邮件或社交应用处理,请使用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>

注意:如果您正在开发短信/彩信应用,则必须为多个其他操作实现意图过滤器,以便在 Android 4.4 及更高版本上可用作默认短信应用。有关更多信息,请参阅Telephony中的文档。

网络浏览器

加载网络 URL 是网络浏览器应用的常见操作。使用以下部分中的信息创建意图过滤器,以宣传您的应用执行此操作的能力。

加载网络 URL

Google 语音操作

  • "打开 example.com"

要打开网页,请使用ACTION_VIEW操作,并在意图数据中指定网络 URL。

操作
ACTION_VIEW
数据 URI 方案
http:<URL>
https:<URL>
MIME 类型
"text/plain"
"text/html"
"application/xhtml+xml"
"application/vnd.wap.xhtml+xml"

示例意图

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 的意图过滤器。然后,如果用户安装了您的应用,则来自电子邮件或其他网页指向您的网站的链接将打开您的 Android 应用,而不是您的网页。在处理 Android 应用链接中了解更多信息。

从 Android 12(API 级别 31)开始,通用网络意图仅在您的应用获准使用该网络意图中包含的特定域时才会解析为您的应用中的活动。如果您的应用未获准使用该域,则网络意图将解析为用户的默认浏览器应用。

使用 Android 调试桥验证意图

要验证您的应用是否响应您要支持的意图,您可以使用adb工具通过执行以下操作来触发特定意图

  1. 开发设置 Android 设备,或使用虚拟设备
  2. 安装处理您要支持的意图的应用版本。
  3. 使用adb触发意图
    adb 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
    
  4. 如果您定义了所需的意图过滤器,则处理该意图。

有关更多信息,请参阅发出 shell 命令