Using Android Intent.ACTION_SEND for sending email
I'm using Intent.ACTION_SEND
to send an email. However, w开发者_如何学Pythonhen I call the intent
it is showing choices to send a message, send an email, and also to send via bluetooth. I want it to only show choices to send an email. How can I do this?
[Solution for API LEVEL >=15]
I've finally succeded in sending email WITH attachments to ONLY email clients. I write it here because it took me a lot of time and it may be usefull to others.
The problem is:
Intent.ACTION_SENDTO takes Data URI (so you can specify "mailto:" schema) BUT it does not accept Intent:EXTRA_STREAM.
Intent.ACTION_SEND accepts Intent:EXTRA_STREAM (so you can add attachment) BUT it takes only Type (not Data URI so you cannot specify "mailto:" schema).
So Intent.ACTION_SEND lets the user choose from several Activities, even if you setType("message/rfc822"), because that App/Activities can manage all file types (tipically GDrive/Dropbox Apps) and so even email message files.
The solution is in the setSelector method. With this method you can use Intent.ACTION_SENDTO to select the Activity, but then send the Intent.ACTION_SEND Intent.
Here my solution code (the attachment came from a FileProvider, but it could be any file):
{
Intent emailSelectorIntent = new Intent(Intent.ACTION_SENDTO);
emailSelectorIntent.setData(Uri.parse("mailto:"));
final Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"address@mail.com"});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
emailIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
emailIntent.setSelector( emailSelectorIntent );
Uri attachment = FileProvider.getUriForFile(this, "my_fileprovider", myFile);
emailIntent.putExtra(Intent.EXTRA_STREAM, attachment);
if( emailIntent.resolveActivity(getPackageManager()) != null )
startActivity(emailIntent);
}
I'm not taking credit for this answer but I believe it gives the best answer for this post.
It's a common misconception to use text/plain or text/html. This will trigger any application that can handle plain or HTML text files without any context, including Google Drive, Dropbox, Evernote and Skype.
Instead use a ACTION_SENDTO
, providing the mailto:
Uri
intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
You can then proceed using the chooser as suggested through the other answers.
Answered by @PaulLammertsma here Android email chooser
Intent email = new Intent(android.content.Intent.ACTION_SEND);
email.setType("application/octet-stream");
EDIT:
You could try setting the type to "message/rfc822"
as well.
try this...
@Ganapathy:try this code for display gmail
Intent gmail = new Intent(Intent.ACTION_VIEW);
gmail.setClassName("com.google.android.gm","com.google.android.gm.ComposeActivityGmail");
gmail.putExtra(Intent.EXTRA_EMAIL, new String[] { "jckdsilva@gmail.com" });
gmail.setData(Uri.parse("jckdsilva@gmail.com"));
gmail.putExtra(Intent.EXTRA_SUBJECT, "enter something");
gmail.setType("plain/text");
gmail.putExtra(Intent.EXTRA_TEXT, "hi android jack!");
startActivity(gmail);
This will help you.
On your button click :
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, new String[]{"youremail@yahoo.com"});
email.putExtra(Intent.EXTRA_SUBJECT, "subject");
email.putExtra(Intent.EXTRA_TEXT, "message");
email.setType("message/rfc822");
startActivity(Intent.createChooser(email, "Choose an Email client :"));
Using message/rfc822
type as pointed here: ACTION_SEND force sending with email solves the issue.
I had a similar problem with my app. I recently found this link form the official android developers site that really helps! Common Intents: Email
TL;DR:
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
Now, you will only be shown email clients!
You can add a Subject and Body by doing this:
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Body" );
I notice, that this is an pretty old question but it is the first result when searching for a "Send mail" solution and all answers have a common problem:
Using Intent.ACTION_SEND
and intent.setType("message/rfc822")
will result in a chooser that not only shows mail apps but all apps that can handle any MIME type support by message/rfc822, e.g. .mhtml
, .mht
, .mime
. Beside mail apps this could be Google Drive, Dropbox, Evernote, etc.
The only solution I found to limit the chooser to mail apps only is to use Intent.ACTION_SENDTO instead:
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto","address@example.com", null));
intent.putExtra(Intent.EXTRA_SUBJECT, "My Mail");
intent.putExtra(Intent.EXTRA_TEXT , "My Message");
try {
startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(MainActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
Thanks to the Open source developer, cketti for sharing this concise and neat solution. It's the only method that worked for me.
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
}
And this is the link to his/her gist.
First solution: try to be more specific in your Intent parameters. Add a message recipient for instance
emailIntent .putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {"user@example.com"});
Second solution: use the package manager to find all applications capable of sending a message and select the only those you want to use.
Shout-out to ARLabs for posting the best solution on how to send an email on android. I just made a little update - an option to add multiple email attachements.
fun sendEmail(context: Context, recipients: List<String>?, subject: String?, body: String?, attachments: List<Uri>?) {
val emailIntent = Intent(Intent.ACTION_SEND_MULTIPLE)
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
emailIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
emailIntent.selector = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"))
recipients?.let {
val recipientsArray = arrayOfNulls<String>(recipients.size)
ArrayList(recipients).toArray(recipientsArray)
emailIntent.putExtra(Intent.EXTRA_EMAIL, recipientsArray)
}
subject?.let {
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject)
}
body?.let {
emailIntent.putExtra(Intent.EXTRA_TEXT, body)
}
if (attachments?.isNotEmpty() == true) {
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(attachments))
}
try {
context.startActivity(emailIntent)
} catch (e: ActivityNotFoundException) {
// TODO handle "no app to handle action" error
}
}
This is a combination of Jack Dsilva and Jignesh Mayani solutions:
try
{
Intent gmailIntent = new Intent(Intent.ACTION_SEND);
gmailIntent.setType("text/html");
final PackageManager pm = _activity.getPackageManager();
final List<ResolveInfo> matches = pm.queryIntentActivities(gmailIntent, 0);
String gmailActivityClass = null;
for (final ResolveInfo info : matches)
{
if (info.activityInfo.packageName.equals("com.google.android.gm"))
{
gmailActivityClass = info.activityInfo.name;
if (gmailActivityClass != null && !gmailActivityClass.isEmpty())
{
break;
}
}
}
gmailIntent.setClassName("com.google.android.gm", gmailActivityClass);
gmailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { "yourmail@gmail.com" });
gmailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
gmailIntent.putExtra(Intent.EXTRA_CC, "cc@gmail.com"); // if necessary
gmailIntent.putExtra(Intent.EXTRA_TEXT, "Email message");
gmailIntent.setData(Uri.parse("yourmail@gmail.com"));
this._activity.startActivity(gmailIntent);
}
catch (Exception e)
{
Intent i = new Intent(Intent.ACTION_SEND);
i.putExtra(Intent.EXTRA_EMAIL, new String[] { "yourmail@gmail.com" });
i.putExtra(Intent.EXTRA_SUBJECT, "Subject");
i.putExtra(Intent.EXTRA_CC, "cc@gmail.com"); // if necessary
i.putExtra(Intent.EXTRA_TEXT, "Email message");
i.setType("plain/text");
this._activity.startActivity(i);
}
So, at first it will try to open gmail app and in case a user doesn't have it then the second approach will be implemented.
Best code to restrict it to only send an email. set this type to only send an email. i.setType("message/rfc822");
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL , new String[]{"skapis1@outlook.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(Firstclass.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
This saved my day. It sends composed text message directly to gmail app:
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto","togmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Report message");
emailIntent.putExtra(Intent.EXTRA_TEXT, edt_msg.getText().toString());
startActivity(Intent.createChooser(emailIntent, "Send email..."));
This will open only the Email app installed in your android phone.
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"example@gmail.com"});
intent.putExtra(Intent.EXTRA_SUBJECT, "email subject");
intent.putExtra(Intent.EXTRA_TEXT, "message body");
try {
startActivity(Intent.createChooser(intent, "send mail"));
} catch (ActivityNotFoundException ex) {
Toast.makeText(this, "No mail app found!!!", Toast.LENGTH_SHORT);
} catch (Exception ex) {
Toast.makeText(this, "Unexpected Error!!!", Toast.LENGTH_SHORT);
}
public class MainActivity extends AppCompatActivity {
private EditText edt_email;
private Button btn_send;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edt_email = (EditText) findViewById(R.id.edt_email);
btn_send = (Button) findViewById(R.id.btn_send);
btn_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_SEND );
intent.putExtra(Intent.EXTRA_EMAIL , new String[]{"sanaebadi97@gmail.com"});
intent.putExtra(Intent.EXTRA_SUBJECT , "subject");
intent.putExtra(Intent.EXTRA_TEXT , "My Email Content");
intent.setType("message/rfc822");
startActivity(Intent.createChooser(intent , "Choose Your Account : "));
}
});
}
}
try with ACTION_VIEW not ACTION_SENDTO , ACTION_VIEW will makes system calls only to Email Apps
Intent emailIntent = new Intent(Intent.ACTION_VIEW);
精彩评论