通过Gmail发送电子邮件

27

我有一段代码用于发送电子邮件意图

Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_EMAIL,
                new String[] { to });
i.putExtra(Intent.EXTRA_SUBJECT, subject);
i.putExtra(Intent.EXTRA_TEXT, msg);
try {
    startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
    Toast.makeText(Start.this,
                    "There are no email clients installed.",
                    Toast.LENGTH_SHORT).show();
}

但是,当这个意图被触发时,我在列表中看到了很多条目,如短信应用程序、Gmail 应用程序、Facebook 应用程序等。

我该如何进行筛选,并仅启用 Gmail 应用程序(或仅启用电子邮件应用程序)?

6个回答

87

使用 android.content.Intent.ACTION_SENDTO (new Intent(Intent.ACTION_SENDTO);) 可以只获取电子邮件客户端的列表,不包括 Facebook 或其他应用程序。只有电子邮件客户端。

我建议你不要直接进入电子邮件应用程序,让用户选择他喜欢的电子邮件应用程序。

如果使用 ACTION_SENDTO,putExtra 不能用于向意图添加主题和文本。请使用 Uri 来添加主题和正文文本。

示例

Intent send = new Intent(Intent.ACTION_SENDTO);
String uriText = "mailto:" + Uri.encode("email@gmail.com") + 
          "?subject=" + Uri.encode("the subject") + 
          "&body=" + Uri.encode("the body of the message");
Uri uri = Uri.parse(uriText);

send.setData(uri);
startActivity(Intent.createChooser(send, "Send mail..."));

请告诉我如何添加一张图片?我尝试了 &attach=(imagefilepath),但好像不起作用! - Abhijit
7
当我使用ACTION_SENDTO时,意图选择器会显示“未安装应用程序以执行此意图”。我使用的是Android 4.1.2,已经安装了邮件应用程序... - ffleandro
当我从ACTION_SENT更改为ACTION_SENDTO时,我收到相同的消息。 - iRunner
在Android 6.0.1上表现良好。 - Andrey Luiz

21

被采纳的答案在4.1.2上不起作用。以下内容应该适用于所有平台:

Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
            "mailto","abc@gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "EXTRA_SUBJECT");
startActivity(Intent.createChooser(emailIntent, "Send email..."));

希望这能帮到你。

1
如果您不知道收件人的地址,就无法使用fromParts构建Uri,但是您必须使用Uri.parse("mailto:")并将其传递给Intent.setData。然后,如果除了主题之外还有一些正文文本,您可以使用Intent.EXTRA_TEXT将其与意图一起传递。 - Giulio Piancastelli
2
如果您不知道收件人的地址,只需在那里放置一个空字符串即可。我刚刚检查过,发现它正常工作。 - thanhbinh84
2
如果您这样做,PayPal应用程序将出现在选择器对话框中,这似乎只是想从我的顾客那里盗取一些钱而不是检索反馈:S请注意,这仅发生在PayPal应用程序的最新更新(大约一周前)。我们能阻止这种情况发生吗? - doplumi

15

Igor Popov的回答是100%正确的,但如果你想要一个备选方案,我使用以下方法:


Igor Popov的回答是正确的,但如果需要备选方案,我使用以下方法:
public static Intent createEmailIntent(final String toEmail, 
                                       final String subject, 
                                       final String message)
{
    Intent sendTo = new Intent(Intent.ACTION_SENDTO);
    String uriText = "mailto:" + Uri.encode(toEmail) +
            "?subject=" + Uri.encode(subject) +
            "&body=" + Uri.encode(message);
    Uri uri = Uri.parse(uriText);
    sendTo.setData(uri);

    List<ResolveInfo> resolveInfos = 
        getPackageManager().queryIntentActivities(sendTo, 0);

    // Emulators may not like this check...
    if (!resolveInfos.isEmpty())
    {
        return sendTo;
    }

    // Nothing resolves send to, so fallback to send...
    Intent send = new Intent(Intent.ACTION_SEND);

    send.setType("text/plain");
    send.putExtra(Intent.EXTRA_EMAIL,
               new String[] { toEmail });
    send.putExtra(Intent.EXTRA_SUBJECT, subject);
    send.putExtra(Intent.EXTRA_TEXT, message);

    return Intent.createChooser(send, "Your Title Here");
}

1
会尝试在我的应用程序中使用它。但是最后一行 - chooser -> createChooser。 - WindRider
我会更新我的回答,没有chooser方法,而是createChooser() - xbakesx
如果我想添加一个附件怎么办? - cmoaciopm
如果您只有一个解决方案,可以使用Intent.EXTRA_STREAM,如此处所示(尽管我不知道不同邮件应用程序对其的支持情况):https://dev59.com/E2035IYBdhLWcg3weP7f#11471489。这仅适用于单个附件。如果您有多个附件,则必须将其base64编码并放入正文中,然后从内容中链接到它。 - xbakesx

8

这是从Android官方文档中引用的内容,我已经在Android 4.4上测试过,完美运行。查看更多示例,请访问https://developer.android.com/guide/components/intents-common.html#Email

  public void composeEmail(String[] addresses, String subject) {
        Intent intent = new Intent(Intent.ACTION_SENDTO);
        intent.setData(Uri.parse("mailto:")); // only email apps should handle this
        intent.putExtra(Intent.EXTRA_EMAIL, addresses);
        intent.putExtra(Intent.EXTRA_SUBJECT, subject);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        }
    }

这并不能帮助处理附件。 - AmaJayJB

6

替换

i.setType("text/plain");

使用

// need this to prompts email client only
i.setType("message/rfc822");

1
使用 MIME 类型执行发送操作是一个坏主意,因为你基本上要求 Android 提供支持发送类型为“message/rfc822”的文件的应用程序列表。那不等同于发送邮件。相反,请使用“mailto:”协议,因为那才是实际理解的电子邮件客户端。 - Paul Lammertsma
1
是的,但是 "mailto:" 不支持附件。 - Ed Burnette
实际上,“mailto:”是否支持附件取决于邮件应用程序。例如,最新的“K9 Mail”支持使用带有附件的mailto。 - cmoaciopm
很不幸,使用mailto:时多个附件会导致Gmail崩溃。 :( - Learn OpenGL ES
已经找到了如何使用多个附件的方法:http://stackoverflow.com/questions/22240028/opening-an-email-with-multiple-attachments-while-restricting-the-chooser-to-onl - Learn OpenGL ES

-1
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
                    "mailto","opinions@gmail.com.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "IndiaTV News - Mobile App Feedback");
emailIntent.putExtra(Intent.EXTRA_TEXT,Html.fromHtml(Settings.this.getString(R.string.MailContent)));
startActivityForResult(Intent.createChooser(emailIntent, "Send email..."),0);

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