Send Email Intent

2018-12-31 13:54发布

问题:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType(\"text/html\");
intent.putExtra(Intent.EXTRA_EMAIL, \"emailaddress@emailaddress.com\");
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.

  1. Open Android Market app
  2. Open any application where developer has specified his/her email address. (If you can\'t find such app just open my app:- market://details?id=com.becomputer06.vehicle.diary.free , OR search by \'Vehicle Diary\')
  3. Scroll down to \'DEVELOPER\'
  4. Click on \'Send Email\'

The dialog shows only email Apps e.g. Gmail, Yahoo Mail etc. It does not show Bluetooth, Orkut etc. What code produces such dialog?

回答1:

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



回答2:

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\",\"abc@gmail.com\", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, \"Subject\");
emailIntent.putExtra(Intent.EXTRA_TEXT, \"Body\");
startActivity(Intent.createChooser(emailIntent, \"Send email...\"));

Hope this helps.

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

Ref link



回答3:

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();


回答4:

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);
    }
}


回答5:

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: abc@xyz.com\"));
startActivity(Intent.createChooser(emailIntent, \"Send feedback\"));

This was my output (Gmail + Inbox and nothing else)

\"enter

I got this solution from Google Developers site



回答6:

Try:

intent.setType(\"message/rfc822\");


回答7:

This works for me:

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse(\"mailto:\"));
intent.putExtra(Intent.EXTRA_EMAIL  , new String[] { \"me@somewhere.com\" });
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.



回答8:

This is the way to do it according to Android Developer Docs 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

If you want to add the body and subject, add this

intent.putExtra(Intent.EXTRA_SUBJECT, \"Your Subject Here\");
intent.putExtra(Intent.EXTRA_TEXT, \"E-mail body\" );


回答9:

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);


回答10:

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);


回答11:

Finally come up with best way to do

    String to = \"test@gmail.com\";
    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);


回答12:

Edit: Not working anymore with new versions of Gmail

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);
}


回答13:

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...\"));


回答14:

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);


回答15:

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\"));


回答16:

Works on All android Versions:

String[] TO = {\"email@server.com\"};
    Uri uri = Uri.parse(\"mailto:email@server.com\")
            .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...\"));


回答17:

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



回答18:

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
}


回答19:

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:youremail@gmail.com\" + 
    \"?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\")); 
}


回答20:

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.



回答21:

Use this:

boolean success = EmailIntentBuilder.from(activity)
        .to(\"support@example.org\")
        .cc(\"developer@example.org\")
        .subject(\"Error report\")
        .body(buildErrorReport())
        .start();

use build gradle :

compile \'de.cketti.mailto:email-intent-builder:1.0.0\'


回答22:

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.



回答23:

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[] {\"mahendrarajdhami@gmail.com\"});
mIntent.putExtra(Intent.EXTRA_SUBJECT, \"\");
startActivity(Intent.createChooser(mIntent, \"Send Email Using...\"));


回答24:

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) { \"test@email.com\" })
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)
}


回答25:

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[] { \"some@email.address\" });
intent.putExtra(Intent.EXTRA_SUBJECT, \"subject\");
intent.putExtra(Intent.EXTRA_TEXT, \"mail body\");
startActivity(Intent.createChooser(intent, \"\"));


回答26:

            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();
            }


回答27:

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:IT@RMAsoft.NET\"));
    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\"));


回答28:

use Anko - kotlin

context.email(email, subject, body)