[android] Send Email Intent


Answers

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

Question
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?




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



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



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



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



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.




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



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
}



Try:

intent.setType("message/rfc822");



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



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



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.




Related