当我们需要在 Android 中发送电子邮件时,我们将使用 Intent.ACTION_SEND 调用注册的电子邮件应用程序,如下所示
Intent i = new Intent(Intent.ACTION_SEND);
startActivity(Intent.createChooser(i, "Send mail..."));
我的疑问是为什么我们需要在startActivity中使用Intent.createChooser而不是使用
startActivty(i)
。
使用Intent.createChooser()
有什么具体原因吗?
AFAIK,如果你使用
Intent.createChooser
,有三个区别:
您可以指定选择器对话框的标题以使其更加清晰。
即使用户选择了默认对话框,系统也会始终显示选择器对话框。
如果您通过
Intent.createChooser
创建的意图与任何活动都不匹配,系统仍会显示一个具有指定标题的对话框和错误消息No application can perform this action
。或者对于正常意图,您可能会收到 Android 运行时错误:Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent
选择器使用户能够选择默认邮件应用程序之外的其他邮件应用程序。如果您使用普通的 Gmail(私人)和电子邮件(与工作相关)并且您想选择哪一个,那么它非常有用。
应始终使用...
很旧的消息,但对于遇到它的其他人来说,您可以将 Intent 上的类型设置为电子邮件的 mime 类型,这至少会将其限制为可以发送适当类型消息的应用程序:
Intent i = new Intent(Intent.ACTION_SEND);
i.setType( "message/rfc822");
startActivity(Intent.createChooser(i, "Send mail..."));
使选择器对话框更加清晰。
如果您不使用
createChooser()
,系统仍将显示选择器对话框,除非用户已经表达了他们对使用哪个已安装程序来执行给定任务的决定(或者他们已经撤回了之前的决定)。
如果您确实使用
createChooser()
,系统将始终显示该对话框,即使已经明确表示了偏好。
所以,两者都是绝对正确的,您必须决定在任何特定情况下使用哪一个。您的情况可能会有所不同,但基本上,如果您提供文本、图像、视频或类似格式用于显示或编辑,您可能需要省略
createChooser()
,以便用户已经喜欢的任何内容都可以立即开始。另一方面,如果您希望每次共享您希望用户使用不同的已安装程序处理的内容(例如,发送电子邮件、Facebook、聊天等),您可能需要使用 createChooser()
来让您的用户可以轻松地进行选择。
我个人使用:
try {
startActivity(i);
} catch (ActivityNotFoundException e) {
startActivity(Intent.createChooser(i, null));
}
因此,如果用户有默认值,它将使用默认值,如果没有应用程序,将弹出“无应用程序”窗口。两个人都很开心。
来自文档
Android 为用户在应用程序之间共享数据提供了两种方式:
- Android Sharesheet 主要用于发送内容 在您的应用程序之外和/或直接发送给其他用户。例如,分享 一个朋友的网址。
- Android 意图解析器最适合 将数据传递到明确定义的任务的下一阶段。例如, 从您的应用程序中打开 PDF 并让用户选择他们喜欢的 观众。
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "Text to send.")
type = "text/plain"
}
// WILL start Android intent resolver
startActivity(sendIntent)
// WILL start Android ShareSheet
val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)
Android Sharesheet 有一些好处,例如它支持 DirectShare、Android 10 中带有复制选项的丰富预览(但有些设备甚至 Android > 10 也没有丰富预览)
//如果你想分享文字+网址
fun Context.createShareIntent(url: String, title: String? = null): Intent {
return ShareCompat.IntentBuilder(this).apply {
type = "text/plain"
val extraText = title?.let {
"$title\n\n$url"
} ?: url
setText(extraText)
}.intent
//如果你想分享图片+文字
fun Context.createShareIntent(url: String, title: String? = null, bitmap: Bitmap?): Intent {
return ShareCompat.IntentBuilder(this).apply {
setType("image/*")
val extraText = title?.let {
"$title\n\n$url"
} ?: url
// if you want to add image bitmap
bitmap?.let {
val uri = saveImageInQ(bitmap) // this is custom method to convert bitmap into image uri
setStream(uri)
}
setText(extraText)
}.intent