Search code examples
androiduriemail-attachmentsfilechooser

Send multiple attachments( images and PDFs) to gmail through intent


I have a file chooser which provides me with the URI of the selected files( could be multiple or single ), now I want to send those selected files(images and pdfs) to gmail app using intent. I tried everything available online to send attachments with intent but failed to succeed. Please guide me through this this thing, have been stuck here for days.

Asking for runtime permissions using EasyPermissions:

if (!EasyPermissions.hasPermissions(AddEventActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                EasyPermissions.requestPermissions(AddEventActivity.this, "Read External data",2, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE);
            }

File chooser:

Intent chooseFile = new Intent();
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
                    chooseFile.setAction(Intent.ACTION_OPEN_DOCUMENT);
                }
                else {
                    chooseFile.setAction(Intent.ACTION_GET_CONTENT);
                }
                chooseFile.setType("*/*");
                chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
                chooseFile.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                chooseFile = Intent.createChooser(chooseFile, "Choose a file");
                startActivityForResult(chooseFile, PICKFILE_RESULT_CODE);

Storing the URI returned in a HashMap : uriMap

Gmail Intent

Intent emailSelectorIntent = new Intent(Intent.ACTION_SENDTO);
            emailSelectorIntent.setData(Uri.parse("mailto:"));
            Log.d("mailList", Arrays.toString(subarray));

            final Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
            emailIntent.putExtra(Intent.EXTRA_EMAIL, subarray);
            emailIntent.putExtra(Intent.EXTRA_SUBJECT,(CharSequence) eventName.getText().toString());
            ArrayList<String> bodyList = new ArrayList<>();
            String body = eventDesc.getText().toString() + " at " + eventVenue.getText().toString() + ", " + hourSelect + ":" + minuteSelect;
            bodyList.add(body);

            emailIntent.putExtra(Intent.EXTRA_TEXT, bodyList);
            emailIntent.setSelector(emailSelectorIntent);
            emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            emailIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            ArrayList<Uri> uris = new ArrayList<Uri>();
            Iterator iterator = uriMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry mapElement = (Map.Entry) iterator.next();
                uris.add((Uri) mapElement.getValue());
            }
            if (uris.size() != 0)
                emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);

            startActivity(Intent.createChooser(emailIntent, "Choose an email application..."));

OnActivityResult code

if multiple files are selected

for (int i = 0; i < data.getClipData().getItemCount(); i++) {
                            
Uri uri = data.getClipData().getItemAt(i).getUri();}

else if single file is selected

Uri uri;
uri = data.getData();

LogCat error

2020-08-01 16:56:16.414 30575-30575/? E/Gmail: ComposeActivity:Error adding attachment
gon: SecurityException when openAssetFileDescriptor.
    at goo.a(PG:5)
    at goo.a(PG:45)
    at dvt.a(PG:137)
    at duz.run(PG:2)
    at dvt.a(PG:176)
    at dvt.a(PG:144)
    at dvt.a(PG:443)
    at drq.a(Unknown Source:24)
    at bbkz.a(Unknown Source:19)
    at bdvu.a(Unknown Source:2)
    at bdvw.run(PG:9)
    at bdzb.run(Unknown Source:7)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
    at bbja.run(PG:2)
    at aqsr.run(Unknown Source:18)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7397)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)

Help is appreciated.

Thanks in advance.


Solution

  • Code for file chooser:

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                    intent.setType("*/*");
                    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true);
                    startActivityForResult(Intent.createChooser(intent, "ChooseFile"), PICKFILE_RESULT_CODE);
    

    Code for intent:

    Intent intent = new Intent();
                intent.setAction(Intent.ACTION_SEND_MULTIPLE);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra(Intent.EXTRA_EMAIL, subarray);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.setType("vnd.android.cursor.dir/email");
                ArrayList<Uri> uris=new ArrayList<Uri>();
                if (uriMap.size()!=0) {
                    Iterator i= uriMap.entrySet().iterator();
                    while(i.hasNext()){
                        Map.Entry mapElement = (Map.Entry) i.next();
                        uris.add((Uri)mapElement.getValue());
                    }
                    intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM,uris);
                }
                intent.setPackage("com.google.android.gm");
                startActivityForResult(intent, 101);
    

    using intent.setType() and intent.setPackage() worked for me!