如何从我的 Android 应用程序发送电子邮件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2197741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:54:26  来源:igfitidea点击:

How to send emails from my Android application?

androidemail

提问by Rakesh

I am developing an application in Android. I don't know how to send an email from the application?

我正在 Android 中开发一个应用程序。我不知道如何从应用程序发送电子邮件?

回答by Jeremy Logan

The best (and easiest) way is to use an Intent:

最好(也是最简单)的方法是使用Intent

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

Otherwise you'll have to write your own client.

否则,您将不得不编写自己的客户端。

回答by Jeff S

Use .setType("message/rfc822")or the chooser will show you all of the (many) applications that support the send intent.

使用.setType("message/rfc822")或选择器将向您显示支持发送意图的所有(许多)应用程序。

回答by Randy Sugianto 'Yuku'

I've been using this since long time ago and it seems good, no non-email apps showing up. Just another way to send a send email intent:

我很久以前就一直在使用它,看起来不错,没有出现非电子邮件应用程序。发送发送电子邮件意图的另一种方式:

Intent intent = new Intent(Intent.ACTION_SENDTO); // it's not ACTION_SEND
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject of email");
intent.putExtra(Intent.EXTRA_TEXT, "Body of email");
intent.setData(Uri.parse("mailto:[email protected]")); // or just "mailto:" for blank
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // this will make such that when user returns to your app, your app is displayed, instead of the email app.
startActivity(intent);

回答by tiguchi

I was using something along the lines of the currently accepted answer in order to send emails with an attached binary error log file. GMail and K-9 send it just fine and it also arrives fine on my mail server. The only problem was my mail client of choice Thunderbird which had troubles with opening / saving the attached log file. In fact it simply didn't save the file at all without complaining.

我正在使用与当前接受的答案类似的东西,以便发送带有附加二进制错误日志文件的电子邮件。GMail 和 K-9 发送得很好,它也可以很好地到达我的邮件服务器。唯一的问题是我选择的 Thunderbird 邮件客户端无法打开/保存附加的日志文件。事实上,它根本没有在没有抱怨的情况下保存文件。

I took a look at one of these mail's source codes and noticed that the log file attachment had (understandably) the mime type message/rfc822. Of course that attachment is not an attached email. But Thunderbird cannot cope with that tiny error gracefully. So that was kind of a bummer.

我查看了其中一个邮件的源代码,并注意到日志文件附件(可以理解)具有 mime 类型message/rfc822. 当然,该附件不是附加的电子邮件。但是 Thunderbird 无法优雅地处理这个小错误。所以这有点令人失望。

After a bit of research and experimenting I came up with the following solution:

经过一番研究和试验,我想出了以下解决方案:

public Intent createEmailOnlyChooserIntent(Intent source,
    CharSequence chooserTitle) {
    Stack<Intent> intents = new Stack<Intent>();
    Intent i = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto",
            "[email protected]", null));
    List<ResolveInfo> activities = getPackageManager()
            .queryIntentActivities(i, 0);

    for(ResolveInfo ri : activities) {
        Intent target = new Intent(source);
        target.setPackage(ri.activityInfo.packageName);
        intents.add(target);
    }

    if(!intents.isEmpty()) {
        Intent chooserIntent = Intent.createChooser(intents.remove(0),
                chooserTitle);
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
                intents.toArray(new Parcelable[intents.size()]));

        return chooserIntent;
    } else {
        return Intent.createChooser(source, chooserTitle);
    }
}

It can be used as follows:

它可以按如下方式使用:

Intent i = new Intent(Intent.ACTION_SEND);
i.setType("*/*");
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(crashLogFile));
i.putExtra(Intent.EXTRA_EMAIL, new String[] {
    ANDROID_SUPPORT_EMAIL
});
i.putExtra(Intent.EXTRA_SUBJECT, "Crash report");
i.putExtra(Intent.EXTRA_TEXT, "Some crash report details");

startActivity(createEmailOnlyChooserIntent(i, "Send via email"));

As you can see, the createEmailOnlyChooserIntent method can be easily fed with the correct intent and the correct mime type.

如您所见, createEmailOnlyChooserIntent 方法可以轻松地提供正确的意图和正确的 mime 类型。

It then goes through the list of available activities that respond to an ACTION_SENDTO mailtoprotocol intent (which are email apps only) and constructs a chooser based on that list of activities and the original ACTION_SEND intent with the correct mime type.

然后它遍历响应 ACTION_SENDTOmailto协议意图(仅限电子邮件应用程序)的可用活动列表,并基于该活动列表和具有正确 mime 类型的原始 ACTION_SEND 意图构建选择器。

Another advantage is that Skype is not listed anymore (which happens to respond to the rfc822 mime type).

另一个优点是不再列出 Skype(恰好响应 rfc822 mime 类型)。

回答by wildzic

To JUST LET EMAIL APPSto resolve your intent you need to specify ACTION_SENDTO as Action and mailto as Data.

为了只是让电子邮件应用解决你的意图,你需要指定ACTION_SENDTO的行动和作为上一篇的数据。

private void sendEmail(){

    Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
    emailIntent.setData(Uri.parse("mailto:" + "[email protected]")); 
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, "My email's subject");
    emailIntent.putExtra(Intent.EXTRA_TEXT, "My email's body");

    try {
        startActivity(Intent.createChooser(emailIntent, "Send email using..."));
    } catch (android.content.ActivityNotFoundException ex) {
        Toast.makeText(Activity.this, "No email clients installed.", Toast.LENGTH_SHORT).show();
    }

}

回答by Pedro Varela

I solved this issue with simple lines of code as the android documentation explains.

正如android文档所解释的那样,我用简单的代码行解决了这个问题。

(https://developer.android.com/guide/components/intents-common.html#Email)

( https://developer.android.com/guide/components/intents-common.html#Email)

The most important is the flag: it is ACTION_SENDTO, and not ACTION_SEND

最重要的是标志:它是ACTION_SENDTO,而不是ACTION_SEND

The other important line is

另一条重要的线路是

intent.setData(Uri.parse("mailto:")); ***// only email apps should handle this***

By the way, if you send an empty Extra, the if()at the end won't work and the app won't launch the email client.

顺便说一句,如果您发送一个空的Extraif()最后将不起作用,该应用程序也不会启动电子邮件客户端。

According to Android documentation. If you want to ensure that your intent is handled only by an email app (and not other text messaging or social apps), then use the ACTION_SENDTOaction and include the "mailto:" data scheme. For example:

根据安卓文档。如果您想确保您的意图仅由电子邮件应用程序(而不是其他文本消息或社交应用程序)处理,请使用该ACTION_SENDTO操作并包含“ mailto:”数据方案。例如:

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

回答by Sam

The strategy of using .setType("message/rfc822")or ACTION_SENDseems to also match apps that aren't email clients, such as Android Beamand Bluetooth.

使用.setType("message/rfc822")ACTION_SEND似乎也匹配非电子邮件客户端的应用程序的策略,例如Android Beam蓝牙

Using ACTION_SENDTOand a mailto:URI seems to work perfectly, and is recommended in the developer documentation. However, if you do this on the official emulators and there aren't any email accounts set up (or there aren't any mail clients), you get the following error:

使用ACTION_SENDTOmailto:URI 似乎工作得很好,并且在开发人员文档中推荐使用。但是,如果您在官方模拟器上执行此操作并且没有设置任何电子邮件帐户(或没有任何邮件客户端),则会出现以下错误:

Unsupported action

That action is not currently supported.

不支持的操作

目前不支持该操作。

As shown below:

如下所示:

Unsupported action: That action is not currently supported.

Unsupported action: That action is not currently supported.

It turns out that the emulators resolve the intent to an activity called com.android.fallback.Fallback, which displays the above message. Apparently this is by design.

事实证明,模拟器将意图解析为名为 的活动com.android.fallback.Fallback,该活动显示上述消息。显然这是设计使然。

If you want your app to circumvent this so it also works correctly on the official emulators, you can check for it before trying to send the email:

如果您希望您的应用程序绕过这一点,以便它也能在官方模拟器上正常运行,您可以在尝试发送电子邮件之前检查它:

private void sendEmail() {
    Intent intent = new Intent(Intent.ACTION_SENDTO)
        .setData(new Uri.Builder().scheme("mailto").build())
        .putExtra(Intent.EXTRA_EMAIL, new String[]{ "John Smith <[email protected]>" })
        .putExtra(Intent.EXTRA_SUBJECT, "Email subject")
        .putExtra(Intent.EXTRA_TEXT, "Email body")
    ;

    ComponentName emailApp = intent.resolveActivity(getPackageManager());
    ComponentName unsupportedAction = ComponentName.unflattenFromString("com.android.fallback/.Fallback");
    if (emailApp != null && !emailApp.equals(unsupportedAction))
        try {
            // Needed to customise the chooser dialog title since it might default to "Share with"
            // Note that the chooser will still be skipped if only one app is matched
            Intent chooser = Intent.createChooser(intent, "Send email with");
            startActivity(chooser);
            return;
        }
        catch (ActivityNotFoundException ignored) {
        }

    Toast
        .makeText(this, "Couldn't find an email app and account", Toast.LENGTH_LONG)
        .show();
}

Find more info in the developer documentation.

开发人员文档中查找更多信息。

回答by Rene

Sending email can be done with Intents which will require no configuration. But then it will require user interaction and the layout will be a bit restricted.

发送电子邮件可以通过 Intent 完成,不需要配置。但是这将需要用户交互并且布局会受到一些限制。

Build and sending a more complex email without user interaction entails building your own client. The first thing is that the Sun Java API for email are unavailable. I have had success leveraging the Apache Mime4j library to build email. All based on the docs at nilvec.

在没有用户交互的情况下构建和发送更复杂的电子邮件需要构建您自己的客户端。首先是用于电子邮件的 Sun Java API 不可用。我已经成功地利用 Apache Mime4j 库构建电子邮件。全部基于nilvec的文档。

回答by Sridhar Nalam

Here is the sample working code which opens mail applicationin android device and auto-filled with To addressand Subjectin the composing mail.

这是示例工作代码,它在 android 设备中打开邮件应用程序并在撰写邮件中自动填充收件人地址主题

protected void sendEmail() {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:[email protected]"));
    intent.putExtra(Intent.EXTRA_SUBJECT, "Feedback");
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

回答by lomza

I use the below code in my apps. This shows exactly email client apps, such as Gmail.

我在我的应用程序中使用以下代码。这准确地显示了电子邮件客户端应用程序,例如 Gmail。

    Intent contactIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", getString(R.string.email_to), null));
    contactIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.email_subject));
    startActivity(Intent.createChooser(contactIntent, getString(R.string.email_chooser)));