Android 利用 intent 及其关联的 extra 让用户快速分享信息, 轻松使用自己喜爱的应用
Android 为用户提供了两种在应用之间分享数据的方式:
- Android Sharesheet 主要用于将内容发送到应用外部和/或直接发送 另一个用户例如,将网址分享给朋友。
- Android intent 解析器最适合将数据传递到 明确任务的下一阶段。例如,在应用中打开 PDF 并允许用户 选择他们首选的观看器
构建 intent 时,您可以指定希望该 intent 执行的操作。
Android 使用 ACTION_SEND
操作
将数据从一个 activity 发送到另一个 activity;
甚至跨进程边界。你需要指定
数据及其类型。系统会自动识别兼容的 activity
可接收数据并显示给用户的容器对于 intent 解析器,
如果只有一个 activity 可以处理 intent,则该 activity 会立即启动。
为什么要使用 Android Sharesheet
![](https://developer.android.google.cn/static/images/training/sharing/sharesheet.png?authuser=9&hl=cs)
我们强烈建议您使用 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_EMAIL
、
EXTRA_CC
,
EXTRA_BCC
)、
电子邮件主题
(EXTRA_SUBJECT
) 等
注意:某些电子邮件应用(如 Gmail)要求
String[]
即可获享额外福利,例如:
EXTRA_EMAIL
和 EXTRA_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
辅助类。 - 使用系统
MediaStore
。MediaStore
主要用于视频、音频和图片 MIME 类型。不过,从 Android 3.0 (API 级别 11),它还可以存储非媒体类型。如需了解详情,请参阅MediaStore.Files
。 您可以使用以下代码将文件插入MediaStore
:scanFile()
, 之后,content://
样式的Uri
将适合共享的onScanCompleted()
回调。请注意,将内容添加到系统MediaStore
后, 任何应用
使用正确的 MIME 类型
提供最具体的 MIME 类型可用于您要查找的数据
发送。例如,在分享纯文本时使用 text/plain
。以下是一些
在 Android 中发送简单数据时的常见 MIME 类型:
接收方注册 | 发件人发送 |
---|---|
text/* |
|
`image/*` |
|
video/* |
|
支持的文件扩展名 | application/pdf |
有关 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));
预览如下所示:
![](https://developer.android.google.cn/static/images/training/sharing/sharing_content_preview.png?authuser=9&hl=cs)
向 Sharesheet 添加自定义操作
![](https://developer.android.google.cn/static/images/training/sharing/sharesheet_custom_actions.png?authuser=9&hl=cs)
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
在应用建议之前:
![](https://developer.android.google.cn/static/images/training/sharing/customshare.png?authuser=9&hl=cs)
将 Intent.EXTRA_CHOOSER_TARGETS
和 Intent.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 解析器
![](https://developer.android.google.cn/static/images/training/sharing/send_intent.png?authuser=9&hl=cs)
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 过滤器。