Reputation: 87430
I want to setup a part of my application that allows users to send a quick email to another user. It's not very hard to set this up:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, message);
Intent mailer = Intent.createChooser(intent, null);
startActivity(mailer);
However, the problem is that the ACTION_SEND is accepted by more than just email programs - for example, on my phone the Facebook app, Twitter, reddit is fun, and even Bluetooth come up as viable alternatives for sending this message. The message is entirely too long for some of these (especially Twitter).
Is there a way to limit the chooser to just applications that support long messages (such as email)? Or is there a way to detect the app that the user has chosen and adjust the message appropriately?
Upvotes: 85
Views: 66570
Reputation: 475
I have tried many solutions, but most of them didn't work. It worked for android 12
Uri uri = Uri.parse("mailto:"+ "[email protected]" +"?subject="+ "Email Subject" +"&body="+ "Email Body");
startActivity(new Intent(Intent.ACTION_VIEW, uri));
I have tried Intent.ACTION_SEND and Intent.ACTION_SENDTO, but non of these worked on android 12
Upvotes: 0
Reputation: 473
None of the solutions worked for me. Thanks to the Open source developer, cketti for sharing his/her concise and neat solution.
String mailto = "mailto:[email protected]" +
"?cc=" + "[email protected]" +
"&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
}
And this is the link to his/her gist.
Upvotes: 3
Reputation: 85
Try this one
Intent intent = new Intent("android.intent.action.SENDTO", Uri.fromParts("mailto", "[email protected]", null));
intent.putExtra("android.intent.extra.SUBJECT", "Enter Subject Here");
startActivity(Intent.createChooser(intent, "Select an email client"));
Upvotes: 3
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: 804
try this option:
Intent intentEmail = new Intent(Intent.ACTION_SEND);
intentEmail.setType("message/rfc822");
Upvotes: 0
Reputation: 3256
Changing the MIME type is the answer, this is what I did in my app to change the same behavior. I used intent.setType("message/rfc822");
Upvotes: 88
Reputation: 2663
This worked for me
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.setType("vnd.android.cursor.item/email");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {"[email protected]"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "My Email Subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "My email content");
startActivity(Intent.createChooser(emailIntent, "Send mail using..."));
Upvotes: 29
Reputation: 16025
This is a bit of a typo, since you need to switch your mimetype:
intent.setType("plain/text"); //Instead of "text/plain"
Upvotes: -1
Reputation: 2003
Try changing the MIME type from plain to message
intent.setType("text/message");
Upvotes: 0
Reputation: 87430
Thanks to Pentium10's suggestion of searching how Linkify works, I have found a great solution to this problem. Basically, you just create a "mailto:" link, and then call the appropriate Intent for that.:
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.parse("mailto:?subject=" + subject + "&body=" + body);
intent.setData(data);
startActivity(intent);
There are a few interesting aspects to this solution:
I'm using the ACTION_VIEW action because that's more appropriate for a "mailto:" link. You could provide no particular action, but then you might get some unsatisfactory results (for example, it will ask you if you want to add the link to your contacts).
Since this is a "share" link, I am simply including no email address - even though this is a mailto link. It works.
There's no chooser involved. The reason for this is to let the user take advantage of defaults; if they have set a default email program, then it'll take them straight to that, bypassing the chooser altogether (which seems good in my mind, you may argue otherwise).
Of course there's a lot of finesse I'm leaving out (such as properly encoding the subject/body), but you should be able to figure that out on your own.
Upvotes: 103
Reputation: 6663
Have you tried including the Intent.EXTRA_EMAIL
extra?
Intent mailer = new Intent(Intent.ACTION_SEND);
mailer.setType("text/plain");
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"[email protected]"});
mailer.putExtra(Intent.EXTRA_SUBJECT, subject);
mailer.putExtra(Intent.EXTRA_TEXT, bodyText);
startActivity(Intent.createChooser(mailer, "Send email..."));
That may restrict the list of available receiver applications...
Upvotes: 4