Câu trả lời:
Cách tốt nhất (và dễ nhất) là sử dụng 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();
}
Nếu không, bạn sẽ phải viết khách hàng của riêng bạn.
Intent i = new Intent(Intent.ACTION_SENDTO);
i.setType("message/rfc822");
i.setData(Uri.parse("mailto:"));
Sử dụng .setType("message/rfc822")
hoặc trình chọn sẽ hiển thị cho bạn tất cả (nhiều) ứng dụng hỗ trợ mục đích gửi.
message/rfc822
Tôi đã sử dụng điều này từ lâu và có vẻ tốt, không có ứng dụng không phải email nào xuất hiện. Chỉ là một cách khác để gửi một ý định gửi email:
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);
Tôi đã sử dụng một cái gì đó dọc theo dòng của câu trả lời hiện được chấp nhận để gửi email với tệp nhật ký lỗi nhị phân đính kèm. GMail và K-9 gửi nó tốt và nó cũng đến tốt trên máy chủ mail của tôi. Vấn đề duy nhất là ứng dụng thư khách của tôi về Thunderbird, có vấn đề với việc mở / lưu tệp nhật ký đính kèm. Trong thực tế, nó chỉ đơn giản là không lưu tập tin mà không phàn nàn.
Tôi đã xem xét một trong những mã nguồn của các thư này và nhận thấy rằng tệp đính kèm tệp nhật ký có (có thể hiểu được) loại mime message/rfc822
. Tất nhiên tệp đính kèm đó không phải là một email đính kèm. Nhưng Thunderbird không thể đối phó với lỗi nhỏ đó một cách duyên dáng. Vì vậy, đó là loại của một bummer.
Sau một chút nghiên cứu và thử nghiệm tôi đã đưa ra giải pháp sau:
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);
}
}
Nó có thể được sử dụng như sau:
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"));
Như bạn có thể thấy, phương thức createdEmailOnlyChooserIntent có thể dễ dàng được cung cấp với mục đích chính xác và loại mime chính xác.
Sau đó, nó đi qua danh sách các hoạt động khả dụng đáp ứng với ACTION_SENDTO mailto
mục đích giao thức (chỉ dành cho ứng dụng email) và xây dựng một trình chọn dựa trên danh sách các hoạt động đó và ý định ACTION_SEND ban đầu với loại mime chính xác.
Một ưu điểm khác là Skype không được liệt kê nữa (điều này xảy ra để đáp ứng với loại mime rfc822).
ACTION_SEND
và điều này rất tuyệt vời.
File
ví dụ chỉ ra tệp nhật ký sự cố mà ứng dụng Android của tôi tạo trong nền trong trường hợp có ngoại lệ chưa được lưu. Ví dụ đó chỉ minh họa cách thêm tệp đính kèm email. Bạn cũng có thể đính kèm bất kỳ tệp nào khác từ bộ nhớ ngoài (ví dụ như hình ảnh). Bạn cũng có thể xóa dòng đó crashLogFile
để lấy ví dụ hoạt động.
Để CHỈ CẦN EMAIL APPS để giải quyết ý định của bạn, bạn cần chỉ định ACTION_SENDTO là Hành động và gửi thư dưới dạng Dữ liệu.
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();
}
}
Tôi đã giải quyết vấn đề này bằng các dòng mã đơn giản như tài liệu Android giải thích.
( https://developer.android.com/guide/components/intents-common.html#Email )
Điều quan trọng nhất là cờ: nó là ACTION_SENDTO
, và khôngACTION_SEND
Dòng quan trọng khác là
intent.setData(Uri.parse("mailto:")); ***// only email apps should handle this***
Nhân tiện, nếu bạn gửi trống Extra
, if()
cuối cùng sẽ không hoạt động và ứng dụng sẽ không khởi chạy ứng dụng email.
Theo tài liệu Android. Nếu bạn muốn đảm bảo rằng ý định của bạn chỉ được xử lý bởi một ứng dụng email (chứ không phải các ứng dụng nhắn tin văn bản hoặc ứng dụng xã hội khác), thì hãy sử dụng ACTION_SENDTO
hành động và bao gồm mailto:
lược đồ dữ liệu "". Ví dụ:
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);
}
}
Chiến lược sử dụng .setType("message/rfc822")
hoặc ACTION_SEND
dường như cũng phù hợp với các ứng dụng không gửi email cho khách hàng, chẳng hạn như Android Beam và Bluetooth .
Việc sử dụng ACTION_SENDTO
và một mailto:
URI dường như hoạt động hoàn hảo và được khuyến nghị trong tài liệu dành cho nhà phát triển . Tuy nhiên, nếu bạn thực hiện việc này trên trình giả lập chính thức và không có bất kỳ tài khoản email nào được thiết lập (hoặc không có bất kỳ ứng dụng thư khách nào), bạn sẽ gặp phải lỗi sau:
Hành động không được hỗ trợ
Hành động đó hiện không được hỗ trợ.
Như hình dưới đây:
Nó chỉ ra rằng các trình giả lập giải quyết ý định cho một hoạt động được gọi com.android.fallback.Fallback
, hiển thị thông báo trên.Rõ ràng đây là do thiết kế.
Nếu bạn muốn ứng dụng của mình phá vỡ điều này để nó cũng hoạt động chính xác trên trình giả lập chính thức, bạn có thể kiểm tra nó trước khi thử gửi email:
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();
}
Tìm thêm thông tin trong tài liệu dành cho nhà phát triển .
Gửi email có thể được thực hiện với Ý định sẽ không yêu cầu cấu hình. Nhưng sau đó nó sẽ yêu cầu tương tác người dùng và bố cục sẽ bị hạn chế một chút.
Xây dựng và gửi một email phức tạp hơn mà không có sự tương tác của người dùng đòi hỏi phải xây dựng ứng dụng khách của riêng bạn. Điều đầu tiên là API Sun Java cho email không có sẵn. Tôi đã thành công trong việc tận dụng thư viện Apache Mime4j để xây dựng email. Tất cả dựa trên các tài liệu tại nilvec .
Dưới đây là mã làm việc mẫu mở ứng dụng thư trong thiết bị Android và tự động điền vào Địa chỉ và Chủ đề trong thư soạn thảo.
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()
và Avi đặt putExtra()
. Cả hai biến thể làm việc. Nhưng nếu loại bỏ setData
và chỉ sử dụng intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"hi@example.com"});
, sẽ có một ActivityNotFoundException
.
Tôi sử dụng mã dưới đây trong ứng dụng của tôi. Điều này hiển thị chính xác các ứng dụng email của khách hàng, chẳng hạn như 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)));
Điều này sẽ chỉ hiển thị cho bạn các ứng dụng email (cũng như PayPal vì một số lý do không xác định)
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";
vào đây vì nó sẽ dẫn đến ngoại lệ.
Đây là cách tôi đã làm nó. Đẹp và đơn giản.
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);
Chức năng này đầu tiên là gmail có ý định trực tiếp để gửi email, nếu không tìm thấy gmail thì hãy thúc đẩy người chọn ý định. Tôi đã sử dụng chức năng này trong nhiều ứng dụng thương mại và nó hoạt động tốt. Hy vọng nó sẽ giúp bạn:
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);
}
}
}
đơn giản thử cái này
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 :"));
}
});
}
Giải pháp khác có thể là
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);
Giả sử hầu hết các thiết bị Android đã cài đặt ứng dụng GMail.
Tôi đã sử dụng mã này để gửi thư bằng cách khởi chạy phần soạn thảo ứng dụng thư mặc định trực tiếp.
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();
}
Phương pháp này làm việc cho tôi. Nó mở ứng dụng Gmail (nếu được cài đặt) và đặt 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**
Thử cái này:
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
}
Đoạn mã trên sẽ mở ứng dụng email khách yêu thích của người dùng được điền sẵn email sẵn sàng gửi.