如何通过意图打开电子邮件程序(但仅限电子邮件程序)

85

我想设置应用程序的一部分,允许用户向另一个用户发送快速电子邮件。这并不难设置:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, message);
Intent mailer = Intent.createChooser(intent, null);
startActivity(mailer);

然而,问题在于ACTION_SEND被更多应用程序所接受,例如在我的手机上,Facebook应用程序、Twitter、reddit is fun甚至是蓝牙都出现为发送此消息的可行替代方案。这条消息对某些应用程序来说完全太长了(尤其是Twitter)。

有没有办法仅限制于支持长消息(例如电子邮件)的应用程序来选择发送?还是有一种方法可以检测用户选择的应用程序并相应地调整消息?


2
我想知道Linkify类是如何决定打开哪个mailto链接的。也许可以检查Linkify的源代码,并发布你的发现。 - Pentium10
好的,我会查看一下并且如果发现有任何有趣的内容,会及时通知你。 - Dan Lew
再次感谢Pentium10,建议很好,可以查看Linkify的实现方式。 - Dan Lew
11个回答

100

感谢Pentium10的建议,在查找Linkify如何工作方面,我找到了一个很好的解决方案。基本上,你只需要创建一个"mailto:"链接,然后调用相应的Intent即可。

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.parse("mailto:?subject=" + subject + "&body=" + body);
intent.setData(data);
startActivity(intent);

这个解决方案有几个有趣的方面:

  1. 我使用了ACTION_VIEW操作,因为这对于“mailto:”链接更加合适。你也可以不提供任何特定的操作,但是那样可能会得到一些不令人满意的结果(例如,它会询问您是否要将链接添加到您的联系人中)。

  2. 由于这是一个“共享”链接,我只是没有包含电子邮件地址 - 即使这是一个mailto链接。它依然有效。

  3. 这里没有涉及chooser(选择器)。原因是让用户利用默认设置;如果他们设置了默认的电子邮件程序,那么它将直接跳转到该程序,完全跳过选择器(在我看来很好,但你可能会有不同的看法)。

当然,还有很多细节我没有讲到(如正确编码主题/正文),但您应该能够自己弄清楚。


从所有的解决方案中,这个对我起作用了。谢谢伙计 :) - Bora
2
我认为这是最好的方法,因为它不会显示Snapchat、Telegram和其他允许发送文本的应用程序。 - WuerfelDev
6
如有需要,您可以使用"&to"指定接收者。 - SpiralDev
不要忘记在mailto:后面写上电子邮件地址。 - Anuj

88

更改 MIME 类型是解决方法,这就是我在我的应用程序中更改相同行为的方式。我使用了 intent.setType("message/rfc822");


2
我不会假设每个电子邮件程序都支持该MIME类型。 - CommonsWare
2
在我的设备上它列出了Gmail,但也有“Drive”和“AndFTP”。 - Amir Uval
11
我会使用新的Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")); - Eric Cochran

29

这对我起了作用

Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.setType("vnd.android.cursor.item/email");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {"abc@xyz.com"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "My Email Subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "My email content");
startActivity(Intent.createChooser(emailIntent, "Send mail using..."));

1
运行得非常好。特别注意,Extra_Email 应该是字符串数组,否则 To: 将为空... - Nilesh

4
您尝试过包括Intent.EXTRA_EMAIL额外信息吗?
Intent mailer = new Intent(Intent.ACTION_SEND);
mailer.setType("text/plain");
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"name@email.com"});
mailer.putExtra(Intent.EXTRA_SUBJECT, subject);
mailer.putExtra(Intent.EXTRA_TEXT, bodyText);
startActivity(Intent.createChooser(mailer, "Send email..."));

这可能会限制可用的接收应用程序列表...

2
我已经尝试过了,没有帮助。在选择器中,额外的内容不用于过滤应用程序。 - Dan Lew
我认为唯一的其他解决方案是通过传递一个包含完整类/包路径的字符串来启动特定的邮件程序。这将限制您的用户只能使用一个邮件应用程序,但它将防止其他类型的应用程序(如 Twitter)成为选项... - user370382
1
我完全不喜欢那个想法,因为大多数用户一开始就会有两个默认的邮件应用程序(标准邮件应用程序和Gmail),而我不想猜测他们使用哪一个。 - Dan Lew
我有4个电子邮件客户端,几乎不用Gmail和Mail应用程序。 - Pentium10

3

对我来说,这些解决方案都没有起作用。感谢开源开发者cketti分享了他/她简洁而整洁的解决方案。

String mailto = "mailto:bob@example.org" +
    "?cc=" + "alice@example.com" +
    "&subject=" + Uri.encode(subject) +
    "&body=" + Uri.encode(bodyText);

Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse(mailto));

try {
  startActivity(emailIntent);
} catch (ActivityNotFoundException e) {
  //TODO: Handle case where no email app is available
}

这是他/她的gist链接:这里


1
使其工作并正确填写GMAIL字段的诀窍是添加一个带有空电子邮件的?cc=。 - FrizzTheSnail
@FrizzTheSnail非常感谢你!!!在努力让它工作后,这解决了问题! - Tgo1014
1
@Tgo1014 谢谢,点赞我的评论吧。这样其他开发者就更容易注意到它啦 ;) - FrizzTheSnail

3

试一试这个

Intent intent = new Intent("android.intent.action.SENDTO", Uri.fromParts("mailto", "yourmail@gmail.com", null));
intent.putExtra("android.intent.extra.SUBJECT", "Enter Subject Here");
startActivity(Intent.createChooser(intent, "Select an email client")); 

0

尝试将 MIME 类型从 plain 更改为 message

intent.setType("text/message");

0

我尝试了许多解决方案,但大多数都没有起作用。 它适用于Android 12。

Uri uri = Uri.parse("mailto:"+ "email@email.com" +"?subject="+ "Email Subject" +"&body="+ "Email Body");

            startActivity(new Intent(Intent.ACTION_VIEW, uri));

我已经尝试了Intent.ACTION_SEND和Intent.ACTION_SENDTO,但是在Android 12上都没有生效。


0

尝试这个选项:

Intent intentEmail = new Intent(Intent.ACTION_SEND);
intentEmail.setType("message/rfc822");

-1

这是一个小错误,因为您需要切换您的MIME类型:

intent.setType("plain/text"); //Instead of "text/plain"

2
据我所知,plain/text不是有效的MIME类型。你有参考资料吗? - Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接