接收来自其他应用的简单数据

正如应用可以向其他应用发送数据一样,它也可以接收来自其他应用的数据。想想用户如何与您的应用互动,以及您希望从其他应用接收哪些数据类型。例如,社交网络应用可能对接收来自其他应用的文本内容(例如有趣的网址)感兴趣。

其他应用的用户经常通过 Android Sharesheet 或 intent 解析器向您的应用发送数据。向您的应用发送数据的应用必须为该数据设置 MIME 类型。您的应用可以通过以下方式接收其他应用发送的数据:

  • 在清单中有匹配的 intent-filter 标记的 Activity
  • 您的应用发布的共享快捷方式。

直接分享目标是深入到您应用中的特定 Activity 的深层链接。它们通常代表一个人或一个群组,并由 Android Sharesheet 显示。 例如,即时通讯应用可以提供某个人的直接分享目标,该目标可以直接深层链接到与此人的对话。如需了解详细说明,请参阅 提供直接分享目标

支持 MIME 类型

理想情况下,应用必须能够接收尽可能广泛的 MIME 类型。 例如,专为发送文本、图片和视频而设计的短信应用理想情况下应支持接收 text/*image/*video/*。以下是在 Android 中发送和接收简单数据时一些常用的 MIME 类型。

接收器注册 发送器发送
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
image/*
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
支持的文件扩展名 application/pdf

请参阅 IANA 官方 MIME 媒体类型注册表。

制作出色的共享目标

当用户点按与特定 Activity·关联的共享目标时,他们应该能够在使用共享内容之前对内容进行确认和编辑。对于文本数据,这一点尤为重要。

通过 Activity 接收数据

通过 Activity 接收数据涉及更新清单、处理传入的内容,以及确保用户能够识别您的应用。

更新您的清单

intent 过滤器会告知系统应用组件接受哪些 intent。 与您在 向其他应用发送简单数据 课程中构建具有 ACTION_SEND 操作的 intent 的方式类似,您可以创建 intent 过滤器来接收具有此操作的 intent。您 可以使用 <intent-filter> 元素在清单中定义 intent 过滤器。 例如,如果您的应用能够处理文本内容接收,则包含一个或多个任意类型的图片的清单将如下面的代码段所示:

<activity android:name=".ui.MyActivity" >
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND_MULTIPLE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
</activity>

当另一个应用尝试通过构建一个 intent 并将它传递给 startActivity() 来共享任何这些内容时,您的应用 都将在 Android Sharesheet 或 intent 解析器中列为一个选项。如果用户选择您的应用,系统会启动相应的 Activity(上例中的 .ui.MyActivity)。然后,您需要在代码和界面中适当地处理内容。

处理传入的内容

如需处理 Intent 传送的内容,请调用 getIntent() 以获取 Intent 对象。获得该对象后,您可以检查其内容以确定下一步操作。如果此 Activity 可从系统的其他部分(例如启动器)启动,您在检查 intent 时需要将这一点考虑在内。

请格外注意检查传入的数据,因为您永远不知道其他应用可能会向您发送什么。例如,可能设置了错误的 MIME 类型,或者所发送的图像可能非常大。此外,请务必在单独的线程(而不是主线程 [“界面”线程])中处理二进制数据。

@Composable
fun SharesheetHandler() {
    val context = LocalContext.current
    val intent = (context as? Activity)?.intent

    when (intent?.action) {
        ACTION_SEND -> {
            if ("text/plain" == intent.type) {
                handleSendText(intent) // Handle text being sent.
            } else if (intent.type?.startsWith("image/") == true) {
                handleSendImage(intent) // Handle single image being sent
            }
        }

        Intent.ACTION_SEND_MULTIPLE -> {
            if (intent.type?.startsWith("image/") == true) {
                handleSendMultipleImages(intent) // Handle multiple images being sent
            }
        }

        else -> {
            // Handle other intents, such as being started from the home screen
        }
    }
}

fun handleSendText(intent: Intent) {
    intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
        // Update ViewModel state to change state of text being shared
    }
}

fun handleSendImage(intent: Intent) {
    IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java).let {
        // Update ViewModel state to change state of image being shared
    }
}

fun handleSendMultipleImages(intent: Intent) {
    IntentCompat.getParcelableArrayListExtra(intent, Intent.EXTRA_STREAM, Uri::class.java).let {
        // Update ViewModel state to change state of image(s) being shared
    }
}

在收到数据后更新界面可能很简单,例如填充 EditText,也可能更 复杂,例如向图片应用有趣的滤镜。接下来会发生什么取决于您的应用。

屏幕截图网址共享

拍摄屏幕截图时,您可以共享屏幕截图和任何关联的网址。 这可以提供更丰富的用户体验。收到网址时,请务必从 intent 中获取 EXTRA_TEXT 字段,如以下示例所示:

IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java).let {
    // Handle the EXTRA_TEXT as well
    val extraText = intent.getCharSequenceExtra(Intent.EXTRA_TEXT)
    // Update ViewModel state to change state image being shared and the EXTRA_TEXT
    // if available
}

确保用户能够识别您的应用

在 Android Sharesheet 和 intent 解析器中,您的应用由其 图标标签表示。两者都在清单中定义。您可以设置 Activity 或 intent 过滤器标签来提供更多上下文。

从 Android 10(API 级别 29)开始,Android Sharesheet 仅使用清单中的 application 标记上设置的图标。Android 会忽略在 intent-filteractivity 标记上设置的图标。