2

The official docs show how you can send an email with an attachment:

public void composeEmail(String[] addresses, String subject, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("*/*");
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

It then says:

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.

Like so:

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

But actually, I want a combination of the above... i.e. send an email with an attachment and using only an email app.

But when using intent.setData(Uri.parse("mailto:")) in combination with Intent.ACTION_SEND or Intent.ACTION_SEND_MULTIPLE, nothing happens... no email app (or app chooser) opens at all.

So how do I send an email with attachment (or multiple attachments) whilst also restricting the app to email apps?

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
drmrbrewer
  • 11,491
  • 21
  • 85
  • 181
  • 2
    Use `setSelector()` on an `ACTION_SEND`/`ACTION_SEND_MULTIPLE` `Intent`, where the `Intent` passed *into* `setSelector()` is your `ACTION_SENDTO` and `mailto:` `Intent`. See https://stackoverflow.com/a/61391007/115145. – CommonsWare May 18 '22 at 11:05
  • @CommonsWare OK thanks... got it... seems to work. For a bonus point, my own app is showing up in the chooser as apparently being able to send emails (which it can't)... how do I flag my own app as NOT being able to handle `mailto:`? – drmrbrewer May 18 '22 at 11:16
  • @CommonsWare the following post suggests *not* putting `android.intent.action.SENDTO` in the Manifest, but if I remove that then the chooser no longer opens: https://stackoverflow.com/questions/55353609/why-does-intent-action-sendto-includes-the-app-as-an-option#comment97431100_55353609. If put it back, the email chooser opens, but with my own app as an option :-/ – drmrbrewer May 18 '22 at 11:43
  • "the following post suggests not putting android.intent.action.SENDTO in the Manifest" -- correct, that is for apps that handle `ACTION_SENDTO`. "if I remove that then the chooser no longer opens" -- if you are testing on Android 11+, try testing on an older version. If it works there, then perhaps `setSelector()` requires a `` element in the manifest to declare your package visibility requirements. I didn't think that was needed here, but I may be mis-remembering. Beyond that, perhaps ask a separate SO question with a fresh [mcve] showing your current approach. – CommonsWare May 18 '22 at 11:45
  • @CommonsWare OK will do. But, so far as I can see on a quick look, `` is intended to specify what your app *can* do not what it *can't* do? – drmrbrewer May 18 '22 at 11:54
  • No, `` says "these are other apps that I'm looking to find on the device". Mostly it controls `PackageManager`, but if `setSelector()` winds up using `PackageManager` in your app's process "under the covers", it might apply. – CommonsWare May 18 '22 at 12:11
  • OK thanks @CommonsWare... I've posted a separate question here: https://stackoverflow.com/q/72289500/4070848 – drmrbrewer May 18 '22 at 12:48

2 Answers2

0

That mailto: URI string appears invalid without recipients; try something alike this instead:

intent.setData(Uri.parse("mailto:" + String.join(",", addresses)));

See RFC 6068: The 'mailto' URI Scheme.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
0

Remove if (intent.resolveActivity(getPackageManager()) != null) check and it will open the intent. Usually the OS returns null whether the email handling apps exist or not.

Abu bakar
  • 751
  • 1
  • 4
  • 16