0

I'm trying to send email with intent by call explicitly GMAIL in my app. It was working fine on all devices but now I got crashes on Android 6 Marshmallow devices. The problem I'm receiving is:

12-14 00:02:55.365: E/AndroidRuntime(18570): Theme: themes:{default=overlay:com.cyngn.hexo, iconPack:com.cyngn.hexoicons, fontPkg:com.cyngn.hexo, com.android.systemui=overlay:com.cyngn.hexo, com.android.systemui.navbar=overlay:com.cyngn.hexo}
12-14 00:02:55.365: E/AndroidRuntime(18570): java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.SEND_MULTIPLE typ=image/* flg=0x3 cmp=com.google.android.gm/.ComposeActivityGmail clip={image/* U:file:///storage/emulated/0/Mydir/myfile20161213105548.jpg} (has extras) } from ProcessRecord{cc9833c 18570:com.myappdr/u0a341} (pid=18570, uid=10341) not exported from uid 10050
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.os.Parcel.readException(Parcel.java:1620)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.os.Parcel.readException(Parcel.java:1573)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2677)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1509)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.app.Activity.startActivityForResult(Activity.java:3930)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.app.Activity.startActivityForResult(Activity.java:3890)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.app.Activity.startActivity(Activity.java:4213)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.app.Activity.startActivity(Activity.java:4181)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at com.myapp.SendGmail.onClick(SendGmail.java:222)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:163)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.os.Handler.dispatchMessage(Handler.java:102)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.os.Looper.loop(Looper.java:148)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at android.app.ActivityThread.main(ActivityThread.java:5461)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at java.lang.reflect.Method.invoke(Native Method)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
12-14 00:02:55.365: E/AndroidRuntime(18570):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Here are the permissions I have in my Manifest:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

And here is how I'm sending the mail in my source:

Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { "email@email.com" });
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getResources().getString(R.string.mail_title));
emailIntent.setType("image/*");

ArrayList<Uri> uris = new ArrayList<Uri>();

for (Map.Entry<CartElement,Integer> c : SingletonShoppingCart.getInstance(null).get_Cart().entrySet()){
    if ((c.getKey().getImgPath() !=null) || (!c.getKey().getImgPath().isEmpty())){
        uris.add(Uri.fromFile(new File(c.getKey().getImgPath())));
    }
}

emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,strMailMsg);
emailIntent.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
emailIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivity(emailIntent);
Floern
  • 33,559
  • 24
  • 104
  • 119
liv_fc
  • 51
  • 5
  • Please edit your question and post the entire Java stack trace. – CommonsWare Dec 13 '16 at 21:59
  • Use ACTION_SEND instead. – greenapps Dec 13 '16 at 22:05
  • I've added the whole stack trace. I'm currently able to reproduce it on my OnePlusOne phone which uses CianogenMod but the crashes in Developer Console are from Marshmallow. – liv_fc Dec 13 '16 at 22:06
  • @greenapps The problem appears with ACTION_SEND either. I'm using ACTION_SEND_MULTIPLE in my current update which is not published but I got the error on the current play store version also. – liv_fc Dec 13 '16 at 22:07
  • You should ask the user for permissions to read external storage on marshmellow. Google for run time permisions. You have a parcel read exception. Or go to the settings for your app and switch the storage permission on. – greenapps Dec 13 '16 at 22:12
  • I had the same question. [This](http://stackoverflow.com/questions/2264622/android-multiple-email-attachments-using-intent) post helped me. – wirthra Dec 13 '16 at 22:13

2 Answers2

0

FLAG_GRANT_READ_URI_PERMISSION doesn't work with file URIs such as those generated from Uri.fromFile(). You have to use content:// URIs such as from FileProvider.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
0

You have this:

emailIntent.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");

Delete it, because that is not an exported activity. That activity is available for Gmail to start, but not for third-parties to start.

Moreover, share where the user wants. Not all Android users use Gmail.

Long term, you will also need to address Ian Lake's concern, as your code will fail on Android 7.0+ devices, once you raise your targetSdkVersion to 24 or higher.

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