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"));
The above code opens a dialog showing following apps:- Bluetooth, Google Docs, Yahoo Mail, Gmail, Orkut, Skype etc.
Actually, I want to filter these list-options. I want to show only email related apps e.g. Gmail, Yahoo Mail. How to do it?
I've seen such example on 'Android Market' application.
The dialog shows only email Apps e.g. Gmail, Yahoo Mail etc. It does not show Bluetooth, Orkut etc. What code produces such dialog?
This question is related to
android
email
android-intent
SEND TO EMAIL CLIENTS ONLY - WITH MULTIPLE ATTACHMENTS
There are many solutions but all work partially.
mailto properly filters email apps but it has the inability of not sending streams/files.
message/rfc822 opens up hell of apps along with email clients
so, the solution for this is to use both.
private void share()
{
Intent queryIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
Intent dataIntent = getDataIntent();
Intent targetIntent = getSelectiveIntentChooser(context, queryIntent, dataIntent);
startActivityForResult(targetIntent);
}
Build the required data intent which is filled with required data to share
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 class for filtering required intents based on query intent
// 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;
}
This was the only way I found at the time to get it to work with any characters.
doreamon's answer is the correct way to go now, as it works with all characters in new versions of Gmail.
Old answer:
Here is mine. It seems to works on all Android versions, with subject and message body support, and full utf-8 characters support:
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);
}
Use this:
boolean success = EmailIntentBuilder.from(activity)
.to("[email protected]")
.cc("[email protected]")
.subject("Error report")
.body(buildErrorReport())
.start();
use build gradle :
compile 'de.cketti.mailto:email-intent-builder:1.0.0'
This is quoted from Android official doc, I've tested it on Android 4.4, and works perfectly. See more examples at 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);
}
}
Most of these answers work only for a simple case when you are not sending attachment. In my case I need sometimes to send attachment (ACTION_SEND) or two attachments (ACTION_SEND_MULTIPLE).
So I took best approaches from this thread and combined them. It's using support library's ShareCompat.IntentBuilder
but I show only apps which match the ACTION_SENDTO with "mailto:" uri. This way I get only list of email apps with attachment support:
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
}
If you want only the email clients you should use android.content.Intent.EXTRA_EMAIL
with an array. Here goes an example:
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);
use Anko - kotlin
context.email(email, subject, body)
From Android developers docs:
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);
}
}
Maybe you should try this: intent.setType("plain/text");
I found it here. I've used it in my app and it shows only E-Mail and Gmail options.
This works for me perfectly fine:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("mailto:" + address));
startActivity(Intent.createChooser(intent, "E-mail"));
I am updating Adil's answer in Kotlin,
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)
}
A late answer, although I figured out a solution which could help others:
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"))
This was my output (only Gmail + Inbox suggested):
I got this solution from the Android Developers site.
If you want to target Gmail then you could do the following. Note that the intent is "ACTION_SENDTO" and not "ACTION_SEND" and the extra intent fields are not necessary for 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"));
}
Try:
intent.setType("message/rfc822");
This works for me:
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..."));
i.e. use the ACTION_SENDTO
action rather than the ACTION_SEND
action. I've tried it on a couple of Android 4.4 devices and it limits the chooser pop-up to only display email applications (Email, Gmail, Yahoo Mail etc) and it correctly inserts the email address and subject into the email.
This is what I use, and it works for me:
//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);
This will also let the user choose their preferred email app. The only thing this does not allow you to do is to set the recipient's email address.
This code is working in my device
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..."));
UPDATE
Official approach:
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);
}
}
OLD ANSWER
The accepted answer doesn't work on the 4.1.2. This should work on all platforms:
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..."));
Update: According to marcwjj, it seems that on 4.3, we need to pass string array instead of a string for email address to make it work. We might need to add one more line:
intent.putExtra(Intent.EXTRA_EMAIL, addresses); // String[] addresses
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", email, null));
if (emailIntent.resolveActivity(context.getPackageManager()) != null) {
context.startActivity(Intent.createChooser(emailIntent, "Send Email..."));
} else {
Toast.makeText(context, "No apps can perform this action.", Toast.LENGTH_SHORT).show();
}
There are three main approaches:
String email = /* Your email address here */
String subject = /* Your subject here */
String body = /* Your body here */
String chooserTitle = /* Your chooser title here */
1. Custom 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. Using Intent
extras:
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. Support Library 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();
If you want to ensure that your intent is handled only by an email app (and not other text messaging or social apps), then use the ACTION_SENDTO
action and include the "mailto:" data scheme. For example:
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);
}
}
I found this in https://developer.android.com/guide/components/intents-common.html#Email
Works on All android Versions:
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..."));
updated for android 10, now using 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)
}
With Kotlin, works with 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)
}
If anyone find a solution to display the message too...
Using intent.setType("message/rfc822");
does work but it shows extra apps that not necessarily handling emails (e.g. GDrive). Using Intent.ACTION_SENDTO
with setType("text/plain")
is the best but you have to add setData(Uri.parse("mailto:"))
to get the best results (only email apps). The full code is as follows:
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"));
There is an easy solution also with ACTION_VIEW:
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.parse("mailto:[email protected]?subject=Feedback");
intent.setData(data);
startActivity(intent);
in Kotlin if anyone is looking
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);
}
Compose an email in the phone email client:
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, ""));
None of these solutions were working for me. Here's a minimal solution that works on Lollipop. On my device, only Gmail and the native email apps appear in the resulting chooser list.
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..."));
Please use the below code :
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();
}
Following Code worked for me!!
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);
Finally come up with best way to do
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);
The following code works for me fine.
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);
Sometimes you need to open default email app to view the inbox without creating a new letter, in this case it will help:
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);
}
This is the proper way to send the e-mail intent according to the Android Developer Official Documentation
Add these lines of code to your app:
Intent intent = new Intent(Intent.ACTION_SEND);//common intent
intent.setData(Uri.parse("mailto:")); // only email apps should handle this
Optional: Add the body and subject, like this
intent.putExtra(Intent.EXTRA_SUBJECT, "Your Subject Here");
intent.putExtra(Intent.EXTRA_TEXT, "E-mail body" );
You already added this line in your question
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"[email protected]"});
This will be the recipient's address, meaning the user will send you (the developer) an e-mail.
Source: Stackoverflow.com