Ответы:
Лучший (и самый простой) способ - использовать 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();
}
В противном случае вам придется написать свой собственный клиент.
Intent i = new Intent(Intent.ACTION_SENDTO);
i.setType("message/rfc822");
i.setData(Uri.parse("mailto:"));
Использование .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@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.
Затем он просматривает список доступных действий, которые отвечают на намерение mailto
протокола ACTION_SENDTO (которые являются только приложениями электронной почты), и строит средство выбора на основе этого списка действий и исходного намерения ACTION_SEND с правильным типом mime.
Еще одним преимуществом является то, что Skype больше не указан (что происходит с типом mime rfc822).
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"));
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()
в конце не будет работать, и приложение не запустит почтовый клиент.
Согласно документации 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);
}
}
Стратегия использования .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();
}
Найти больше информации в документации для разработчиков .
Отправка электронной почты может быть выполнена с помощью Intents, которая не требует настройки. Но тогда это потребует взаимодействия с пользователем, и расположение будет немного ограничено.
Создание и отправка более сложных электронных писем без взаимодействия с пользователем влечет за собой создание собственного клиента. Во-первых, 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);
}
}
}
просто попробуйте этот
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();
используйте build gradle:
compile 'de.cketti.mailto:email-intent-builder:1.0.0'
Я использовал этот код для отправки почты, непосредственно запустив раздел создания почтового приложения по умолчанию.
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();
}
Этот метод работает для меня. Он открывает приложение 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;
}
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, "Write your Pubg user name or Phone Number");
startActivity(Intent.createChooser(emailIntent, "Send email..."));**strong text**
Попробуй это:
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
}
Приведенный выше код откроет любимый почтовый клиент пользователей, предварительно заполненный электронным письмом, готовым к отправке.