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


76

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

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很有趣,甚至蓝牙也成为发送此消息的可行选择。对于其中一些消息(特别是Twitter),消息完全太长。

有没有一种方法可以将选择器限制为仅支持长消息的应用程序(例如电子邮件)?还是有一种方法可以检测用户选择的应用并适当地调整消息?


2
我想知道Linkify类如何决定为mailto链接打开什么。也许检查Linkify的源代码,然后发表您的发现。
Pentium10'7

打个好电话-我会检查一下,让我知道是否感兴趣。
丹·卢

再次感谢Pentium10,关于查找Linkify的工作方式的很好建议。
丹·卢

Answers:


84

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


2
我不认为每个电子邮件程序都支持该MIME类型。
CommonsWare 2010年

2
在我的设备中,它列出了Gmail,还列出了“驱动器”和“ AndFTP”
Amir Uval,2013年

9
我使用新的Intent(Intent.ACTION_SENDTO,Uri.parse(“ mailto:”));
埃里克·科克伦

92

由于奔腾10建议搜索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. 没有选择器参与。这样做的原因是让用户利用默认值。如果他们已经设置了默认的电子邮件程序,那么它将直接带给他们,完全绕过选择器(在我看来,这似乎很好,您可能会反驳)。

当然,我遗漏了很多技巧(例如正确编码主题/身体),但是您应该能够自己弄清楚。


从周围的所有解决方案为我工作,谢谢伙伴:)
宝来2014年

2
这是imo最好的方法,因为它不显示允许文本发送的Snapchat,Telegram和其他应用
WuerfelDev

5
如果有人需要,可以使用“&to”指定接收器
SpiralDev

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应该在String数组中,否则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
我已经尝试过了,没有帮助。不使用其他功能来过滤选择器中的应用程序。
丹·卢

我认为唯一的解决方案是通过传递带有完整类/包路径的String来启动特定的邮件程序。这会将您的用户限制为一个Mail应用程序,但将阻止其他类型的应用程序(如Twitter)成为选择...
idolize 2010年

1
我根本不喜欢这个主意,因为大多数用户都将有两个默认的Mail应用程序开始(标准Mail应用程序和Gmail),并且我不想猜测他们使用哪个。
丹·卢

我有4个电子邮件客户端,几乎没有使用Gmail和邮件应用程序。
Pentium10'7

1

试试这个

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")); 

1

没有一个解决方案对我有用。感谢开源开发人员,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
}

是链接到他/她的要点。


这实际上是唯一可行的方法,我尝试了6种不同的解决方案。谢谢。
Code Wiget

0

尝试将MIME类型从普通更改为邮件

intent.setType("text/message");

0

这有点打错字,因为您需要切换您的模仿类型:

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

1
就我所知,plain/text这不是有效的MIME类型。您对此有参考吗?
托马斯


-1

仅发送给电子邮件客户-有多个附件

有很多解决方案,但全部都可以部分解决。

mailto可以正确过滤电子邮件应用程序,但是无法发送流/文件。

message / rfc822与电子邮件客户端一起打开应用程序的地狱

因此,解决方案是同时使用两者。

  1. 首先使用mailto intent解决intent活动
  2. 然后将数据设置为已解析的每个活动,以发送所需的数据
private void share()
{
     Intent queryIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
     Intent dataIntent  = getDataIntent();

     Intent targetIntent = getSelectiveIntentChooser(context, queryIntent, dataIntent);
     startActivityForResult(targetIntent);
}

建立所需的数据意图,其中填充了所需的数据以进行共享

private Intent getDataIntent()
{
        Intent dataIntent = buildIntent(Intent.ACTION_SEND, null, "message/rfc822", null);

        // Set subject
        dataIntent.putExtra(Intent.EXTRA_SUBJECT, title);

        //Set receipient list.
        dataIntent.putExtra(Intent.EXTRA_EMAIL, toRecipients);
        dataIntent.putExtra(Intent.EXTRA_CC, ccRecipients);
        dataIntent.putExtra(Intent.EXTRA_BCC, bccRecipients);
        if (hasAttachments())
        {
            ArrayList<Uri> uris = getAttachmentUriList();

            if (uris.size() > 1)
            {
                intent.setAction(Intent.ACTION_SEND_MULTIPLE);
                dataIntent.putExtra(Intent.EXTRA_STREAM, uris);
            }
            else
            {
                dataIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris.get(0));
            }
        }

        return dataIntent;
}

protected ArrayList<Uri> getAttachmentUriList()
{
        ArrayList<Uri> uris = new ArrayList();
        for (AttachmentInfo eachAttachment : attachments)
        {
            uris.add(eachAttachment.uri);
        }

        return uris;
}

实用程序类,用于基于查询意图过滤所需的意图

// Placed in IntentUtil.java
public static Intent getSelectiveIntentChooser(Context context, Intent queryIntent, Intent dataIntent)
{
        List<ResolveInfo> appList = context.getPackageManager().queryIntentActivities(queryIntent, PackageManager.MATCH_DEFAULT_ONLY);

        Intent finalIntent = null;

        if (!appList.isEmpty())
        {
            List<android.content.Intent> targetedIntents = new ArrayList<android.content.Intent>();

            for (ResolveInfo resolveInfo : appList)
            {
                String packageName = resolveInfo.activityInfo != null ? resolveInfo.activityInfo.packageName : null;

                Intent allowedIntent = new Intent(dataIntent);
                allowedIntent.setComponent(new ComponentName(packageName, resolveInfo.activityInfo.name));
                allowedIntent.setPackage(packageName);

                targetedIntents.add(allowedIntent);
            }

            if (!targetedIntents.isEmpty())
            {
                //Share Intent
                Intent startIntent = targetedIntents.remove(0);

                Intent chooserIntent = android.content.Intent.createChooser(startIntent, "");
                chooserIntent.putExtra(android.content.Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));
                chooserIntent.addFlags(android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION);

                finalIntent = chooserIntent;
            }

        }

        if (finalIntent == null) //As a fallback, we are using the sent data intent
        {
            finalIntent = dataIntent;
        }

        return finalIntent;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.