我正在开发一个 Android 应用程序。我不知道如何从应用程序发送电子邮件?
最好(也是最简单)的方法是使用 Intent
:
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL , new String[]{"recipient@example.com"});
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();
}
否则,您将不得不编写自己的客户端。
使用 .setType("message/rfc822")
或选择器将向您显示所有(许多)支持发送意图的应用程序。
message/rfc822
后我没有看到任何区别
我很久以前就一直在使用它,它看起来不错,没有出现非电子邮件应用程序。发送发送电子邮件意图的另一种方式:
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:default@example.com")); // 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);
我正在使用与当前接受的答案类似的东西来发送带有附加二进制错误日志文件的电子邮件。 GMail 和 K-9 可以很好地发送它,它也可以很好地到达我的邮件服务器。唯一的问题是我选择的邮件客户端 Thunderbird 无法打开/保存附加的日志文件。事实上,它根本没有在没有抱怨的情况下保存文件。
我查看了其中一封邮件的源代码,发现日志文件附件具有(可以理解的)mime 类型 message/rfc822
。当然,该附件不是附加的电子邮件。但是 Thunderbird 无法优雅地处理这个微小的错误。所以这有点令人失望。
经过一番研究和实验,我想出了以下解决方案:
public Intent createEmailOnlyChooserIntent(Intent source,
CharSequence chooserTitle) {
Stack<Intent> intents = new Stack<Intent>();
Intent i = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto",
"info@example.com", 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);
}
}
它可以按如下方式使用:
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"));
如您所见,createEmailOnlyChooserIntent 方法可以轻松地输入正确的意图和正确的 mime 类型。
然后,它会遍历响应 ACTION_SENDTO mailto
协议意图(仅限电子邮件应用程序)的可用活动列表,并根据该活动列表和具有正确 mime 类型的原始 ACTION_SEND 意图构建选择器。
另一个优点是不再列出 Skype(它恰好响应 rfc822 mime 类型)。
ACTION_SEND
,这很好地解决了问题。
File
实例,指向我的 Android 应用程序在后台创建的崩溃日志文件,以防出现未捕获的异常。该示例应仅说明如何添加电子邮件附件。您还可以附加外部存储中的任何其他文件(例如图像)。您还可以使用 crashLogFile
删除该行以获得一个工作示例。
要让电子邮件应用程序解决您的意图,您需要将 ACTION_SENDTO 指定为操作,将 mailto 指定为数据。
private void sendEmail(){
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto:" + "recipient@example.com")); // You can use "mailto:" if you don't know the address beforehand.
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();
}
}
解决方案很简单:android 文档对此进行了解释。
(https://developer.android.com/guide/components/intents-common.html#Email)
最重要的是标志:它是 ACTION_SENDTO
,而不是 ACTION_SEND
另一条重要的线是
intent.setData(Uri.parse("mailto:")); ***// only email apps should handle this***
顺便说一句,如果您发送一个空的 Extra
,最后的 if()
将不起作用,应用程序将不会启动电子邮件客户端。
根据安卓文档。如果您想确保您的意图仅由电子邮件应用程序(而不是其他短信或社交应用程序)处理,请使用 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);
}
}
使用 .setType("message/rfc822")
或 ACTION_SEND
的策略似乎也与非电子邮件客户端的应用相匹配,例如 Android Beam 和 Bluetooth。
使用 ACTION_SENDTO
和 mailto:
URI 似乎可以完美运行,并且 is recommended in the developer documentation。但是,如果您在官方模拟器上执行此操作并且没有设置任何电子邮件帐户(或没有任何邮件客户端),您会收到以下错误:
不支持的操作 当前不支持该操作。
如下所示:
https://i.stack.imgur.com/wcbFj.png
事实证明,模拟器将意图解析为名为 com.android.fallback.Fallback
的活动,该活动显示上述消息。 Apparently this is by design.
如果您希望您的应用程序规避这一点,以便它在官方模拟器上也能正常工作,您可以在尝试发送电子邮件之前检查它:
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 <johnsmith@yourdomain.com>" })
.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();
}
在 the developer documentation 中查找更多信息。
可以使用不需要配置的 Intent 发送电子邮件。但随后它将需要用户交互,并且布局会受到一些限制。
在没有用户交互的情况下构建和发送更复杂的电子邮件需要构建您自己的客户端。首先是用于电子邮件的 Sun Java API 不可用。我已经成功地利用 Apache Mime4j 库来构建电子邮件。全部基于 nilvec 的文档。
这是在 android 设备中打开邮件应用程序并在撰写邮件中自动填充收件人地址和主题的示例工作代码。
protected void sendEmail() {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:feedback@gmail.com"));
intent.putExtra(Intent.EXTRA_SUBJECT, "Feedback");
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
setData()
中设置了电子邮件,而 Avi 在 putExtra()
中设置。两种变体都有效。但如果删除 setData
并仅使用 intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"hi@example.com"});
,就会有 ActivityNotFoundException
。
我在我的应用程序中使用以下代码。这准确显示了电子邮件客户端应用程序,例如 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)));
这将只向您显示电子邮件客户端(以及出于某种未知原因的 PayPal)
public void composeEmail() {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"hi@example.com"});
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Body");
try {
startActivity(Intent.createChooser(intent, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(MainActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
}
intent.type = "message/rfc822"; intent.type = "text/html";
,否则会导致异常。
我就是这样做的。很好很简单。
String emailUrl = "mailto:email@example.com?subject=Subject Text&body=Body Text";
Intent request = new Intent(Intent.ACTION_VIEW);
request.setData(Uri.parse(emailUrl));
startActivity(request);
此功能首先直接使用意图 gmail 发送电子邮件,如果未找到 gmail,则提升意图选择器。我在许多商业应用程序中使用了这个功能,它工作正常。希望对您有所帮助:
public static void sentEmail(Context mContext, String[] addresses, String subject, String body) {
try {
Intent sendIntentGmail = new Intent(Intent.ACTION_VIEW);
sendIntentGmail.setType("plain/text");
sendIntentGmail.setData(Uri.parse(TextUtils.join(",", addresses)));
sendIntentGmail.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");
sendIntentGmail.putExtra(Intent.EXTRA_EMAIL, addresses);
if (subject != null) sendIntentGmail.putExtra(Intent.EXTRA_SUBJECT, subject);
if (body != null) sendIntentGmail.putExtra(Intent.EXTRA_TEXT, body);
mContext.startActivity(sendIntentGmail);
} catch (Exception e) {
//When Gmail App is not installed or disable
Intent sendIntentIfGmailFail = new Intent(Intent.ACTION_SEND);
sendIntentIfGmailFail.setType("*/*");
sendIntentIfGmailFail.putExtra(Intent.EXTRA_EMAIL, addresses);
if (subject != null) sendIntentIfGmailFail.putExtra(Intent.EXTRA_SUBJECT, subject);
if (body != null) sendIntentIfGmailFail.putExtra(Intent.EXTRA_TEXT, body);
if (sendIntentIfGmailFail.resolveActivity(mContext.getPackageManager()) != null) {
mContext.startActivity(sendIntentIfGmailFail);
}
}
}
我使用此代码通过直接启动默认邮件应用程序撰写部分来发送邮件。
Intent i = new Intent(Intent.ACTION_SENDTO);
i.setType("message/rfc822");
i.setData(Uri.parse("mailto:"));
i.putExtra(Intent.EXTRA_EMAIL , new String[]{"test@gmail.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "Subject");
i.putExtra(Intent.EXTRA_TEXT , "body of email");
try {
startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
简单试试这个
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonSend = (Button) findViewById(R.id.buttonSend);
textTo = (EditText) findViewById(R.id.editTextTo);
textSubject = (EditText) findViewById(R.id.editTextSubject);
textMessage = (EditText) findViewById(R.id.editTextMessage);
buttonSend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String to = textTo.getText().toString();
String subject = textSubject.getText().toString();
String message = textMessage.getText().toString();
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, new String[] { to });
// email.putExtra(Intent.EXTRA_CC, new String[]{ to});
// email.putExtra(Intent.EXTRA_BCC, new String[]{to});
email.putExtra(Intent.EXTRA_SUBJECT, subject);
email.putExtra(Intent.EXTRA_TEXT, message);
// need this to prompts email client only
email.setType("message/rfc822");
startActivity(Intent.createChooser(email, "Choose an Email client :"));
}
});
}
其他解决方案可以
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.setType("plain/text");
emailIntent.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"someone@gmail.com"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Yo");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Hi");
startActivity(emailIntent);
假设大多数 android 设备已经安装了 GMail 应用程序。
使用它发送电子邮件...
boolean success = EmailIntentBuilder.from(activity)
.to("support@example.org")
.cc("developer@example.org")
.subject("Error report")
.body(buildErrorReport())
.start();
使用构建等级:
compile 'de.cketti.mailto:email-intent-builder:1.0.0'
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto","ebgsoldier@gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Forgot Password");
emailIntent.putExtra(Intent.EXTRA_TEXT, "this is a text ");
startActivity(Intent.createChooser(emailIntent, "Send email..."));
这种方法对我有用。它打开 Gmail 应用程序(如果已安装)并设置 mailto。
public void openGmail(Activity activity) {
Intent emailIntent = new Intent(Intent.ACTION_VIEW);
emailIntent.setType("text/plain");
emailIntent.setType("message/rfc822");
emailIntent.setData(Uri.parse("mailto:"+activity.getString(R.string.mail_to)));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, activity.getString(R.string.app_name) + " - info ");
final PackageManager pm = activity.getPackageManager();
final List<ResolveInfo> matches = pm.queryIntentActivities(emailIntent, 0);
ResolveInfo best = null;
for (final ResolveInfo info : matches)
if (info.activityInfo.packageName.endsWith(".gm") || info.activityInfo.name.toLowerCase().contains("gmail"))
best = info;
if (best != null)
emailIntent.setClassName(best.activityInfo.packageName, best.activityInfo.name);
activity.startActivity(emailIntent);
}
/**
* Will start the chosen Email app
*
* @param context current component context.
* @param emails Emails you would like to send to.
* @param subject The subject that will be used in the Email app.
* @param forceGmail True - if you want to open Gmail app, False otherwise. If the Gmail
* app is not installed on this device a chooser will be shown.
*/
public static void sendEmail(Context context, String[] emails, String subject, boolean forceGmail) {
Intent i = new Intent(Intent.ACTION_SENDTO);
i.setData(Uri.parse("mailto:"));
i.putExtra(Intent.EXTRA_EMAIL, emails);
i.putExtra(Intent.EXTRA_SUBJECT, subject);
if (forceGmail && isPackageInstalled(context, "com.google.android.gm")) {
i.setPackage("com.google.android.gm");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
} else {
try {
context.startActivity(Intent.createChooser(i, "Send mail..."));
} catch (ActivityNotFoundException e) {
Toast.makeText(context, "No email app is installed on your device...", Toast.LENGTH_SHORT).show();
}
}
}
/**
* Check if the given app is installed on this devuice.
*
* @param context current component context.
* @param packageName The package name you would like to check.
* @return True if this package exist, otherwise False.
*/
public static boolean isPackageInstalled(@NonNull Context context, @NonNull String packageName) {
PackageManager pm = context.getPackageManager();
if (pm != null) {
try {
pm.getPackageInfo(packageName, 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
return false;
}
尝试这个:
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
}
上面的代码将打开用户最喜欢的电子邮件客户端,其中预先填充了准备发送的电子邮件。
以下代码适用于 Android 10 及更高版本的设备。它还设置主题、正文和收件人(收件人)。
val uri = Uri.parse("mailto:$EMAIL")
.buildUpon()
.appendQueryParameter("subject", "App Feedback")
.appendQueryParameter("body", "Body Text")
.appendQueryParameter("to", EMAIL)
.build()
val emailIntent = Intent(Intent.ACTION_SENDTO, uri)
startActivity(Intent.createChooser(emailIntent, "Select app"))
Kotlin 版本仅显示电子邮件客户端(无联系人等):
with(Intent(Intent.ACTION_SEND)) {
type = "message/rfc822"
data = Uri.parse("mailto:")
putExtra(Intent.EXTRA_EMAIL, arrayOf("user@example.com"))
putExtra(Intent.EXTRA_SUBJECT,"YOUR SUBJECT")
putExtra(Intent.EXTRA_TEXT, "YOUR BODY")
try {
startActivity(Intent.createChooser(this, "Send Email with"))
} catch (ex: ActivityNotFoundException) {
// No email clients found, might show Toast here
}
}
import androidx.core.app.ShareCompat
import androidx.core.content.IntentCompat
ShareCompat.IntentBuilder(this)
.setType("message/rfc822")
.setEmailTo(arrayOf(email))
.setStream(uri)
.setSubject(subject)
.setText(message + emailMessage)
.startChooser()
这是在 Android 上发送电子邮件的最简洁方式。
val intent = Intent(Intent.ACTION_SENDTO).apply {
data = Uri.parse("mailto:")
putExtra(Intent.EXTRA_EMAIL, arrayOf("email@example.com"))
putExtra(Intent.EXTRA_SUBJECT, "Subject")
putExtra(Intent.EXTRA_TEXT, "Email body")
}
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
您还需要在清单中(在您的应用程序标签之外)指定处理电子邮件的应用程序(mailto)的查询
<queries>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>
</queries>
如果您需要在电子邮件正文中发送 HTML 文本,请将“电子邮件正文”替换为您的电子邮件字符串,如下所示(请注意 Html.fromHtml 可能已弃用,这只是为了向您展示如何操作)
Html.fromHtml(
StringBuilder().append("<b>Hello world</b>").toString()
)
Intent i = new Intent(Intent.ACTION_SENDTO);
i.setType("message/rfc822");
i.setData(Uri.parse("mailto:"));