Как отправлять сообщения электронной почты из приложения Android?

Я пишу приложение для Android. Как я могу отправить электронное письмо от него?

Solutions Collecting From Web of "Как отправлять сообщения электронной почты из приложения 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") или выборщик покажет вам все (многие) приложения, которые поддерживают намерение отправки.

Я использую это с давних пор, и это кажется хорошим, никаких приложений, не связанных с электронной почтой. Еще один способ отправить адрес электронной почты для отправки:

 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, у которого были проблемы с открытием / сохранением прикрепленного файла журнала. На самом деле он просто не сохранял файл вообще, не жалуясь.

Я взглянул на один из исходных кодов этой почты и заметил, что вложение в файл журнала (понятно) message/rfc822 типа 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.

Затем он просматривает список доступных действий, которые отвечают за намерение протокола ICANN_SENDTO (только для почтовых приложений) и строит выбор на основе этого списка действий и первоначального намерения ACTION_SEND с правильным типом mime.

Еще одно преимущество заключается в том, что Skype больше не указан (что реагирует на тип mime rfc822).

Чтобы ПРОСТО ПОЛУЧИТЬ EMAIL APPS, чтобы решить ваши намерения, вам необходимо указать ACTION_SENDTO как Action и mailto как Data.

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

Найдите дополнительную информацию в документации разработчика .

Отправка электронной почты может осуществляться с помощью намерений, которые не требуют настройки. Но тогда это потребует взаимодействия с пользователем, и макет будет немного ограничен.

Построение и отправка более сложной электронной почты без участия пользователя влечет за собой создание собственного клиента. Первое, что Sun Java API для электронной почты недоступно. У меня был успех, используя библиотеку Apache Mime4j для создания электронной почты. Все они основаны на документах на nilvec .

Я решил эту проблему с помощью простых строк кода, как объясняет документация по 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() в конце не будет работать, и приложение не запустит почтовый клиент.

Это работает для меня. Согласно документации на 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); } } 

Если вы действительно хотите отправить электронное письмо из приложения без участия пользователя, вот отличный код, который я нашел в Интернете, и он работает как шарм:

http://www.jondev.net/articles/Sending_Emails_without_User_Intervention_(no_Intents)_in_Android

Просто попробуйте этот

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

Используйте это для отправки электронной почты …

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

Другое решение может быть

 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.

Вот как я это сделал. Приятно и просто.

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

Это покажет вам только клиентов электронной почты (а также 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(CardViewActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show(); } }