5

Here is how I'm sending email through Gmail App.

        Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");
        emailIntent.setType("text/html");
        emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Puzzle");
        emailIntent.putExtra(Intent.EXTRA_TEXT, someTextHere));
        emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(attachmentFile));
         try {
            startActivityForResult(emailIntent, SHARE_PUZZLE_REQUEST_CODE);
        } catch (ActivityNotFoundException e) {
            showToast("No application found on this device to perform share action");
        } catch (Exception e) {
            showToast(e.getMessage());
            e.printStackTrace();
        }

It's not starting the Gmail App but shows the following message.

java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.SEND typ=text/html cmp=com.google.android.gm/.ComposeActivityGmail (has extras) } from ProcessRecord{8293c64 26854:com.xxx.puzzleapp/u0a383} (pid=26854, uid=10383) not exported from uid 10083

There are few questions regarding this on SOF and most of them are suggested to use exported = true. But I cannot use this solution as I'm launching the activity of another app. Could you please guide me?

Santhosh
  • 4,956
  • 12
  • 62
  • 90
  • 2
    ClassName(com.google.android.gm.ComposeActivityGmail) was changed recently . Please check and give appropriate classname.Otherwise you can give directly emailIntent.setPackage("com.google.android.gm") instead of emailIntent.setClassName; – Rajasekhar Nov 16 '16 at 11:21
  • @Rajasekhar getting android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW typ=text/plain pkg=com.google.android.gm (has extras) } – Gopal Nov 19 '16 at 11:24

2 Answers2

17

Try this

        Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.setType("text/html");
        final PackageManager pm = this.getPackageManager();
        final List<ResolveInfo> matches = pm.queryIntentActivities(emailIntent, 0);
        String className = null;
        for (final ResolveInfo info : matches) {
            if (info.activityInfo.packageName.equals("com.google.android.gm")) {
                className = info.activityInfo.name;

                if(className != null && !className.isEmpty()){
                    break;
                }
            }
        }
        emailIntent.setClassName("com.google.android.gm", className);
Rajasekhar
  • 2,345
  • 1
  • 13
  • 20
3

I guess Rajasekhar is right. In my case having the same problem with a legacy app, I've looked at the reference code in G site, and used something similar to this:

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

And it worked with no issues.

PS: In my case I've no problems giving the app selector to the user. It works with every gmail version, the same code as yours, breaks the app at v6.10.23 of gmail

Victor
  • 31
  • 2