如果你的应用可以执行对另一个应用有用的操作,请通过在 Activity 中指定适当的 intent 过滤器,使其能够响应操作请求。
例如,如果你构建了一个可以与用户朋友分享消息或照片的社交应用,请支持 ACTION_SEND
intent。然后,当用户从另一个应用发起“分享”操作时,你的应用会在选择器对话框(也称为消歧对话框)中显示为一个选项,如图 1 所示。

图 1. 选择器对话框。
为了让其他应用以这种方式启动你的 Activity,你需要在清单文件中为相应的 <activity>
元素添加一个 <intent-filter>
元素。
当你的应用安装在设备上时,系统会识别你的 intent 过滤器,并将信息添加到所有已安装应用支持的 intent 的内部目录中。当应用使用隐式 intent 调用 startActivity()
或 startActivityForResult()
时,系统会检查可以响应此 intent 的 Activity。
添加 intent 过滤器
为了正确定义你的 Activity 可以处理哪些 intent,请确保你添加的每个 intent 过滤器都尽可能具体,以指明 Activity 接受的操作类型和数据类型。
如果某个 Activity 具有一个 intent 过滤器,该过滤器满足 Intent
对象的以下条件,则系统可能会将给定的 Intent
发送给该 Activity:
- 操作
- 指定要执行操作的字符串。通常是平台定义的值之一,例如
ACTION_SEND
或ACTION_VIEW
。使用
<action>
元素在 intent 过滤器中指定此项。你在此元素中指定的值必须是操作的完整字符串名称,而不是 API 常量,如本页的示例所示。 - 数据
- 与 intent 相关联的数据说明。
使用
<data>
元素在 intent 过滤器中指定此项。使用此元素中的一个或多个属性,可以指定 MIME 类型、URI 前缀、URI 方案,或这些以及其他表示所接受数据类型的组合。注意:如果你不需要声明有关数据
Uri
的具体信息,例如当你的 Activity 处理其他类型的“额外”数据而不是 URI 时,则只需指定android:mimeType
属性来声明你的 Activity 处理的数据类型,例如text/plain
或image/jpeg
。 - 类别
- 提供了一种额外的方式来描述处理 intent 的 Activity,通常与用户手势或其启动位置相关。系统支持多种不同的类别,但大多数很少使用。然而,所有隐式 intent 默认都定义了
CATEGORY_DEFAULT
。使用
<category>
元素在 intent 过滤器中指定此项。
在 intent 过滤器中,你可以通过在 <intent-filter>
元素中嵌套相应的 XML 元素来声明你的 Activity 接受哪些条件。
例如,以下是一个 Activity,其 intent 过滤器处理数据类型为文本或图像的 ACTION_SEND
intent:
<activity android:name="ShareActivity"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter> </activity>
提示:如果你希望选择器对话框中的图标与 Activity 的默认图标不同,请在 <intent-filter>
元素中添加 android:icon
。
每个传入的 intent 只指定一个操作和一个数据类型,但在每个 <intent-filter>
中声明 <action>
、<category>
和 <data>
元素的多个实例是没问题的。
如果任何两对操作和数据在行为上相互排斥,请创建单独的 intent 过滤器来指定哪些操作在与哪些数据类型配对时是可接受的。
例如,假设你的 Activity 为 ACTION_SEND
和 ACTION_SENDTO
intent 处理文本和图像。在这种情况下,你必须为这两个操作定义两个单独的 intent 过滤器,因为 ACTION_SENDTO
intent 必须使用数据 Uri
通过 send
或 sendto
URI 方案来指定收件人地址。示例如下:
<activity android:name="ShareActivity"> <!-- Filter for sending text; accepts SENDTO action with sms URI schemes --> <intent-filter> <action android:name="android.intent.action.SENDTO"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="sms" /> <data android:scheme="smsto" /> </intent-filter> <!-- Filter for sending text or images; accepts SEND action and text or image data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="image/*"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>
注意:要接收隐式 intent,你必须在 intent 过滤器中包含 CATEGORY_DEFAULT
类别。方法 startActivity()
和 startActivityForResult()
会将所有 intent 视为已声明 CATEGORY_DEFAULT
类别。如果你未在 intent 过滤器中声明它,则没有隐式 intent 会解析到你的 Activity。
有关发送和接收执行社交分享行为的 ACTION_SEND
intent 的更多信息,请参阅从其他应用接收简单数据。你还可以在共享简单数据和共享文件中找到有用的数据共享信息。
在 Activity 中处理 intent
要决定在 Activity 中执行何种操作,请读取用于启动它的 Intent
。
当你的 Activity 启动时,调用 getIntent()
以检索启动该 Activity 的 Intent
。你可以在 Activity 生命周期中的任何时候执行此操作,但通常在早期回调期间执行,例如 onCreate()
或 onStart()
。
示例如下:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) val data: Uri? = intent?.data // Figure out what to do based on the intent type if (intent?.type?.startsWith("image/") == true) { // Handle intents with image data } else if (intent?.type == "text/plain") { // Handle intents with text } }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get the intent that started this activity Intent intent = getIntent(); Uri data = intent.getData(); // Figure out what to do based on the intent type if (intent.getType().indexOf("image/") != -1) { // Handle intents with image data } else if (intent.getType().equals("text/plain")) { // Handle intents with text } }
返回结果
如果你想向调用你的 Activity 的 Activity 返回结果,请调用 setResult()
来指定结果代码和结果 Intent
。当你的操作完成并且用户返回到原始 Activity 时,调用 finish()
以关闭和销毁你的 Activity。示例如下:
Kotlin
// Create intent to deliver some kind of result data Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result -> setResult(Activity.RESULT_OK, result) } finish()
Java
// Create intent to deliver some kind of result data Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")); setResult(Activity.RESULT_OK, result); finish();
你必须始终指定结果代码。通常,它是 RESULT_OK
或 RESULT_CANCELED
。然后,你可以根据需要提供额外的 Intent
数据。
注意:结果默认为 RESULT_CANCELED
。因此,如果用户在完成操作并设置结果之前点击返回按钮,则原始 Activity 会收到“已取消”结果。
如果你只需要返回一个整数来表示多个结果选项之一,你可以将结果代码设置为任何大于 0 的值。如果你使用结果代码来传递整数并且不需要包含 Intent
,则可以调用 setResult()
并只传递结果代码:
Kotlin
setResult(RESULT_COLOR_RED) finish()
Java
setResult(RESULT_COLOR_RED); finish();
在这种情况下,可能只有少数几种可能的结果,因此结果代码是本地定义的整数(大于 0)。当你要将结果返回到自己应用中的 Activity 时,这种方法效果很好,因为接收结果的 Activity 可以引用公共常量来确定结果代码的值。
注意:无需检查你的 Activity 是通过 startActivity()
还是 startActivityForResult()
启动的。如果启动你的 Activity 的 intent 可能会期望结果,只需调用 setResult()
即可。如果原始 Activity 调用了 startActivityForResult()
,系统会将你提供给 setResult()
的结果发送给它;否则,结果将被忽略。