Reputation: 30594
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 the 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, and Yahoo Mail. How to do it?
I've seen such an example on the '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?
Upvotes: 689
Views: 489421
Reputation: 18434
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);
}
}
UPDATE Since Android 11, we have to add a query in AndroidManifest.xml to be able to query all apps that can handle "mailto" intents.
Add this to your manifest file:
<queries>
<intent>
<action android:name="android.intent.action.SENDTO"/>
<data android:scheme="mailto" android:host="*" />
</intent>
</queries>
Reference: https://developer.android.com/training/package-visibility/use-cases#sms-apps
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
Upvotes: 987
Reputation: 2548
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]"}); //or arrayOf(getString(R.string.support_email)) works in kotlin
This will be the recipient's address, meaning the user will send you (the developer) an e-mail.
Finally, either call
startActivity(intent); //to open in default mail app
or
startActivity(Intent.createChooser(intent, "Send email...")) //to let user pick which email app to use
Upvotes: 38
Reputation: 1140
private void sendEmail() {
String version = getString(R.string.android_version_not_found);
String appVersion;
try {
version = "Version Android: " + Build.VERSION.RELEASE + " (API " + Build.VERSION.SDK_INT + ")";
PackageInfo packageInfo = requireActivity().getPackageManager().getPackageInfo(requireActivity().getPackageName(), 0);
appVersion = "Version App: " + packageInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
appVersion = getString(R.string.app_version_not_found);
}
String deviceName = Build.MODEL; // Get the device name
String subjectTemplate = getString(R.string.contact_us_subject_template);
String subject = getString(R.string.contact_us_subject_template);
String bodyTemplate = getString(R.string.contact_us_body_template);
String topic = getString(R.string.problem_description) + "\n\n" + version + "\n" + appVersion + "\nDevice: " + deviceName;
String body = String.format(bodyTemplate, topic);
String email = getString(R.string.contact_us_email);
String mailtoUrl = "mailto:" + email + "?subject=" + Uri.encode(subject) +
"&body=" + Uri.encode(body);
Intent emailIntent = new Intent(Intent.ACTION_VIEW);
emailIntent.setData(Uri.parse(mailtoUrl));
try {
startActivity(Intent.createChooser(emailIntent, getString(R.string.choose_email_client)));
} catch (ActivityNotFoundException e) {
Toast.makeText(requireContext(), getString(R.string.install_email_client_before_sending), Toast.LENGTH_LONG).show();
}
}
<TextView
android:id="@+id/txt_EmailInfor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:autoLink="web|email"
android:linksClickable="true"
android:text="@string/support_emailt"
android:textColor="@color/appBlue"
android:textSize="@dimen/_14sdp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground" />
Upvotes: 1
Reputation: 937
This is how i manage to do it in kotlin :
val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:")
intent.putExtra(Intent.EXTRA_EMAIL, emailAddress)
intent.putExtra(Intent.EXTRA_SUBJECT, emailSubject)
intent.putExtra(Intent.EXTRA_TEXT, emailBody)
context.startActivity(intent)
Hope it can help
Upvotes: 4
Reputation: 32083
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..."));
Most importantly: Use the ACTION_SENDTO action rather than the ACTION_SEND action. I've tried it on a couple of Android 4.4 devices and:
Upvotes: 50
Reputation: 395
I almost used all of the answers here on android 11 but they did not work properly. some of them does not place the mailto on its required field and some other don't even work at all. so I did read the new documentation and found that mailto emails should be in an array so what worked for me finally is here. Anyways thanks for all the answers, they did help after all.
//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
}
Upvotes: 1
Reputation: 151
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();
}
Upvotes: 3
Reputation: 826
String sendEmailTo = "[email protected]";
String subject = "Subject";
String body = "Body";
Uri uri = Uri.parse("mailto:"+sendEmailTo+"?subject="+subject+"&body="+body);
startActivity(new Intent(Intent.ACTION_VIEW, uri);
This worked for me. This will only show the mailing application in the intent chooser.
Additionally:
One problem that i faced with this method is I was unable to add space in the suggestions and body text.
So, to put spaces in the suggestion or body text then replace the space with %20
Upvotes: 2
Reputation: 151
Kotlin:
val email: String = getEmail()
val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:$email" )
startActivity(intent)
Upvotes: 2
Reputation: 1004
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(ACTION_SENDTO, uri);
emailIntent.putExtra(EXTRA_EMAIL, TO);
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
Updated for Android 10, now using Kotlin...
fun Context.sendEmail(
address: String?,
subject: String?,
body: String?,
) {
val recipients = arrayOf(address)
val uri = address.toUri()
.buildUpon()
.appendQueryParameter("subject", subject)
.appendQueryParameter("body", body)
.build()
val emailIntent = Intent(ACTION_SENDTO, uri).apply {
setData("mailto:$address".toUri());
putExtra(EXTRA_SUBJECT, subject);
putExtra(EXTRA_TEXT, body);
putExtra(EXTRA_EMAIL, recipients)
}
val pickerTitle = getString(R.string.some_title)
ContextCompat.startActivity(this, Intent.createChooser(emailIntent, pickerTitle, null)
}
...after updating to API 30, the code did not fill the subject and body of the email client (e.g Gmail). But I found an answer here:
fun Context.sendEmail(
address: String?,
subject: String?,
body: String?,
) {
val selectorIntent = Intent(ACTION_SENDTO)
.setData("mailto:$address".toUri())
val emailIntent = Intent(ACTION_SEND).apply {
putExtra(EXTRA_EMAIL, arrayOf(address))
putExtra(EXTRA_SUBJECT, subject)
putExtra(EXTRA_TEXT, body)
selector = selectorIntent
}
startActivity(Intent.createChooser(emailIntent, getString(R.string.send_email)))
}
Upvotes: 20
Reputation: 394
follow this to the letter and you should have no issues
https://developer.android.com/guide/components/intents-common#ComposeEmail
make sure you pass an array in the EXTRA_EMAIL field while using ACTION_SENDTO
Upvotes: 0
Reputation: 2683
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);
Upvotes: 1
Reputation: 1311
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);
}
Upvotes: 0
Reputation: 10651
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.
Upvotes: 114
Reputation: 4866
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);
}
Upvotes: 10
Reputation: 2455
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);
Upvotes: 31
Reputation: 715
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);
}
Upvotes: 6
Reputation: 618
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...
Upvotes: 0
Reputation: 2626
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"));
Upvotes: 3
Reputation: 4644
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();
}
Upvotes: 1
Reputation: 1984
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;
}
Upvotes: 1
Reputation: 331
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);
}
}
Upvotes: 9
Reputation: 14618
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)
}
Upvotes: 2
Reputation: 1940
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"));
}
Upvotes: 2
Reputation: 19149
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
}
Upvotes: 9
Reputation: 20031
when you will change your intent.setType like below you will get
intent.setType("text/plain");
Use android.content.Intent.ACTION_SENDTO
to get only the list of e-mail clients, with no facebook or other apps. Just the email clients.
Ex:
new Intent(Intent.ACTION_SENDTO);
I wouldn't suggest you get directly to the email app. Let the user choose his favorite email app. Don't constrain him.
If you use ACTION_SENDTO, putExtra does not work to add subject and text to the intent. Use Uri to add the subject and body text.
EDIT:
We can use message/rfc822
instead of "text/plain"
as the MIME type. However, that is not indicating "only offer email clients" -- it indicates "offer anything that supports message/rfc822 data". That could readily include some application that are not email clients.
message/rfc822
supports MIME Types of .mhtml, .mht, .mime
Upvotes: 238
Reputation: 760
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..."));
Upvotes: 1
Reputation: 51
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
Upvotes: 5
Reputation: 21
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.
Upvotes: 1