2

I am writing an app that needs to send emails at the end of each transaction. I am doing the following:

Intent mail = new Intent(Intent.ACTION_SEND);
mail.setType("text/html");
mail.putExtra(Intent.EXTRA_EMAIL, new String[] { emailTo });
mail.putExtra(Intent.EXTRA_SUBJECT, "Send from Android");
mail.putExtra(Intent.EXTRA_TEXT, "Sent from Android");
startActivity(Intent.createChooser(mail,"Select Email Software..."));

What I would like to do is pre-select the email software and store it in a setting. That way, every time the email is being sent, it does not have to ask the user which email to use. I just can't seem to figure out how to invoke the chooser and get the selected value.

Any help would be greatly appreciated.

jd1
  • 63
  • 1
  • 5

3 Answers3

9

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.

Paul Lammertsma
  • 37,593
  • 16
  • 136
  • 187
  • Finally, an answer that only shows mail clients. There's one thing I noticed though. This will by default select have GMail selected instead of allowing the user to first select which email client. How do you get around this? – Etienne Lawlor Mar 10 '14 at 01:51
  • @toobsco42 You've likely set up Gmail as the default handler. – Paul Lammertsma Mar 10 '14 at 08:03
  • Actually I went and set up an account on the Email app. Then I uninstalled my app and reinstalled my app and am seeing the same thing. – Etienne Lawlor Mar 10 '14 at 14:39
  • @toobsco42 This has nothing to do with your app; you've likely set Gmail as the default handler for all `mailto:` intents. To clear this default, go to Android application settings for Gmail, and clear its defaults. If you want to provide special handling in your app, you can instead query the PackageManager, and e.g. construct a chooser to display all apps capable of handling the intent. – Paul Lammertsma Mar 10 '14 at 15:06
  • I just went to clear defaults for the Gmail application. Then uninstalled and reinstalled my app. And still the Gmail app gets auto selected. Its not a big issue, im just wondering why I have seen other choosers where it doesn't autoselect an option. – Etienne Lawlor Mar 10 '14 at 15:14
  • The reason i don't want to construct my own chooser is because I want the two buttons at the bottom of the dialog to show up. The "Always" and "Just Once" buttons. – Etienne Lawlor Mar 10 '14 at 15:15
  • @toobsco42 This sounds very odd to me. Perhaps you can confirm the behavior by installing another e-mail client, such as [K-9 Mail](https://play.google.com/store/apps/details?id=com.fsck.k9). – Paul Lammertsma Mar 10 '14 at 17:35
  • Still shows text Messaging in chooser not 100% perfect but close – JPM Mar 25 '15 at 17:32
  • Messaging must register itself as an intent filter for the "mailto" schema. If it does not support email, it's a bug in the Messaging app. – Paul Lammertsma Mar 25 '15 at 17:42
4

Here is the solution:

private void setSpinnerValues() {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("text/html");
    PackageManager pm = getPackageManager();
    emailers = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_RESOLVED_FILTER);

    if (emailers.size() == 0) {
        spnEmailProgram.setEnabled(false);
        return;
    }
    spnEmailProgram.setEnabled(true);
    CharSequence[] sa = new CharSequence[emailers.size()];
    int lastPosition = 0;
    for (int i = 0; i < emailers.size(); i++) {
        ResolveInfo r = emailers.get(i);
        sa[i] = pm.getApplicationLabel(r.activityInfo.applicationInfo);
        if (r.activityInfo.name.equalsIgnoreCase(Options.EmailClass)) {
            lastPosition = i;
        }
    }
    ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this,
            android.R.layout.simple_spinner_item, sa);
    adapter.
              setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spnEmailProgram.setAdapter(adapter);
    spnEmailProgram.setSelection(lastPosition);
}

Save the choice for later use:

    if (emailers.size() == 0) {
        Options.EmailProgram = "";
        Options.EmailClass = "";
    } else {
        ResolveInfo r = emailers.get(spnEmailProgram.getSelectedItemPosition());
        Options.EmailProgram = r.activityInfo.packageName;
        Options.EmailClass = r.activityInfo.name;
    }

Now, to consume it, just to the following:

Intent mail = new Intent(Intent.ACTION_SEND);
mail.setType("text/html");
Intent chooser = null;
if (Options.EmailProgram!=null && Options.EmailProgram.length()>0) {
  mail.setClassName(Options.EmailProgram,Options.EmailClass);
  chooser = mail;
}

fill in rest of data and start the activity

if (chooser == null) {
  chooser = Intent.createChooser(mail,"Select Email Software..."); 
}
startActivity(chooser);
jd1
  • 63
  • 1
  • 5
  • 1
    Beware of using `new Intent(Intent.ACTION_SEND).setType("text/html")`; the semantic meaning of this is sending a HTML file. Only 'by coincidence' do most e-mail clients match this intent, but bear in mind that many other applications do too, such as Drive, Dropbox and Skype. A better technique would be using `ACTION_SENDTO` and specifying the `mailto:` Uri scheme. – Paul Lammertsma Mar 11 '13 at 17:25
2

You would have to create your own chooser, possibly as an AlertDialog populated using the results of calling queryIntentActivities() on PackageManager.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491