将简单的数据发送到其他应用

Android 利用 intent 及其关联的 extra 让用户快速分享信息, 轻松使用自己喜爱的应用

Android 为用户提供了两种在应用之间分享数据的方式:

  • Android Sharesheet 主要用于将内容发送到应用外部和/或直接发送 另一个用户例如,将网址分享给朋友。
  • Android intent 解析器最适合将数据传递到 明确任务的下一阶段。例如,在应用中打开 PDF 并允许用户 选择他们首选的观看器

构建 intent 时,您可以指定希望该 intent 执行的操作。 Android 使用 ACTION_SEND 操作 将数据从一个 activity 发送到另一个 activity; 甚至跨进程边界。你需要指定 数据及其类型。系统会自动识别兼容的 activity 可接收数据并显示给用户的容器对于 intent 解析器, 如果只有一个 activity 可以处理 intent,则该 activity 会立即启动。

为什么要使用 Android Sharesheet

我们强烈建议您使用 Android Sharesheet 确保用户在各个 。不要显示应用自己的共享目标列表,也不要自行创建共享目标列表 Sharesheet 变体。

通过 Android Sharesheet,用户可以与 获取相关应用建议,而且只需点按一下。 Sharesheet 可以推荐自定义解决方案不可用的目标,并使用一致的排名。 这是因为,Sharesheet 可以将有关应用和用户活动的信息纳入考量 只供系统使用

Android Sharesheet 还为开发者提供了许多方便的功能。例如,您可以 执行以下操作:

使用 Android Sharesheet

对于所有类型的分享,请创建一个 intent 并将其操作设置为 Intent.ACTION_SEND。 要显示 Android Sharesheet,请调用 Intent.createChooser(), 向其传递 Intent 对象。 它会返回您的 intent 的一个版本,该版本始终显示 Android Sharesheet。

发送文本内容

Android Sharesheet 最直接和最常见的用途是从 从一个 activity 复制到另一个 activity。例如,大多数浏览器都可以将当前显示的 与另一个应用以文字形式显示网页。这对于通过 电子邮件或社交网络下面举例说明如何执行此操作:

Kotlin

val sendIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
    type = "text/plain"
}

val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)

Java

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");

Intent shareIntent = Intent.createChooser(sendIntent, null);
startActivity(shareIntent);

您还可以选择添加 extra 以包含更多信息,例如电子邮件收件人 (EXTRA_EMAILEXTRA_CC, EXTRA_BCC)、 电子邮件主题 (EXTRA_SUBJECT) 等

注意:某些电子邮件应用(如 Gmail)要求 String[]即可获享额外福利,例如: EXTRA_EMAILEXTRA_CC。使用 putExtra(String, String[]) 将它们添加到您的 intent 中。

发送二进制内容

您可以使用 ACTION_SEND 操作分享二进制数据。 请设置适当的 MIME 类型,并在 extra 中添加数据的 URI EXTRA_STREAM,以 如以下示例中所示。 这通常用于分享图片,但可以用于分享任何类型的二进制内容。

Kotlin

val shareIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    // Example: content://com.google.android.apps.photos.contentprovider/...
    putExtra(Intent.EXTRA_STREAM, uriToImage)
    type = "image/jpeg"
}
startActivity(Intent.createChooser(shareIntent, null))

Java

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
// Example: content://com.google.android.apps.photos.contentprovider/...
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, null));

接收方应用需要相关权限才能访问Uri中的数据 指向的页面。为此,建议您采用以下两种方法:

  • 将数据存储在您自己的 ContentProvider 中,确保其他 应用具有访问您的提供程序的正确权限。提供 即使用按 URI 的权限,也就是 并且仅向接收应用授予访问权限。轻松创建 ContentProvider 会使用 FileProvider 辅助类。
  • 使用系统 MediaStoreMediaStore 主要用于视频、音频和图片 MIME 类型。不过,从 Android 3.0 (API 级别 11),它还可以存储非媒体类型。如需了解详情,请参阅 MediaStore.Files。 您可以使用以下代码将文件插入 MediaStorescanFile(), 之后, content://样式的Uri 将适合共享的 onScanCompleted() 回调。请注意,将内容添加到系统 MediaStore 后, 任何应用

使用正确的 MIME 类型

提供最具体的 MIME 类型可用于您要查找的数据 发送。例如,在分享纯文本时使用 text/plain。以下是一些 在 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

<ph type="x-smartling-placeholder">

有关 MIME 类型的详情,请参阅 IANA 是 MIME 媒体类型的官方注册表。

Android Sharesheet 可能会显示内容预览,具体取决于提供的 MIME 类型。部分 预览功能仅适用于特定类型。

分享多份内容

如需分享多份内容,请使用 ACTION_SEND_MULTIPLE 操作以及指向相应内容的 URI 列表。MIME 类型根据 各种内容组合例如,如果您分享三张 JPEG 图片,则可以使用类型 "image/jpg"。对于混合的图片类型,请使用 "image/*" 来匹配 用于处理任何类型的图片的 activity。虽然您可以分享多种类型的内容,但我们强烈建议 我们不建议这样做 接收者不清楚发送的内容如果需要发送多种类型的内容,请使用 "*/*"。由接收应用解析 和处理您的数据示例如下:

Kotlin

val imageUris: ArrayList<Uri> = arrayListOf(
        // Add your image URIs here
        imageUri1,
        imageUri2
)

val shareIntent = Intent().apply {
    action = Intent.ACTION_SEND_MULTIPLE
    putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris)
    type = "image/*"
}
startActivity(Intent.createChooser(shareIntent, null))

Java

ArrayList<Uri> imageUris = new ArrayList<Uri>();
imageUris.add(imageUri1); // Add your image URIs here
imageUris.add(imageUri2);

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, null));

确保提供的 Uri 对象指向 接收应用可以访问的数据

向文本预览添加富媒体内容

从 Android 10(API 级别 29)开始,Android Sharesheet 会显示 共享。在某些情况下,分享的文本可能难以理解。您可以考虑共享 复杂网址,例如 https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4。更丰富的 预览功能可确保用户安心分享的内容。

如需预览文本,您可以设置标题和/或缩略图。将说明添加到 Intent.EXTRA_TITLE,然后在调用 Intent.createChooser() 之前添加 相关缩略图,并使用 ClipData

注意:图片内容 URI 是由 FileProvider,通常来自配置的 <cache-path>。 如需了解详情,请参阅共享文件。请务必为 Sharesheet 提供适当的权限,以便读取您要用作缩略图的任何图片。如需更多信息 请参阅 Intent.FLAG_GRANT_READ_URI_PERMISSION

示例如下:

Kotlin

 val share = Intent.createChooser(Intent().apply {
      action = Intent.ACTION_SEND
      putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/")

      // (Optional) Here you're setting the title of the content
      putExtra(Intent.EXTRA_TITLE, "Introducing content previews")

      // (Optional) Here you're passing a content URI to an image to be displayed
      data = contentUri
      flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
  }, null)
  startActivity(share)

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/");

// (Optional) Here you're setting the title of the content
sendIntent.putExtra(Intent.EXTRA_TITLE, "Introducing content previews");

// (Optional) Here you're passing a content URI to an image to be displayed
sendIntent.setData(contentUri);
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

// Show the Sharesheet
startActivity(Intent.createChooser(sendIntent, null));

预览如下所示:

向 Sharesheet 添加自定义操作

Android Sharesheet 上的自定义操作的屏幕截图。

在 Android 14(API 级别 34)及更高版本中,应用可以向 Android Sharesheet 添加自定义操作。 自定义操作以小操作图标的形式显示在 Android Sharesheet 顶部,应用 可以将任何 Intent 指定为点击图标时调用的操作。

要在 Android Sharesheet 上添加自定义操作,请先创建一个 ChooserAction 替换为 ChooserAction.Builder。 您可以将 PendingIntent 指定为点击图标时调用的操作。创建 一个包含所有自定义操作的数组,并将其指定为 EXTRA_CHOOSER_CUSTOM_ACTIONS 份额 Intent

Kotlin

val sendIntent = Intent(Intent.ACTION_SEND)
    .setType("text/plain")
    .putExtra(Intent.EXTRA_TEXT, text)
val shareIntent = Intent.createChooser(sendIntent, null)
val customActions = arrayOf(
    ChooserAction.Builder(
        Icon.createWithResource(context, R.drawable.ic_custom_action),
        "Custom",
        PendingIntent.getBroadcast(
            context,
            1,
            Intent(Intent.ACTION_VIEW),
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
        )
    ).build()
)
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions)
context.startActivity(shareIntent)

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND)
        .setType("text.plain")
        .putExtra(Intent.EXTRA_TEXT, text);
Intent shareIntent = Intent.createChooser(sendIntent, null);
ChooserAction[] actions = new ChooserAction[]{
        new ChooserAction.Builder(
                Icon.createWithResource(context, R.drawable.ic_custom_action),
                "Custom",
                PendingIntent.getBroadcast(
                        context,
                        1,
                        new Intent(Intent.ACTION_VIEW),
                        PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT
                )
        ).build()
};
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions);
context.startActivity(shareIntent);

添加自定义目标

借助 Android Sharesheet,您最多可以指定两个 ChooserTarget 对象, 在从 ChooserTargetServices 加载的共享快捷方式和选择器目标之前显示。您还可以 最多指定两个指向列出的 activity 的 intent 在应用建议之前:

Intent.EXTRA_CHOOSER_TARGETSIntent.EXTRA_INITIAL_INTENTS 添加到 调用之后的共享 intent Intent.createChooser():

Kotlin

val share = Intent.createChooser(myShareIntent, null).apply {
    putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray)
    putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray)
}

Java

Intent shareIntent = Intent.createChooser(sendIntent, null);
share.putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray);
share.putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray);

请谨慎使用此功能。每个自定义Intent 而您添加的 ChooserTarget 会减少系统推荐的数量。通常情况下,我们 不建议添加自定义目标在容器中添加 Intent.EXTRA_INITIAL_INTENTS 用于提供用户可对共享项目执行的其他操作 内容。例如,当用户分享图片时,Intent.EXTRA_INITIAL_INTENTS 用于 让他们改为发送链接适当添加 Intent.EXTRA_CHOOSER_TARGETS 的示例 就是向与您相关的用户或设备展示您的应用。

按组件排除特定目标

您可以通过提供 Intent.EXTRA_EXCLUDE_COMPONENTS 排除特定目标。 此操作仅适用于移除您可以控制的定位条件。一个常见的用例是隐藏 用户从您的应用内分享时,应用的分享目标,因为他们很可能分享 。

调用 Intent.createChooser() 后,将 Intent.EXTRA_EXCLUDE_COMPONENTS 添加到您的 intent:

Kotlin

  val share = Intent.createChooser(Intent(), null).apply {
    // Only use for components you have control over
    val excludedComponentNames = arrayOf(ComponentName("com.example.android", "ExampleClass"))
    putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames)
  }

Java

  Intent shareIntent = Intent.createChooser(new Intent(), null);
  // Only use for components you have control over
  ComponentName[] excludedComponentNames = {
          new ComponentName("com.example.android", "ExampleClass")
  };
  shareIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames);

获取有关共享的信息

了解用户何时共享内容以及他们选择的目标可能很有用。通过 借助 Android Sharesheet,您可以通过提供 ComponentName 使用 IntentSender 定位您的用户选择的定位条件。

首先,为 BroadcastReceiver 创建一个 PendingIntent,并提供其 Intent.createChooser() 中的 IntentSender

Kotlin

var share = Intent(Intent.ACTION_SEND)
// ...
val pi = PendingIntent.getBroadcast(
    myContext, requestCode,
    Intent(myContext, MyBroadcastReceiver::class.java),
    PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
share = Intent.createChooser(share, null, pi.intentSender)

Java

Intent share = new Intent(ACTION_SEND);
...
PendingIntent pi = PendingIntent.getBroadcast(myContext, requestCode,
        new Intent(myContext, MyBroadcastReceiver.class),
        PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
share = Intent.createChooser(share, null, pi.getIntentSender());

MyBroadcastReceiver 中接收回调并查找 Intent.EXTRA_CHOSEN_COMPONENT

Kotlin

override fun onReceive(context: Context, intent: Intent) {
  ...
  val clickedComponent : ComponentName = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}

Java

@Override public void onReceive(Context context, Intent intent) {
  ...
  ComponentName clickedComponent = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}

向 Sharesheet 添加自定义操作

在 Android 14(API 级别 34)及更高版本中,应用可以向 Android Sharesheet 添加自定义操作。 创建 ChooserAction 替换为 ChooserAction.Builder。 您可以将 PendingIntent 指定为点击图标时调用的操作。创建 一个包含所有自定义操作的数组,并将其指定为 EXTRA_CHOOSER_CUSTOM_ACTIONS 份额 Intent

Kotlin

val sendIntent = Intent(Intent.ACTION_SEND)
    .setType("text/plain")
    .putExtra(Intent.EXTRA_TEXT, text)
val shareIntent = Intent.createChooser(sendIntent, null)
val customActions = arrayOf(
    ChooserAction.Builder(
        Icon.createWithResource(context, R.drawable.ic_custom_action),
        "Custom",
        PendingIntent.getBroadcast(
            context,
            1,
            Intent(Intent.ACTION_VIEW),
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
        )
    ).build()
)
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions)
context.startActivity(shareIntent)

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND)
        .setType("text.plain")
        .putExtra(Intent.EXTRA_TEXT, text);
Intent shareIntent = Intent.createChooser(sendIntent, null);
ChooserAction[] actions = new ChooserAction[]{
        new ChooserAction.Builder(
                Icon.createWithResource(context, R.drawable.ic_custom_action),
                "Custom",
                PendingIntent.getBroadcast(
                        context,
                        1,
                        new Intent(Intent.ACTION_VIEW),
                        PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT
                )
        ).build()
};
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions);
context.startActivity(shareIntent);

使用 Android intent 解析器

ACTION_SEND intent 解析器的屏幕截图。

在明确定义的任务流中将数据发送到另一个应用时,使用 Android intent 解析器最为合适。

如需使用 Android intent 解析器,请创建一个 intent 并添加 extra,就像调用 Android Sharesheet。但是,请勿调用 Intent.createChooser()

如果有多个已安装的应用具有匹配的过滤条件 ACTION_SEND 和 MIME 类型,系统会显示一个名为 intent 解析器的消除歧义对话框 让用户可以选择要分享的目标对象。如果单个应用 匹配。

下面举例说明如何使用 Android intent 解析器发送文本:

Kotlin

val sendIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
    type = "text/plain"
}
startActivity(sendIntent)

Java

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);

了解详情

如需详细了解如何发送数据,请参阅 intent 和 intent 过滤器