Как я могу отправлять электронные письма из моего приложения Android?
Я пишу приложение для Android. Как я могу отправить письмо с него?
18 ответов
лучший (и самый простой) способ-это использовать 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")
или выбор покажет вам все (многие) приложения, которые поддерживают намерение отправки.
Я использую это с давних пор, и это кажется хорошим, никаких приложений без электронной почты не появляется. Еще один способ отправить сообщение по электронной почте:
Intent intent = new Intent(Intent.ACTION_SENDTO); // it's not ACTION_SEND
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject of email");
intent.putExtra(Intent.EXTRA_TEXT, "Body of email");
intent.setData(Uri.parse("mailto:default@recipient.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@domain.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
намерение протокола (которые являются только приложениями электронной почты) и создает выбор на основе этого списка действий и исходного намерения ACTION_SEND с правильным типом mime.
еще одно преимущество заключается в том, что Skype больше не указан (который реагирует на тип MIME rfc822).
до ПРОСТО ПУСТЬ ПРИЛОЖЕНИЯ ЭЛЕКТРОННОЙ ПОЧТЫ чтобы разрешить ваше намерение, вам нужно указать ACTION_SENDTO как действие и mailto как данные.
private void sendEmail(){
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto:" + "recipient@example.com"));
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();
}
}
стратегия использования .setType("message/rfc822")
или ACTION_SEND
похоже, также соответствуют приложениям, которые не являются почтовыми клиентами, такими как Android Beam и Bluetooth.
используя ACTION_SENDTO
и a mailto:
URI, кажется, работает отлично, и рекомендуется в документации разработчика. Однако, если вы сделаете это на официальных эмуляторах, и нет никаких учетных записей электронной почты (или нет никаких почтовых клиентов), вы получите следующую ошибку:
неподдерживаемые действия
, что в настоящее время не поддерживается.
как показано ниже:
оказывается, что эмуляторы разрешают намерение к действию под названием com.android.fallback.Fallback
, который отображает вышеуказанное сообщение. по-видимому, это намеренно.
если вы хотите, чтобы ваше приложение обойти это, так что он также работает правильно на официальных эмуляторах, вы можете проверить это, прежде чем пытаться отправить электронное письмо:
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();
}
найти более подробную информацию в разработчик документации.
я решил эту проблему с помощью простых строк кода, как объясняет документация 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
, the if()
в конце не будет работать, и приложение перестанет запускаться почтовый клиент.
согласно документации Android. Если вы хотите убедиться, что ваше намерение обрабатывается только приложением электронной почты (а не другими текстовыми сообщениями или социальными приложениями), используйте 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);
}
}
отправка электронной почты может быть выполнена с намерениями, которые не потребуют настройки. Но тогда это потребует взаимодействия с пользователем, и макет будет немного ограничен.
создание и отправка более сложной электронной почты без взаимодействия с пользователем влечет за собой создание собственного клиента. Во-первых, Sun Java API для электронной почты недоступны. У меня был успех, используя библиотеку Apache Mime4j для создания электронной почты. Все на основе документов в nilvec.
просто попробуй это
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 :"));
}
});
}
Я использую приведенный ниже код в своих приложениях. Это показывает именно клиентские приложения электронной почты, такие как 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)));
вот пример рабочего кода, который открывается почта в устройстве 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);
}
}
другое решение может быть
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();
используйте build gradle:
compile 'de.cketti.mailto:email-intent-builder:1.0.0'
эта функция сначала прямое намерение 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);
}
}
}
Это покажет вам только почтовые клиенты (а также 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();
}
}
вот как я это сделал. Просто и мило.
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 (если оно установлено) и устанавливает 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);
}
я использовал этот код для отправки почты, запустив раздел по умолчанию mail app compose напрямую.
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();
}