正如应用可以向其他应用发送数据一样,它也可以从其他应用接收数据。请思考用户如何与您的应用互动,以及您希望从其他应用接收哪些数据类型。例如,社交网络应用可能对接收来自其他应用的文本内容(如有趣的网页 URL)感兴趣。
其他应用的用户经常通过 Android 分享表或 intent 解析器向您的应用发送数据。向您的应用发送数据的应用必须为该数据设置 MIME 类型。您的应用可以通过以下方式接收其他应用发送的数据:
- 清单中带有匹配
intent-filter
标签的Activity
- 您的应用发布的共享快捷方式。
直接分享目标是您的应用中特定 Activity 的深层链接。它们通常代表一个人或一个群组,并显示在 Android 分享表中。例如,消息应用可以为某个人提供直接分享目标,该目标直接链接到与该人的对话。有关详细说明,请参阅提供直接分享目标。
支持 MIME 类型
理想情况下,应用必须能够接收尽可能广泛的 MIME 类型。例如,一个设计用于发送文本、图片和视频的消息应用,理想情况下应支持接收 text/*
、image/*
和 video/*
。以下是一些在 Android 中发送和接收简单数据的常见 MIME 类型。
接收方注册 | 发送方发送 |
---|---|
text/* |
|
`image/*` |
|
video/* |
|
支持的文件扩展名 | 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 分享表或 intent 解析器中。如果用户选择您的应用,这将启动相应的 activity(在前面的示例中是 .ui.MyActivity
)。接下来,由您在代码和 UI 中适当处理内容。
处理传入内容
要处理 Intent
传递的内容,请调用 getIntent()
来获取 Intent
对象。获取到对象后,您可以检查其内容以确定下一步操作。如果此 activity 可以从系统的其他部分启动(例如启动器),请在检查 intent 时考虑这一点。
请格外小心地检查传入数据,您永远不知道其他应用可能会发送什么给您。例如,可能会设置错误的 MIME 类型,或者发送的图片可能非常大。此外,请记住在单独的线程而非主(“UI”)线程中处理二进制数据。
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... when { intent?.action == Intent.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 == Intent.ACTION_SEND_MULTIPLE && intent.type?.startsWith("image/") == true -> { handleSendMultipleImages(intent) // Handle multiple images being sent } else -> { // Handle other intents, such as being started from the home screen } } ... } private fun handleSendText(intent: Intent) { intent.getStringExtra(Intent.EXTRA_TEXT)?.let { // Update UI to reflect text being shared } } private fun handleSendImage(intent: Intent) { (intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as? Uri)?.let { // Update UI to reflect image being shared } } private fun handleSendMultipleImages(intent: Intent) { intent.getParcelableArrayListExtra<Parcelable>(Intent.EXTRA_STREAM)?.let { // Update UI to reflect multiple images being shared } }
Java
void onCreate (Bundle savedInstanceState) { ... // Get intent, action and MIME type Intent intent = getIntent(); String action = intent.getAction(); String type = intent.getType(); if (Intent.ACTION_SEND.equals(action) && type != null) { if ("text/plain".equals(type)) { handleSendText(intent); // Handle text being sent } else if (type.startsWith("image/")) { handleSendImage(intent); // Handle single image being sent } } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) { if (type.startsWith("image/")) { handleSendMultipleImages(intent); // Handle multiple images being sent } } else { // Handle other intents, such as being started from the home screen } ... } void handleSendText(Intent intent) { String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); if (sharedText != null) { // Update UI to reflect text being shared } } void handleSendImage(Intent intent) { Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM); if (imageUri != null) { // Update UI to reflect image being shared } } void handleSendMultipleImages(Intent intent) { ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); if (imageUris != null) { // Update UI to reflect multiple images being shared } }
接收数据后更新 UI 可以像填充 EditText
一样简单,也可以更复杂,例如对图像应用有趣的图片滤镜。接下来发生什么取决于您的应用。
确保用户识别您的应用
您的应用在 Android 分享表和 intent 解析器中通过其图标和标签表示。这些都在清单中定义。您可以设置 activity 或 intent 过滤器标签以提供更多上下文。
从 Android 10 (API 级别 29) 开始,Android 分享表仅使用在清单的 application
标签中设置的图标。Android 会忽略在 intent-filter
和 activity
标签中设置的图标。