从其他应用接收简单数据

就像应用可以向其他应用发送数据一样,它也可以从其他应用接收数据。考虑用户如何与您的应用交互以及您希望从其他应用接收哪些数据类型。例如,社交网络应用可能希望接收文本内容(如有趣的网页 URL)来自其他应用。

其他应用的用户通常会通过 Android 共享表单或 Intent 解析器将数据发送到您的应用。向您的应用发送数据的应用必须为此数据设置 MIME 类型。您的应用可以通过以下方式接收其他应用发送的数据

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

直接共享目标是您应用中特定 Activity 的深层链接。它们通常代表一个人或一个群组,并且 Android 共享表单会显示它们。例如,消息应用可以为一个人提供一个直接共享目标,该目标直接深层链接到与该人的对话。有关详细说明,请参阅 提供直接共享目标

支持 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 媒体类型官方注册表。

创建出色的共享目标

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

使用活动接收数据

使用活动接收数据涉及更新清单、处理传入内容以及确保用户识别您的应用。

更新清单

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

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

当另一个应用尝试通过构建意图并将其传递给startActivity()来共享这些内容中的任何一个时,您的应用将在 Android 共享表单或意图解析器中列为选项。如果用户选择您的应用,这将启动相应的活动(在前面的示例中为.ui.MyActivity)。然后,您需要在代码和 UI 中适当地处理内容。

处理传入内容

要处理由Intent传递的内容,请调用getIntent()以获取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 共享表单和意图解析器中由其图标标签表示。这些都在清单中定义。您可以设置活动或意图过滤器标签以提供更多上下文。

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