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

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。例如,大多数浏览器都可以将当前显示的 与另一个应用以文字形式显示网页。这对于通过 电子邮件或社交网络下面举例说明如何执行此操作:

KotlinJava
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)
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_EMAIL, EXTRA_CCEXTRA_BCC)、 电子邮件主题 (EXTRA_SUBJECT) 等

注意:某些电子邮件应用(如 Gmail)要求 String[],享受额外福利,例如: EXTRA_EMAILEXTRA_CC。使用 putExtra(String, String[]) 将这些添加到 intent。

发送二进制内容

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

KotlinJava
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))
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。可以使用 scanFile() 将文件插入 MediaStore,然后将适合分享的 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

如需详细了解 MIME 类型,请参阅 MIME 媒体类型的 IANA 官方注册表。

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

分享多份内容

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

KotlinJava
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))
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.createChooser() 之前,先向 Intent.EXTRA_TITLE 添加说明,然后使用 ClipData 添加相关缩略图。

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

示例如下:

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

KotlinJava
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)
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 加载的 ChooserTarget 之前显示。此外,您还可以指定最多两个指向在应用建议之前列出的 activity 的 intent:

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

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

请谨慎使用此功能。每添加一个自定义 IntentChooserTarget,系统推荐的次数就会相应地减少。我们通常不建议添加自定义目标。添加 Intent.EXTRA_INITIAL_INTENTS 的一个做法恰当的常见例子是为了提供用户可以对分享内容执行的其他操作。例如,当用户分享图片时,Intent.EXTRA_INITIAL_INTENTS 用于 让他们改为发送链接添加 Intent.EXTRA_CHOOSER_TARGETS 的一个做法恰当的常见例子是为了呈现您的应用提供的相关人员或设备。

按组件排除特定目标

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

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

KotlinJava
  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)
  }
  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,您可以通过提供用户使用 IntentSender 选择的目标的 ComponentName 来获取此类信息。

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

KotlinJava
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)
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:

KotlinJava
override fun onReceive(context: Context, intent: Intent) {
  ...
  val clickedComponent : ComponentName = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}
@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 指定为点击图标时调用的操作。创建一个包含所有自定义操作的数组,并将其指定为分享 IntentEXTRA_CHOOSER_CUSTOM_ACTIONS

KotlinJava
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)
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 解析器发送文本:

KotlinJava
val sendIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
    type = "text/plain"
}
startActivity(sendIntent)
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 过滤器