让其他应用启动您的活动

如果您的应用可以执行可能对其他应用有用的操作,请通过在您的活动中指定适当的意图过滤器,准备它来响应操作请求。

例如,如果您构建了一个可以与用户朋友共享消息或照片的社交应用,请支持 ACTION_SEND 意图。然后,当用户从另一个应用中启动“共享”操作时,您的应用会作为选择对话框(也称为歧义对话框)中的一个选项出现,如图 1 所示。

图 1. 选择对话框。

要以这种方式让其他应用启动您的活动,您需要在清单文件中为相应的 <activity> 元素添加一个 <intent-filter> 元素。

当您的应用安装在设备上时,系统会识别您的意图过滤器并将信息添加到所有已安装应用支持的意图的内部目录中。当应用调用 startActivity()startActivityForResult() 并使用隐式意图时,系统会检查可以响应该意图的活动。

添加意图过滤器

为了正确定义您的活动可以处理的意图,请尽可能具体地指定您添加的每个意图过滤器,以说明活动接受的动作和数据类型。

如果活动拥有满足以下 Intent 对象条件的意图过滤器,系统可能会将给定的 Intent 发送到该活动。

操作
指定要执行的操作的字符串。通常是平台定义的值之一,例如 ACTION_SENDACTION_VIEW

在您的意图过滤器中使用 <action> 元素指定此操作。您在此元素中指定的值必须是操作的完整字符串名称,而不是 API 常量,如本页示例所示。

数据
与意图关联的数据描述。

在您的意图过滤器中使用 <data> 元素指定此操作。可以使用此元素中的一个或多个属性来指定 MIME 类型、URI 前缀、URI 方案或这些属性的组合,以指示接受的数据类型。

注意: 如果您不需要声明有关数据 Uri 的具体信息(例如,当您的活动处理其他类型的“额外”数据而不是 URI 时),请仅指定 android:mimeType 属性来声明您的活动处理的数据类型,例如 text/plainimage/jpeg

类别
提供了一种额外的途径来描述处理意图的活动,通常与用户操作或启动它的位置相关。系统支持多种不同的类别,但大多数类别很少使用。但是,所有隐式意图默认情况下都使用 CATEGORY_DEFAULT 定义。

在您的意图过滤器中使用 <category> 元素指定此操作。

在您的意图过滤器中,您可以通过在 <intent-filter> 元素中嵌套相应的 XML 元素来声明您的活动接受哪些条件。

例如,以下活动拥有一个意图过滤器,它在数据类型为文本或图像时处理 ACTION_SEND 意图。

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

提示:如果您希望选择器对话框中的图标与活动的默认图标不同,请在 <intent-filter> 元素中添加 android:icon

每个传入的意图仅指定一个操作和一个数据类型,但您可以在每个 <intent-filter> 元素中声明多个 <action><category><data> 元素实例。

如果操作和数据的两对在行为上是互斥的,请创建单独的意图过滤器来指定在与哪些数据类型配对时哪些操作是可接受的。

例如,假设您的活动同时处理 ACTION_SENDACTION_SENDTO 意图的文本和图像。在这种情况下,您必须为这两个操作定义两个单独的意图过滤器,因为 ACTION_SENDTO 意图必须使用数据 Uri 来使用 sendsendto 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>

注意: 要接收隐式意图,您必须在意图过滤器中包含 CATEGORY_DEFAULT 类别。方法 startActivity()startActivityForResult() 会将所有意图视为已声明 CATEGORY_DEFAULT 类别。如果您没有在您的意图过滤器中声明它,则没有隐式意图会解析到您的活动。

有关发送和接收执行社交分享行为的 ACTION_SEND 意图的更多信息,请参阅 从其他应用接收简单数据。您还可以在 分享简单数据分享文件 中找到有关分享数据的有用信息。

在您的活动中处理意图

要决定在您的活动中采取什么操作,请读取用于启动它的 Intent

当您的活动启动时,请调用 getIntent() 来检索启动活动的 Intent。您可以在活动的整个生命周期中随时执行此操作,但通常在早期的回调期间执行,例如 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
    }
}

返回结果

如果您希望将结果返回到调用您的活动的活动,请调用 setResult() 来指定结果代码和结果 Intent。当您的操作完成并且用户返回到原始活动时,请调用 finish() 来关闭并销毁您的活动。以下示例显示了这种情况。

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。因此,如果用户在完成操作之前以及您设置结果之前点击了“后退”按钮,则原始活动会收到“已取消”的结果。

如果您只需要返回一个表示多个结果选项之一的整数,您可以将结果代码设置为大于 0 的任何值。如果您使用结果代码来传递整数并且您不需要包含 Intent,您可以调用 setResult() 并且仅传递结果代码。

Kotlin

setResult(RESULT_COLOR_RED)
finish()

Java

setResult(RESULT_COLOR_RED);
finish();

在这种情况下,可能只有几个可能的结果,因此结果代码是本地定义的整数(大于 0)。当您将结果返回到您自己应用中的活动时,这非常有效,因为接收结果的活动可以引用公共常量来确定结果代码的值。

注意: 不需要检查您的活动是使用 startActivity() 还是 startActivityForResult() 启动的。如果启动您的活动的意图可能期望结果,只需调用 setResult() 即可。如果发起的活动调用了 startActivityForResult(),则系统会将您提供给 setResult() 的结果传递给它;否则,结果将被忽略。