13

There are two requirements:

  • Email with attachment
  • In the Intent chooser, there should be only Email apps.

What I have known/done:

  • Intent.ACTION_SENDTO with intent.setData(Uri.parse("mailto:")) can make sure that there are only Email apps in Intent chooser but it will not bring attachment(For some apps like Gmail it will, but there are also many apps that will ignore attachment).

  • Intent.ACTION_SEND can send Email with attachment. However, in Intent chooser, there will be apps that are actually not Email apps but can response to Intent.ACTION_SEND. Using intent.setType("message/rfc822") can reduce number of those apps but not all.

  • References this answer: https://stackoverflow.com/a/8550043/3952691 and nearly succeed in my goals. My code is as below:

    private static void sendFeedbackWithAttachment(Context context, String subject) {
        Intent intent = new Intent(Intent.ACTION_SENDTO);
        intent.setData(Uri.parse("mailto:"));
    
        PackageManager packageManager = context.getPackageManager();
        List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0);
        if (resolveInfos.isEmpty()) {
            Toast.makeText(context, context.getString(R.string.error_activity_not_found),
                    Toast.LENGTH_SHORT).show();
        } else {
            // ACTION_SEND may be replied by some apps that are not email apps. However,
            // ACTION_SENDTO doesn't allow us to choose attachment. As a result, we use
            // an ACTION_SENDTO intent with email data to filter email apps and then send
            // email with attachment by ACTION_SEND.
            List<LabeledIntent> intents = new ArrayList<>();
            Uri uri = getLatestLogUri();
            for (ResolveInfo info : resolveInfos) {
                Intent i = new Intent(Intent.ACTION_SEND);
                i.setPackage(info.activityInfo.packageName);
                i.setClassName(info.activityInfo.packageName, info.activityInfo.name);
                i.putExtra(Intent.EXTRA_EMAIL, new String[] { Def.Meta.FEEDBACK_EMAIL });
                i.putExtra(Intent.EXTRA_SUBJECT, subject);
                i.putExtra(Intent.EXTRA_STREAM, uri);
                intents.add(new LabeledIntent(i, info.activityInfo.packageName,
                        info.loadLabel(context.getPackageManager()), info.icon));
            }
            Intent chooser = Intent.createChooser(intents.remove(0),
                    context.getString(R.string.send_feedback_to_developer));
            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS,
                    intents.toArray(new LabeledIntent[intents.size()]));
            context.startActivity(chooser);
        }
    }
    

    However, on some devices(For example, Xiaomi 2S with MIUI V5, I don't know if this can be influenced by a third-party rom), the result is an empty Intent chooser. And it seems that above Android 6.0, Intent.EXTRA_INITIAL_INTENTS has some bugs(Custom intent-chooser - why on Android 6 does it show empty cells?, and another one: https://code.google.com/p/android/issues/detail?id=202693).

As a result, I don't know how to achieve my goals. Please help me, thank you in advance.

Community
  • 1
  • 1
ywwynm
  • 11,573
  • 7
  • 37
  • 53
  • "Intent.ACTION_SENDTO with intent.setData(Uri.parse("mailto:")) can make sure that there are only Email apps in Intent chooser" -- no, it does not. It puts in the chooser any app that elects to support that `Intent` structure. Anyone can write such an app, and it may not be an "Email app". There is no universal declaration of what "Email apps" are. – CommonsWare May 16 '16 at 23:09
  • @CommonsWare Yes I know it. But I'm talking about common case. We can say, an app which has a `IntentFilter` for `Intent.ACTION_SEND` and data scheme as "mailto", if it is a formal app, it should have the ability to handle Email events thus we can see it as an "Email app". – ywwynm May 17 '16 at 05:38
  • @ywwynm Use .setType("message/rfc822") or the chooser will show you all of the (many) applications that support the send intent. – Stanojkovic May 18 '16 at 22:36
  • 1
    @Stanojkovic Could you please see my question description carefully? In "What I have known/done" section, I said that I have tried to use "message/rfc822" but it didn't meet my demand. – ywwynm May 19 '16 at 13:16
  • @ywwynm This is how I manage sending mails: `String mailTo = "email@gmail.com";` `Intent email_intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", mailTo, null));` – Stanojkovic May 19 '16 at 18:08
  • @ywwynm maybe youll find something usefull here: http://stackoverflow.com/questions/9974987/how-to-send-an-email-with-a-file-attachment-in-android, this guy had putExtra(Intent.EXTRA_STREAM); – Stanojkovic May 20 '16 at 20:08
  • 1
    @Stanojkovic I did say "`Intent.ACTION_SEND` can send Email with attachment" in "what I have known/done" section, right? So I know how to attach file using `Intent.ACTION_SEND`. I know that very very very clearly. – ywwynm May 21 '16 at 02:31

2 Answers2

0

Try the below code to Send a mail

String filename="filename.vcf"; 
File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);
Uri path = Uri.fromFile(filelocation); 
Intent emailIntent = new Intent(Intent.ACTION_SEND);
// set the type to 'email'
emailIntent .setType("vnd.android.cursor.dir/email");
String to[] = {"asd@gmail.com"};
emailIntent .putExtra(Intent.EXTRA_EMAIL, to);
// the attachment
emailIntent .putExtra(Intent.EXTRA_STREAM, path);
// the mail subject
emailIntent .putExtra(Intent.EXTRA_SUBJECT, "Subject");
startActivity(Intent.createChooser(emailIntent , "Send email..."));
Jayaprakash G
  • 2,537
  • 1
  • 14
  • 10
-2

There are two ways to do this

OPTION 1

 Intent emailIntent = new Intent(
            android.content.Intent.ACTION_VIEW);

     
     //Option 1
    Uri data = Uri.parse("mailto:?subject=" + "blah blah subject"
            + "&body=" + "blah blah body" + "&to=" + "sendme@me.com");
    emailIntent.setData(data);

    startActivity(Intent.createChooser(emailIntent, ""));

Result

enter image description here

OPTION 2

It works perfactly except it wont filter out FTP

    //Option 2
  emailIntent = new Intent(
            android.content.Intent.ACTION_SEND);
    emailIntent.setType("message/rfc822");
    final String[] toRecipients = new String[] { "sendme@me.com", "", };
    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, toRecipients);
    emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "blah blah subject");
    emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
            Html.fromHtml("blah blah body"));

    startActivity(Intent.createChooser(emailIntent, ""));

Result

enter image description here

Both ways have minor flaws I show you both ways it is now upto you to pick one.

Community
  • 1
  • 1
Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154