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_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));
预览如下所示:
向 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_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 解析器
在明确定义的任务流中将数据发送到另一个应用时,使用 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 过滤器。