Отправить намерение по электронной почте

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/html");
intent.putExtra(Intent.EXTRA_EMAIL, "[email protected]");
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "I'm email body.");

startActivity(Intent.createChooser(intent, "Send Email"));

Приведенный выше код открывает диалоговое окно со следующими приложениями: - Bluetooth, Google Docs, Yahoo Mail, Gmail, Orkut, Skype и т. Д.

На самом деле, я хочу отфильтровать эти параметры списка. Я хочу показать только приложения, связанные с электронной почтой, например Gmail, Yahoo Mail. Как это сделать?

Я видел такой пример в приложении «Android Market».

  1. Откройте приложение Android Market
  2. Откройте любое приложение, в котором разработчик указал свой адрес электронной почты. (Если вы не можете найти такое приложение, просто откройте мое приложение: - market: // details? Id = com.becomputer06.vehicle.diary.free, ИЛИ выполните поиск по «Дневнику автомобиля»)
  3. Прокрутите вниз до "РАЗРАБОТЧИК".
  4. Нажмите "Отправить электронное письмо".

В диалоговом окне отображаются только приложения электронной почты, например Gmail, Yahoo Mail и т. Д. Он не показывает Bluetooth, Orkut и т. Д. Какой код создает такое диалоговое окно?


person dira    schedule 02.01.2012    source источник
comment
К сожалению, это невозможно с Intent.ACTION_SEND. Возможно, это работает с намерением непосредственно в gmail-приложении, но я не знаю, возможно ли это.   -  person Thommy    schedule 02.01.2012
comment
На случай, если кто-то узнает здесь о намерениях электронной почты, EXTRA_MAIL должен соответствовать String[], а не только String, как показано здесь.   -  person bigstones    schedule 16.08.2012
comment
возможный дубликат Отправить электронное письмо через gmail   -  person Sergey Glotov    schedule 25.09.2013
comment
Возможный дубликат Использование Android Intent.ACTION_SEND для отправки электронной почты   -  person Avi Parshan    schedule 03.02.2017
comment
Это не сработало для меня в 2020 году. Вот, если мое рабочее решение: stackoverflow.com/a/62877003/2155858   -  person Rajeev Jayaswal    schedule 19.12.2020


Ответы (36)


когда вы измените свой intent.setType, как показано ниже, вы получите

intent.setType("text/plain");

Используйте android.content.Intent.ACTION_SENDTO, чтобы получить только список клиентов электронной почты, без facebook или других приложений. Только почтовые клиенты. Бывший:

new Intent(Intent.ACTION_SENDTO);

Я бы не советовал вам сразу переходить к почтовому приложению. Позвольте пользователю выбрать свое любимое почтовое приложение. Не сдерживайте его.

Если вы используете ACTION_SENDTO, putExtra не работает для добавления темы и текста в намерение. Используйте Uri, чтобы добавить тему и основной текст.

РЕДАКТИРОВАТЬ: мы можем использовать message/rfc822 вместо "text/plain" в качестве типа MIME. Однако это не означает «предлагать только почтовые клиенты» - это означает «предлагать все, что поддерживает данные message / rfc822». Это может легко включать некоторые приложения, которые не являются почтовыми клиентами.

message/rfc822 поддерживает типы MIME .mhtml, .mht, .mime

person Padma Kumar    schedule 02.01.2012
comment
Не могли бы вы предоставить код для получения желаемого результата? - person dira; 02.01.2012
comment
@ becomputer06 ссылается на это: stackoverflow.com/questions/8284706/send-email-via-gmail - person Padma Kumar; 03.01.2012
comment
Выбор намерения говорит no apps installed to perform this intent, когда я использую ACTION_SENDTO. Я использую Android 4.1.2 и у меня установлено почтовое приложение ... - person ffleandro; 28.11.2012
comment
@ffleandro, вы вошли в почтовое приложение со своими учетными данными. - person Padma Kumar; 28.11.2012
comment
«Правильный» путь - это ответ Магнуса. Я рекомендую исходный плакат, чтобы изменить принятый ответ. - person jhabbott; 12.02.2013
comment
Использование типа MIME для выполнения операции отправки - плохая идея, потому что вы в основном инструктируете Android предоставить список приложений, которые поддерживают отправку файла типа message/rfc822. Это не то же самое, что отправка электронного письма. Вместо этого используйте протокол mailto:, потому что это то, что на самом деле понимают почтовые клиенты. - person Paul Lammertsma; 28.05.2013
comment
Ответ stackoverflow.com/a/16217921/5245903 ниже намного лучше и правильный ответ. - person Veneet Reddy; 26.01.2018
comment
сработало, но также необходимо добавить intent.setData (Uri.parse (mailto :)); - person Dev; 22.03.2018
comment
Это не сработало для меня в 2020 году, вот мое рабочее решение: stackoverflow.com/a/62877003/2155858 - person Rajeev Jayaswal; 19.12.2020

ОБНОВЛЕНИЕ

Официальный подход:

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

Ссылка

СТАРЫЙ ОТВЕТ

Принятый ответ не работает на 4.1.2. Это должно работать на всех платформах:

Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
            "mailto","[email protected]", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Body");
startActivity(Intent.createChooser(emailIntent, "Send email..."));

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

intent.putExtra(Intent.EXTRA_EMAIL, addresses); // String[] addresses
person thanhbinh84    schedule 22.02.2013
comment
Вы правы, и на 4.2 это тоже не так. Так что это на самом деле единственный правильный ответ, спасибо! - person mDroidd; 31.03.2013
comment
Это потрясающе. Кто-то ниже упомянул, что указание части mailto сужает доступные параметры для почтовых клиентов. Использование Uri.fromParts (mailto`` null) поместит курсор в поле получателя - идеально подходит для того, что мне нужно. - person Shaggy; 17.08.2013
comment
есть способ установить тело с этим? - person Malabarba; 31.08.2013
comment
Попробуйте этот emailIntent.putExtra (Intent.EXTRA_TEXT, я тело письма.); - person thanhbinh84; 01.09.2013
comment
В некоторых случаях это вызывало исключение: для вызова startActivity () из-за пределов контекста действия требуется флаг FLAG_ACTIVITY_NEW_TASK. Вы действительно этого хотите? Чтобы исправить это, по крайней мере, это работает: Intent chooser = Intent.createChooser(emailIntent, "Send email..."); chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(chooser); - person Jonik; 07.11.2013
comment
Если у вас нет конкретного получателя, это тоже работает: Uri.fromParts("mailto", "", null) - person Phil; 13.11.2013
comment
Можно ли прикрепить изображение? - person Arst; 20.10.2014
comment
Вы можете попробовать i.putExtra (Intent.EXTRA_STREAM, Uri.fromFile (pic)) и i.setType (image / png), но вам нужно проверить несколько версий ОС, так как у меня возникла проблема с прикреплением файлов txt, она работала на версия ОС, но будет отличаться от других - person thanhbinh84; 20.10.2014
comment
Почему у меня не работает? Я установил почтовые приложения. - person chenzhongpu; 23.10.2014
comment
Это больше не работает на моем Android 4.3. Ознакомьтесь с официальным документом Android об отправке электронной почты в качестве намерения, который отлично работает: developer.android.com/guide/components/ - person marcwjj; 13.04.2015
comment
Имейте в виду, что EXTRA_EMAIL всегда должен быть массивом String, а не String с одним адресом, потому что он будет проигнорирован. - person Roel; 17.09.2015
comment
Вам не следует создавать средство выбора, если вы хотите, чтобы пользователь отправлял электронное письмо прямо на адрес электронной почты по вашему выбору. Ref Вместо этого вы должны просто сделать startActivity(emailIntent) - person Jelmer Brands; 29.12.2017
comment
Привет. Спасибо за вашу помощь. - person H. Farid; 10.08.2019
comment
Это решение не работает с приложением GMX Mail. Это работало со всеми приложениями, которые я тестировал stackoverflow.com/a/17886006/1329901 - person Egis; 20.04.2020
comment
К сожалению, этот верный старый ответ больше не работает (в последних версиях Gmail?) - с этим кодом тема и тело теряются. На данный момент лучшим способом является подход 2 отсюда: medium.com/better-programming/ - person Jonik; 01.12.2020
comment
intent.resolveActivity() выдает предупреждение, см. Здесь: developer.android.com/training/package-visibility - person Izak; 07.04.2021
comment
Почему MailTo не отображается в Gmail в обновленном ответе? - person Ahmed Elsayed; 28.04.2021

Есть три основных подхода:

String email = /* Your email address here */
String subject = /* Your subject here */
String body = /* Your body here */
String chooserTitle = /* Your chooser title here */

1. Пользовательский Uri:

Uri uri = Uri.parse("mailto:" + email)
    .buildUpon()
    .appendQueryParameter("subject", subject)
    .appendQueryParameter("body", body)
    .build();

Intent emailIntent = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(Intent.createChooser(emailIntent, chooserTitle));

2. Использование Intent дополнительных услуг:

Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:" + email));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
//emailIntent.putExtra(Intent.EXTRA_HTML_TEXT, body); //If you are using HTML in your body text

startActivity(Intent.createChooser(emailIntent, "Chooser Title"));

3. Библиотека поддержки ShareCompat:

Activity activity = /* Your activity here */

ShareCompat.IntentBuilder.from(activity)
    .setType("message/rfc822")
    .addEmailTo(email)
    .setSubject(subject)
    .setText(body)
    //.setHtmlText(body) //If you are using HTML in your body text
    .setChooserTitle(chooserTitle)
    .startChooser();
person dira    schedule 25.04.2013
comment
Это сработало для меня намного лучше - другие варианты выскочили несколько простых вещей (например, Skype) в качестве возможных обработчиков. - person Chris Rae; 09.07.2013
comment
Если у вас есть символ % в буфере, некоторые символы в полученном электронном письме не будут правильно закодированы. Вам нужно исполнить Uri.encode танец, предложенный @minipif. - person Giulio Piancastelli; 02.08.2013
comment
Это лучшие ответы, не тратьте время на попытки других, второй - это то, что я выбрал, и он отлично работает, показывая только чистые почтовые приложения, а не gDrive, не bluetooth ... и т. Д. Спасибо @ becomputer06 - person Hugo; 10.11.2014
comment
Будьте осторожны с персонажем &. Если у вас есть символ & в теле письма, этот метод отрежет тело после &. Например, если вы отправите тело, как я, и образец тела, вы получите только я. - person Emre Koç; 19.10.2015
comment
Для SENDTO (и использования URI.encode, если это важно) мой телефон не показывает никаких приложений для обработки намерения. На SEND он показывает Gmail и многое другое. - person Zelphir Kaltstahl; 28.01.2016
comment
Прекрасный ответ. Я хорошо знал первых двух, но узнал кое-что новое, особенно последний; о ShareCompat! Спасибо - person sud007; 04.06.2016
comment
ShareCompat работает почти во всех приложениях, а не только в почтовых клиентах! - person rpattabi; 22.06.2016
comment
@Zelphir - это случилось и со мной. И ни один из этих ответов не касается вложений. - person Kristy Welsh; 22.12.2016
comment
Подход №2 работает правильно и соответствует документации. Если у вас нет вложений, то это правильно. Одна вещь - вы можете не включать электронные письма recpieints в оператор Uri.parse и передавать их в дополнениях намерения, способ сделать это здесь: developer.android.com/guide/components/ - person Kirill Starostin; 21.02.2019
comment
Третий вариант с .setType("message/rfc822") дает мне слишком много нерелевантных опций в диалоговом окне Chooser (Android 8.1). Старый добрый подход Intent.ACTION_SENDTO работает лучше всего! - person Kirill Karmazin; 01.04.2019
comment
На Huawei P10: вариант 1 работает, но варианты 2 и 3 приводят к тому, что поля темы и тела не заполняются предварительно, когда выбран gmail. - person Carmen; 07.10.2019
comment
В последних версиях Android (т.е.10) работает только пользовательский метод URI. - person Tushar Bapte; 21.12.2019
comment
Первый подход не сработает, поскольку appendQueryParameter удалит часть получателя. Подробнее здесь: stackoverflow.com/a/12035226/485986 - person jpmcosta; 08.01.2020

Это цитируется из официального документа Android, я тестировал его на Android 4.4 и отлично работает. Дополнительные примеры см. На странице https://developer.android.com/guide/components/intents-common.html#Email

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);
    }
}
person marcwjj    schedule 13.04.2015
comment
Согласовано! Я удивлен, что такой ответ находится так далеко в списке. Я предполагаю, что это должно быть относительно недавнее изменение в Android Docs. - person Mikey; 01.05.2015
comment
Большой! Надежный, он относился к «Библии» разработчиков приложений для Android. - person dev_android; 19.09.2015
comment
Двоеточие после mailto помогло мне! Я использовал mailto вместо mailto: - person Nigel Crasto; 17.03.2016
comment
Работает на 5.1.1. Остальные варианты мне не подходят. - person Juanin; 02.07.2016
comment
хорошее решение :) - person Abed Putra; 18.07.2017
comment
не работает правильно, и электронная почта, и данные темы не заполняются в приложении gmail - person Jonathan; 23.04.2018
comment
Это единственный рабочий ответ. Будьте осторожны при установке Intent.ACTION_SENDTO, Intent.ACTION_SEND не будет работать с mailto: - person Pelanes; 13.05.2018
comment
Согласно документам, только ACTION_SENDTO должен отображать только почтовые приложения, но он также не позволяет иметь вложения. Как придешь? Что делать, если я действительно хочу отправлять вложения, и я хочу отправлять только в приложения электронной почты? - person android developer; 22.08.2018
comment
EXTRA_EMAIL у меня не работает, поэтому я использовал Uri.parse("mailto: " + myEmail) - person Pratik Butani; 27.11.2018

Поздний ответ, хотя я нашел решение, которое могло бы помочь другим:

Версия Java

Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto:[email protected]"));
startActivity(Intent.createChooser(emailIntent, "Send feedback"));

Котлинская версия

val emailIntent = Intent(Intent.ACTION_SENDTO).apply { 
    data = Uri.parse("mailto:[email protected]")
}
startActivity(Intent.createChooser(emailIntent, "Send feedback"))

Это был мой результат (предлагается только Gmail + Inbox):

мой результат

Я получил это решение на сайте для разработчиков Android.

person capt.swag    schedule 03.02.2016
comment
Для меня было важно, чтобы между mailto и электронным письмом не было пробелов: mailto:[email protected] - person AlvaroSantisteban; 13.06.2018
comment
Отличное решение, у меня было такое же требование, большое спасибо. !!!! - person Gyan Swaroop Awasthi; 18.06.2020
comment
Отличное решение. Было бы здорово, если бы вы могли показать, как добавить тему и тело. - person Houman; 01.11.2020

Это работает для меня:

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_EMAIL  , new String[] { "[email protected]" });
intent.putExtra(Intent.EXTRA_SUBJECT, "My subject");

startActivity(Intent.createChooser(intent, "Email via..."));

т.е. используйте действие ACTION_SENDTO, а не действие ACTION_SEND. Я пробовал его на нескольких устройствах Android 4.4, и он ограничивает всплывающее окно выбора только отображением почтовых приложений (электронная почта, Gmail, Yahoo Mail и т. Д.), И он правильно вставляет адрес электронной почты и тему в электронное письмо.

person Adil Hussain    schedule 24.01.2015

Пытаться:

intent.setType("message/rfc822");
person Magnus    schedule 03.01.2012
comment
Он прав, я попробовал и предлагает [Диск, электронная почта, Gmail, Skype], это должен быть правильный ответ - person gurbieta; 17.11.2012
comment
Использование типа MIME для выполнения операции отправки - плохая идея, потому что вы в основном инструктируете Android предоставить список приложений, которые поддерживают отправку файла типа message/rfc822. Это не то же самое, что отправка электронного письма. Вместо этого используйте протокол mailto:, потому что это то, что на самом деле понимают почтовые клиенты. - person Paul Lammertsma; 28.05.2013

Это правильный способ отправки сообщения электронной почты в соответствии с Android Официальная документация разработчика

Добавьте эти строки кода в свое приложение:

Intent intent = new Intent(Intent.ACTION_SEND);//common intent 
intent.setData(Uri.parse("mailto:")); // only email apps should handle this

Необязательно: добавьте текст и тему, как это

intent.putExtra(Intent.EXTRA_SUBJECT, "Your Subject Here");
intent.putExtra(Intent.EXTRA_TEXT, "E-mail body" );

Вы уже добавили эту строку в свой вопрос

intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"[email protected]"});

Это будет адрес получателя, то есть пользователь отправит вам (разработчику) электронное письмо.

person Avi Parshan    schedule 05.06.2015
comment
@ barnacle.m Спасибо! Это также один из самых простых способов. Проблема в том, что мой ответ не набирает достаточно голосов :( - person Avi Parshan; 01.03.2018
comment
Это потому, что есть много похожих ответов, но этот указывает на официальную документацию Android по этому вопросу. - person barnacle.m; 01.03.2018
comment
Мне не удалось отправить адрес электронной почты. Я исправил это так: intent.data = Uri.parse (mailto: [email protected]) - person Hitesh Bisht; 11.01.2020
comment
Это не сработало, пока я не изменил Intent.ACTION_SEND на Intent.ACTION_SENDTO. - person Westy92; 07.10.2020
comment
Я всегда забываю, что значение Intent.EXTRA_EMAIL должно быть массивом, иначе оно не будет заполнять поле To в почтовом клиенте (по крайней мере, клиент приложения Gmail, в любом случае, не тестировал другие) - person ProjectDelta; 05.12.2020

Наконец-то придумал лучший способ сделать

String to = "[email protected]";
String subject= "Hi I am subject";
String body="Hi I am test body";
String mailTo = "mailto:" + to +
        "?&subject=" + Uri.encode(subject) +
        "&body=" + Uri.encode(body);
Intent emailIntent = new Intent(Intent.ACTION_VIEW);
emailIntent.setData(Uri.parse(mailTo));
startActivity(emailIntent);
person Ajay Shrestha    schedule 19.06.2017
comment
Ты классный, чувак. - person Ashik; 08.09.2017
comment
Нет проблем, чувак - person Ajay Shrestha; 08.09.2017
comment
Отлично работает. - person Solanki Kamlesh; 03.04.2019
comment
Единственное решение, которое работает и открывает почтовые приложения :) - person Umair; 01.07.2020
comment
Этот ответ должен быть вверху - person Emmanuel Njorodongo; 11.06.2021

Если вам нужны только почтовые клиенты, вы должны использовать android.content.Intent.EXTRA_EMAIL с массивом. Вот пример:

final Intent result = new Intent(android.content.Intent.ACTION_SEND);
result.setType("plain/text");
result.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { recipient });
result.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
result.putExtra(android.content.Intent.EXTRA_TEXT, body);
person Addev    schedule 17.02.2014
comment
нет, по-прежнему вызывает множество других приложений - намного больше, чем ACTION_SENDTO - person Dori; 11.06.2014

Работает на всех версиях Android:

String[] TO = {"[email protected]"};
    Uri uri = Uri.parse("mailto:[email protected]")
            .buildUpon()
            .appendQueryParameter("subject", "subject")
            .appendQueryParameter("body", "body")
            .build();
    Intent emailIntent = new Intent(Intent.ACTION_SENDTO, uri);
    emailIntent.putExtra(Intent.EXTRA_EMAIL, TO);
    startActivity(Intent.createChooser(emailIntent, "Send mail..."));

обновлен для android 10, теперь на kotlin.

fun Context.sendEmail(adress:String?,subject:String?,body:String?){
val TO = arrayOf(adress)
val uri = Uri.parse(adress)
    .buildUpon()
    .appendQueryParameter("subject", subject)
    .appendQueryParameter("body", body)
    .build()
val emailIntent = Intent(Intent.ACTION_SENDTO, uri)
emailIntent.setData(Uri.parse("mailto:$adress"));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
emailIntent.putExtra(Intent.EXTRA_EMAIL, TO)
ContextCompat.startActivity(this,Intent.createChooser(emailIntent, "Send 
mail..."),null)
}

после обновления до API 30 код не заполнял тему и тело почтового клиента, например gmail, нашел ответ здесь

fun Context.sendEmail(adress: String?, subject: String?, body: String?){

val selectorIntent = Intent(Intent.ACTION_SENDTO)
selectorIntent.data = Uri.parse("mailto:")

val emailIntent = Intent(Intent.ACTION_SEND)
emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(adress))
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject)
emailIntent.putExtra(Intent.EXTRA_TEXT, body)
emailIntent.selector = selectorIntent

startActivity(Intent.createChooser(emailIntent,
getString(R.string.send_email))) 

}
person Usama Saeed US    schedule 21.03.2016
comment
Ваш ответ мне помог. Спасибо - person Adnan Khan; 05.10.2016
comment
блин почта не принимается / пуста от gmail в java версии. - person larsaars; 30.09.2020
comment
не используйте устаревшую версию java. добавлено новое для поддержки всех версий Android. - person Usama Saeed US; 01.10.2020

Следующий код мне подходит.

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"abc@gmailcom"});
Intent mailer = Intent.createChooser(intent, null);
startActivity(mailer);
person Anam Ansari    schedule 23.10.2013

Изменить: больше не работает с новыми версиями Gmail

Это был единственный способ, который я нашел в то время, чтобы заставить его работать с любыми персонажами.

Ответ doreamon - правильный путь, поскольку он работает со всеми символами в новых версиях Gmail.

Старый ответ:


Вот мой. Кажется, он работает на всех версиях Android, с поддержкой темы и тела сообщения, а также полной поддержкой символов utf-8:

public static void email(Context context, String to, String subject, String body) {
    StringBuilder builder = new StringBuilder("mailto:" + Uri.encode(to));
    if (subject != null) {
        builder.append("?subject=" + Uri.encode(Uri.encode(subject)));
        if (body != null) {
            builder.append("&body=" + Uri.encode(Uri.encode(body)));
        }
    }
    String uri = builder.toString();
    Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(uri));
    context.startActivity(intent);
}
person minipif    schedule 26.07.2013
comment
+1 Uri.encode - правильный путь. Но зачем называть это дважды для темы и тела? - person Giulio Piancastelli; 02.08.2013
comment
Так что делать кодирование самостоятельно - плохая идея. Лучше использовать правильное намерение с необходимыми дополнениями, см., Например, stackoverflow.com/a/15022222 - person Giulio Piancastelli; 02.08.2013
comment
Для меня это лучший ответ, потому что другие решения корректно работают только с некоторыми почтовыми приложениями. Этот работает с каждым почтовым приложением, которое я тестировал. - person Egis; 20.04.2020

Из документации для разработчиков Android:

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);
    }
}
person marvatron    schedule 08.01.2019

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

Intent emailIntent = new Intent(Intent.ACTION_SENDTO,
                                Uri.parse("mailto:" + Uri.encode(address)));

emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
startActivity(Intent.createChooser(emailIntent, "Send email via..."));
person scottt    schedule 20.03.2015

Большинство из этих ответов работают только в простом случае, когда вы не отправляете вложение. В моем случае мне иногда нужно отправить вложение (ACTION_SEND) или два вложения (ACTION_SEND_MULTIPLE).

Поэтому я взял лучшие подходы из этой ветки и объединил их. Он использует ShareCompat.IntentBuilder библиотеки поддержки, но я показываю только те приложения, которые соответствуют ACTION_SENDTO с uri "mailto:". Таким образом я получаю только список почтовых приложений с поддержкой вложений:

fun Activity.sendEmail(recipients: List<String>, subject: String, file: Uri, text: String? = null, secondFile: Uri? = null) {
    val originalIntent = createEmailShareIntent(recipients, subject, file, text, secondFile)
    val emailFilterIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"))
    val originalIntentResults = packageManager.queryIntentActivities(originalIntent, 0)
    val emailFilterIntentResults = packageManager.queryIntentActivities(emailFilterIntent, 0)
    val targetedIntents = originalIntentResults
            .filter { originalResult -> emailFilterIntentResults.any { originalResult.activityInfo.packageName == it.activityInfo.packageName } }
            .map {
                createEmailShareIntent(recipients, subject, file, text, secondFile).apply { `package` = it.activityInfo.packageName }
            }
            .toMutableList()
    val finalIntent = Intent.createChooser(targetedIntents.removeAt(0), R.string.choose_email_app.toText())
    finalIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toTypedArray())
    startActivity(finalIntent)
}

private fun Activity.createEmailShareIntent(recipients: List<String>, subject: String, file: Uri, text: String? = null, secondFile: Uri? = null): Intent {
    val builder = ShareCompat.IntentBuilder.from(this)
            .setType("message/rfc822")
            .setEmailTo(recipients.toTypedArray())
            .setStream(file)
            .setSubject(subject)
    if (secondFile != null) {
        builder.addStream(secondFile)
    }
    if (text != null) {
        builder.setText(text)
    }
    return builder.intent
}
person David Vávra    schedule 06.01.2018
comment
Похоже, это может быть полезно; есть ли шанс получить это на Java? - person Kyle Humfeld; 06.03.2018
comment
Kotlin очень похож на Java, вы должны иметь возможность копировать и вставлять просто некоторые вещи. - person David Vávra; 07.03.2018

в Котлине, если кто-нибудь ищет

val emailArrray:Array<String> = arrayOf("[email protected]")
val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:") // only email apps should handle this
intent.putExtra(Intent.EXTRA_EMAIL, emailArrray)
intent.putExtra(Intent.EXTRA_SUBJECT, "Inquire about travel agent")
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}
person Mughil    schedule 16.04.2019

Следующий код работал у меня !!

import android.support.v4.app.ShareCompat;
    .
    .
    .
    .
final Intent intent = ShareCompat.IntentBuilder
                        .from(activity)
                        .setType("application/txt")
                        .setSubject(subject)
                        .setText("Hii")
                        .setChooserTitle("Select One")
                        .createChooserIntent()
                        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
                        .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

activity.startActivity(intent);
person Suyog Gunjal    schedule 04.12.2015

Это отлично работает для меня:

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(Uri.parse("mailto:" + address));
    startActivity(Intent.createChooser(intent, "E-mail"));
person EpicPandaForce    schedule 22.12.2015

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

Я нашел это в https://developer.android.com/guide/components/intents-common.html#Email

person Lamine Slimany    schedule 19.02.2017

Использование intent.setType("message/rfc822"); действительно работает, но показывает дополнительные приложения, которые не обязательно обрабатывают электронную почту (например, GDrive). Лучше всего использовать Intent.ACTION_SENDTO с setType("text/plain"), но вам нужно добавить setData(Uri.parse("mailto:")), чтобы получить наилучшие результаты (только для почтовых приложений). Полный код выглядит следующим образом:

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setType("text/plain");
intent.setData(Uri.parse("mailto:[email protected]"));
intent.putExtra(Intent.EXTRA_SUBJECT, "Email from My app");
intent.putExtra(Intent.EXTRA_TEXT, "Place your email message here ...");
startActivity(Intent.createChooser(intent, "Send Email"));
person Rami Alloush    schedule 10.08.2018
comment
Идеальная душа - person Daxesh Vekariya; 31.12.2019

Если вы хотите настроить таргетинг на Gmail, вы можете сделать следующее. Обратите внимание, что намерением является «ACTION_SENDTO», а не «ACTION_SEND», и дополнительные поля намерения не требуются для Gmail.

String uriText =
    "mailto:[email protected]" + 
    "?subject=" + Uri.encode("your subject line here") + 
    "&body=" + Uri.encode("message body here");

Uri uri = Uri.parse(uriText);

Intent sendIntent = new Intent(Intent.ACTION_SENDTO);
sendIntent.setData(uri);
if (sendIntent.resolveActivity(getPackageManager()) != null) {
   startActivity(Intent.createChooser(sendIntent, "Send message")); 
}
person pcodex    schedule 03.02.2018

Я обновляю ответ Адиля в Котлине,

val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:") // only email apps should handle this
intent.putExtra(Intent.EXTRA_EMAIL, Array(1) { "[email protected]" })
intent.putExtra(Intent.EXTRA_SUBJECT, "subject")
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    showSnackBar(getString(R.string.no_apps_found_to_send_mail), this)
}
person Kishan Solanki    schedule 19.09.2018
comment
Это не удается, даже если в приложении есть Gmail. - person AndroidDev; 11.01.2019
comment
@AndroidDev, на каком устройстве вы столкнулись с проблемой? - person Kishan Solanki; 16.01.2019

Пожалуйста, используйте приведенный ниже код:

                try {

                    String uriText =
                            "mailto:emailid" +
                                    "?subject=" + Uri.encode("Feedback for app") +
                                    "&body=" + Uri.encode(deviceInfo);
                    Uri uri = Uri.parse(uriText);
                    Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
                    emailIntent.setData(uri);
                    startActivity(Intent.createChooser(emailIntent, "Send email using..."));
                } catch (android.content.ActivityNotFoundException ex) {
                    Toast.makeText(ContactUsActivity.this, "No email clients installed.", Toast.LENGTH_SHORT).show();
                }
person Tushar Bapte    schedule 21.12.2019

Может, тебе стоит попробовать это: intent.setType("plain/text");

Я нашел его здесь. Я использовал его в своем приложении, и он показывает только параметры электронной почты и Gmail.

person sianis    schedule 02.01.2012
comment
Обычный / текстовый показывает Bluetooth, Skype и т. д. Проверьте желаемый результат в приложении Android Market. Шаги перечислены в вопросе. - person dira; 02.01.2012
comment
Использование типа MIME для выполнения операции отправки - плохая идея, потому что вы в основном инструктируете Android предоставить список приложений, которые поддерживают отправку файла типа plain/text, а это даже не допустимый тип MIME. Это не то же самое, что отправка электронного письма. Вместо этого используйте протокол mailto:, потому что это то, что на самом деле понимают почтовые клиенты. - person Paul Lammertsma; 28.05.2013

Напишите электронное письмо в почтовом клиенте телефона:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("plain/text");
intent.putExtra(Intent.EXTRA_EMAIL, new String[] { "[email protected]" });
intent.putExtra(Intent.EXTRA_SUBJECT, "subject");
intent.putExtra(Intent.EXTRA_TEXT, "mail body");
startActivity(Intent.createChooser(intent, ""));
person Community    schedule 26.05.2015

Использовать этот:

boolean success = EmailIntentBuilder.from(activity)
        .to("[email protected]")
        .cc("[email protected]")
        .subject("Error report")
        .body(buildErrorReport())
        .start();

использовать build gradle:

compile 'de.cketti.mailto:email-intent-builder:1.0.0'
person Manish    schedule 24.10.2016

Вот что я использую, и у меня это работает:

//variables
String subject = "Whatever subject you want";
String body = "Whatever text you want to put in the body";
String intentType = "text/html";
String mailToParse = "mailto:";

//start Intent
Intent variableName = new Intent(Intent.ACTION_SENDTO);
variableName.setType(intentType);
variableName.setData(Uri.parse(mailToParse));
variableName.putExtra(Intent.EXTRA_SUBJECT, subject);
variableName.putExtra(Intent.EXTRA_TEXT, body);

startActivity(variableName);

Это также позволит пользователю выбрать предпочтительное почтовое приложение. Единственное, что это не позволяет сделать, - это указать адрес электронной почты получателя.

person grasshopper    schedule 30.12.2016
comment
Во второй строке отсутствует ". - person Tim; 30.12.2016

Этот код работает на моем устройстве

Intent mIntent = new Intent(Intent.ACTION_SENDTO);
mIntent.setData(Uri.parse("mailto:"));
mIntent.putExtra(Intent.EXTRA_EMAIL  , new String[] {"[email protected]"});
mIntent.putExtra(Intent.EXTRA_SUBJECT, "");
startActivity(Intent.createChooser(mIntent, "Send Email Using..."));
person Mahen    schedule 01.06.2017
comment
он открывает только Gmail и электронную почту на моем устройстве - person Mahen; 01.06.2017

ОТПРАВИТЬ ТОЛЬКО КЛИЕНТАМ ПО ЭЛЕКТРОННОЙ ПОЧТЕ - С НЕСКОЛЬКИМИ ПРИЛОЖЕНИЯМИ

Есть много решений, но все работают частично.

mailto правильно фильтрует почтовые приложения, но не может не отправлять потоки / файлы.

message / rfc822 открывает множество приложений вместе с почтовыми клиентами.

Итак, решение для этого - использовать оба.

  1. Сначала разрешите действия с намерением с помощью намерения mailto
  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;
}

Класс Utitlity для фильтрации требуемых намерений на основе намерений запроса

// 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;
}
person Ayyappa    schedule 09.02.2019
comment
Большое спасибо за этот ответ, это единственный, который у меня работает, чтобы также включать вложения ... Не знаю, почему в этом случае голосование "против". Я помещаю здесь один голос "за" .. - person Petr Nalevka; 05.05.2020

Также есть простое решение с ACTION_VIEW:

  Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri data = Uri.parse("mailto:[email protected]?subject=Feedback");
        intent.setData(data);
        startActivity(intent);
person Darksymphony    schedule 23.11.2020

использовать Anko - kotlin

context.email(email, subject, body)
person Ali hasan    schedule 22.09.2018

Kotlin работает с Gmail:

val i = Intent(Intent.ACTION_SENDTO).apply {
    type = "text/html"
    data = Uri.parse("mailto:")
    putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
    putExtra(Intent.EXTRA_SUBJECT, subject)
    putExtra(Intent.EXTRA_TITLE, subject)
}
if (packageManager != null && i.resolveActivity(packageManager) != null) {
    startActivity(i)
}

Если кто найдет решение для вывода сообщения тоже ...

person A. Ferrand    schedule 24.02.2020

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

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}
person remain4life    schedule 21.06.2020

Я почти использовал все ответы здесь на android 11, но они не работали должным образом. некоторые из них не помещают mailto в обязательное поле, а некоторые вообще не работают. поэтому я прочитал новую документацию и обнаружил, что электронные письма mailto должны быть в массиве, так что то, что сработало для меня, наконец, здесь. В любом случае спасибо за все ответы, в конце концов, они помогли.

//mail me
    findViewById<TextView>(R.id.mailme).setOnTouchListener { _, _ ->
        try {
            val mail: Array<String> = arrayOf("[email protected]")
            val mailme = Intent(Intent.ACTION_SENDTO).apply {
                data = Uri.parse("mailto:")
                putExtra(Intent.EXTRA_EMAIL, mail)
                putExtra(Intent.EXTRA_TEXT, "Hey We Need Your Help With This Issue.")
                putExtra(Intent.EXTRA_SUBJECT, "At Logs Calculator, We Need Your Help !")
            }
            startActivity(mailme)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        true
    }
person Haris    schedule 30.03.2021

следуйте этому до буквы, и у вас не должно быть проблем

https://developer.android.com/guide/components/intents-common#ComposeEmail

убедитесь, что вы передаете массив в поле EXTRA_EMAIL при использовании ACTION_SENDTO

person Jean Raymond Daher    schedule 26.04.2021