55import android .content .pm .ResolveInfo ;
66import android .net .Uri ;
77import android .text .Html ;
8+ import androidx .core .content .FileProvider ;
89
910import com .facebook .react .bridge .ReactApplicationContext ;
1011import com .facebook .react .bridge .ReactContextBaseJavaModule ;
1516
1617import java .util .List ;
1718import java .io .File ;
19+ import java .net .URI ;
1820import java .util .ArrayList ;
1921
2022/**
@@ -54,8 +56,9 @@ private String[] readableArrayToStringArray(ReadableArray r) {
5456
5557 @ ReactMethod
5658 public void mail (ReadableMap options , Callback callback ) {
57- Intent i = new Intent (Intent .ACTION_SENDTO );
58- i .setData (Uri .parse ("mailto:" ));
59+ Intent i = new Intent (Intent .ACTION_SEND_MULTIPLE );
60+ Intent selectorIntent = new Intent (Intent .ACTION_SENDTO , Uri .parse ("mailto:" ));
61+ i .setSelector (selectorIntent );
5962
6063 if (options .hasKey ("subject" ) && !options .isNull ("subject" )) {
6164 i .putExtra (Intent .EXTRA_SUBJECT , options .getString ("subject" ));
@@ -86,25 +89,33 @@ public void mail(ReadableMap options, Callback callback) {
8689 }
8790
8891 if (options .hasKey ("attachments" ) && !options .isNull ("attachments" )) {
89- ReadableArray r = options .getArray ("attachments" );
90- int length = r .size ();
91- ArrayList <Uri > uris = new ArrayList <Uri >();
92- for (int keyIndex = 0 ; keyIndex < length ; keyIndex ++) {
93- ReadableMap clip = r .getMap (keyIndex );
94- if (clip .hasKey ("path" ) && !clip .isNull ("path" )){
95- String path = clip .getString ("path" );
96- File file = new File (path );
97- Uri u = Uri .fromFile (file );
98- uris .add (u );
99- }
100- }
101-
102- if (uris .size () == 1 ) {
103- i .putExtra (Intent .EXTRA_STREAM , uris .get (0 ));
104- } else {
105- i .putParcelableArrayListExtra (Intent .EXTRA_STREAM , uris );
106- }
107- }
92+ ReadableArray r = options .getArray ("attachments" );
93+ int length = r .size ();
94+
95+ String provider = reactContext .getApplicationContext ().getPackageName () + ".rnmail.provider" ;
96+ List <ResolveInfo > resolvedIntentActivities = reactContext .getPackageManager ().queryIntentActivities (i ,
97+ PackageManager .MATCH_DEFAULT_ONLY );
98+
99+ ArrayList <Uri > uris = new ArrayList <Uri >();
100+ for (int keyIndex = 0 ; keyIndex < length ; keyIndex ++) {
101+ ReadableMap clip = r .getMap (keyIndex );
102+ if (clip .hasKey ("path" ) && !clip .isNull ("path" )){
103+ String path = clip .getString ("path" );
104+ File file = new File (path );
105+ Uri uri = FileProvider .getUriForFile (reactContext , provider , file );
106+ uris .add (uri );
107+
108+ for (ResolveInfo resolvedIntentInfo : resolvedIntentActivities ) {
109+ String packageName = resolvedIntentInfo .activityInfo .packageName ;
110+ reactContext .grantUriPermission (packageName , uri ,
111+ Intent .FLAG_GRANT_WRITE_URI_PERMISSION | Intent .FLAG_GRANT_READ_URI_PERMISSION );
112+ }
113+ }
114+ }
115+
116+ i .addFlags (Intent .FLAG_GRANT_READ_URI_PERMISSION );
117+ i .putParcelableArrayListExtra (Intent .EXTRA_STREAM , uris );
118+ }
108119
109120 PackageManager manager = reactContext .getPackageManager ();
110121 List <ResolveInfo > list = manager .queryIntentActivities (i , 0 );
@@ -123,11 +134,11 @@ public void mail(ReadableMap options, Callback callback) {
123134 }
124135 } else {
125136 String chooserTitle = "Send Mail" ;
126-
137+
127138 if (options .hasKey ("customChooserTitle" ) && !options .isNull ("customChooserTitle" )) {
128139 chooserTitle = options .getString ("customChooserTitle" );
129- }
130-
140+ }
141+
131142 Intent chooser = Intent .createChooser (i , chooserTitle );
132143 chooser .setFlags (Intent .FLAG_ACTIVITY_NEW_TASK );
133144
0 commit comments