From ae39a8de90e1db20d2abc77ef1c0b398b8302d3b Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Wed, 8 Nov 2017 12:41:42 +0000 Subject: [PATCH 01/11] Rebase mult-attachment PR --- RNMail/RNMail.m | 101 +++++++++--------- .../java/com/chirag/RNMail/RNMailModule.java | 43 ++++---- 2 files changed, 76 insertions(+), 68 deletions(-) diff --git a/RNMail/RNMail.m b/RNMail/RNMail.m index 2e95e44..abe1d7d 100644 --- a/RNMail/RNMail.m +++ b/RNMail/RNMail.m @@ -41,7 +41,7 @@ + (BOOL)requiresMainQueueSetup NSString *subject = [RCTConvert NSString:options[@"subject"]]; [mail setSubject:subject]; } - + bool *isHTML = NO; if (options[@"isHTML"]){ @@ -57,7 +57,7 @@ + (BOOL)requiresMainQueueSetup NSArray *recipients = [RCTConvert NSArray:options[@"recipients"]]; [mail setToRecipients:recipients]; } - + if (options[@"ccRecipients"]){ NSArray *ccRecipients = [RCTConvert NSArray:options[@"ccRecipients"]]; [mail setCcRecipients:ccRecipients]; @@ -67,55 +67,58 @@ + (BOOL)requiresMainQueueSetup NSArray *bccRecipients = [RCTConvert NSArray:options[@"bccRecipients"]]; [mail setBccRecipients:bccRecipients]; } - - if (options[@"attachment"] && options[@"attachment"][@"path"] && options[@"attachment"][@"type"]){ - NSString *attachmentPath = [RCTConvert NSString:options[@"attachment"][@"path"]]; - NSString *attachmentType = [RCTConvert NSString:options[@"attachment"][@"type"]]; - NSString *attachmentName = [RCTConvert NSString:options[@"attachment"][@"name"]]; - - // Set default filename if not specificed - if (!attachmentName) { - attachmentName = [[attachmentPath lastPathComponent] stringByDeletingPathExtension]; - } - - // Get the resource path and read the file using NSData - NSData *fileData = [NSData dataWithContentsOfFile:attachmentPath]; - - // Determine the MIME type - NSString *mimeType; - - /* - * Add additional mime types and PR if necessary. Find the list - * of supported formats at http://www.iana.org/assignments/media-types/media-types.xhtml - */ - if ([attachmentType isEqualToString:@"jpg"]) { - mimeType = @"image/jpeg"; - } else if ([attachmentType isEqualToString:@"png"]) { - mimeType = @"image/png"; - } else if ([attachmentType isEqualToString:@"doc"]) { - mimeType = @"application/msword"; - } else if ([attachmentType isEqualToString:@"ppt"]) { - mimeType = @"application/vnd.ms-powerpoint"; - } else if ([attachmentType isEqualToString:@"html"]) { - mimeType = @"text/html"; - } else if ([attachmentType isEqualToString:@"csv"]) { - mimeType = @"text/csv"; - } else if ([attachmentType isEqualToString:@"pdf"]) { - mimeType = @"application/pdf"; - } else if ([attachmentType isEqualToString:@"vcard"]) { - mimeType = @"text/vcard"; - } else if ([attachmentType isEqualToString:@"json"]) { - mimeType = @"application/json"; - } else if ([attachmentType isEqualToString:@"zip"]) { - mimeType = @"application/zip"; - } else if ([attachmentType isEqualToString:@"text"]) { - mimeType = @"text/*"; + + if (options[@"attachments"]){ + NSArray *attachments = [RCTConvert NSArray:options[@"attachments"]]; + + for(NSDictionary *attachment in attachments) { + if (attachment[@"path"] && attachment[@"type"]) { + NSString *attachmentPath = [RCTConvert NSString:attachment[@"path"]]; + NSString *attachmentType = [RCTConvert NSString:attachment[@"type"]]; + NSString *attachmentName = [RCTConvert NSString:attachment[@"name"]]; + + // Set default filename if not specificed + if (!attachmentName) { + attachmentName = [[attachmentPath lastPathComponent] stringByDeletingPathExtension]; + } + // Get the resource path and read the file using NSData + NSData *fileData = [NSData dataWithContentsOfFile:attachmentPath]; + + // Determine the MIME type + NSString *mimeType; + + /* + * Add additional mime types and PR if necessary. Find the list + * of supported formats at http://www.iana.org/assignments/media-types/media-types.xhtml + */ + if ([attachmentType isEqualToString:@"jpg"]) { + mimeType = @"image/jpeg"; + } else if ([attachmentType isEqualToString:@"png"]) { + mimeType = @"image/png"; + } else if ([attachmentType isEqualToString:@"doc"]) { + mimeType = @"application/msword"; + } else if ([attachmentType isEqualToString:@"ppt"]) { + mimeType = @"application/vnd.ms-powerpoint"; + } else if ([attachmentType isEqualToString:@"html"]) { + mimeType = @"text/html"; + } else if ([attachmentType isEqualToString:@"csv"]) { + mimeType = @"text/csv"; + } else if ([attachmentType isEqualToString:@"pdf"]) { + mimeType = @"application/pdf"; + } else if ([attachmentType isEqualToString:@"vcard"]) { + mimeType = @"text/vcard"; + } else if ([attachmentType isEqualToString:@"json"]) { + mimeType = @"application/json"; + } else if ([attachmentType isEqualToString:@"zip"]) { + mimeType = @"application/zip"; + } else if ([attachmentType isEqualToString:@"text"]) { + mimeType = @"text/*"; + } + [mail addAttachmentData:fileData mimeType:mimeType fileName:attachmentName]; + } } - - // Add attachment - [mail addAttachmentData:fileData mimeType:mimeType fileName:attachmentName]; } - + UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; while (root.presentedViewController) { diff --git a/android/src/main/java/com/chirag/RNMail/RNMailModule.java b/android/src/main/java/com/chirag/RNMail/RNMailModule.java index 658ce6a..613e1bc 100644 --- a/android/src/main/java/com/chirag/RNMail/RNMailModule.java +++ b/android/src/main/java/com/chirag/RNMail/RNMailModule.java @@ -66,34 +66,39 @@ public void mail(ReadableMap options, Callback callback) { i.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(body)); } else { i.putExtra(Intent.EXTRA_TEXT, body); - } + } } if (options.hasKey("recipients") && !options.isNull("recipients")) { ReadableArray recipients = options.getArray("recipients"); i.putExtra(Intent.EXTRA_EMAIL, readableArrayToStringArray(recipients)); - } + } if (options.hasKey("ccRecipients") && !options.isNull("ccRecipients")) { ReadableArray ccRecipients = options.getArray("ccRecipients"); i.putExtra(Intent.EXTRA_CC, readableArrayToStringArray(ccRecipients)); } + if (options.hasKey("attachments") && !options.isNull("attachments")) { + ReadableArray r = options.getArray("attachments"); + int length = r.size(); + ArrayList uris = new ArrayList(); + for (int keyIndex = 0; keyIndex < length; keyIndex++) { + ReadableMap clip = r.getMap(keyIndex); + if (clip.hasKey("path") && !clip.isNull("path")){ + String path = clip.getString("path"); + File file = new File(path); + Uri u = Uri.fromFile(file); + uris.add(u); + } + } + i.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); + } if (options.hasKey("bccRecipients") && !options.isNull("bccRecipients")) { ReadableArray bccRecipients = options.getArray("bccRecipients"); i.putExtra(Intent.EXTRA_BCC, readableArrayToStringArray(bccRecipients)); } - if (options.hasKey("attachment") && !options.isNull("attachment")) { - ReadableMap attachment = options.getMap("attachment"); - if (attachment.hasKey("path") && !attachment.isNull("path")) { - String path = attachment.getString("path"); - File file = new File(path); - Uri p = Uri.fromFile(file); - i.putExtra(Intent.EXTRA_STREAM, p); - } - } - PackageManager manager = reactContext.getPackageManager(); List list = manager.queryIntentActivities(i, 0); @@ -110,14 +115,14 @@ public void mail(ReadableMap options, Callback callback) { callback.invoke("error"); } } else { - Intent chooser = Intent.createChooser(i, "Send Mail"); - chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Intent chooser = Intent.createChooser(i, "Send Mail"); + chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - reactContext.startActivity(chooser); - } catch (Exception ex) { - callback.invoke("error"); - } + try { + reactContext.startActivity(chooser); + } catch (Exception ex) { + callback.invoke("error"); } } } +} From 4a02c4d39034646e8a622fb08a221796b6fedbc6 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Wed, 8 Nov 2017 12:52:43 +0000 Subject: [PATCH 02/11] Add iOS audio MIME types --- RNMail/RNMail.m | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/RNMail/RNMail.m b/RNMail/RNMail.m index abe1d7d..e7d48d7 100644 --- a/RNMail/RNMail.m +++ b/RNMail/RNMail.m @@ -113,6 +113,16 @@ + (BOOL)requiresMainQueueSetup mimeType = @"application/zip"; } else if ([attachmentType isEqualToString:@"text"]) { mimeType = @"text/*"; + } else if ([attachmentType isEqualToString:@"mp3"]) { + mimeType = @"audio/mpeg"; + } else if ([attachmentType isEqualToString:@"wav"]) { + mimeType = @"audio/wav"; + } else if ([attachmentType isEqualToString:@"aiff"]) { + mimeType = @"audio/aiff"; + } else if ([attachmentType isEqualToString:@"flac"]) { + mimeType = @"audio/flac"; + } else if ([attachmentType isEqualToString:@"ogg"]) { + mimeType = @"audio/ogg"; } [mail addAttachmentData:fileData mimeType:mimeType fileName:attachmentName]; } From ecfd0a339e779c614cbc38d290cbfa233da3a99c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kne=C5=BEevi=C4=87?= Date: Mon, 11 Dec 2017 10:27:54 +0100 Subject: [PATCH 03/11] Fix multimple attachments android --- .../java/com/chirag/RNMail/RNMailModule.java | 64 +++++++++++-------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/android/src/main/java/com/chirag/RNMail/RNMailModule.java b/android/src/main/java/com/chirag/RNMail/RNMailModule.java index 613e1bc..95e34d2 100644 --- a/android/src/main/java/com/chirag/RNMail/RNMailModule.java +++ b/android/src/main/java/com/chirag/RNMail/RNMailModule.java @@ -6,15 +6,17 @@ import android.net.Uri; import android.text.Html; +import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.ReadableMap; -import java.util.List; import java.io.File; +import java.util.ArrayList; +import java.util.List; + /** * NativeModule that allows JS to open emails sending apps chooser. @@ -34,12 +36,11 @@ public String getName() { } /** - * Converts a ReadableArray to a String array - * - * @param r the ReadableArray instance to convert - * - * @return array of strings - */ + * Converts a ReadableArray to a String array + * + * @param r the ReadableArray instance to convert + * @return array of strings + */ private String[] readableArrayToStringArray(ReadableArray r) { int length = r.size(); String[] strArray = new String[length]; @@ -53,8 +54,9 @@ private String[] readableArrayToStringArray(ReadableArray r) { @ReactMethod public void mail(ReadableMap options, Callback callback) { - Intent i = new Intent(Intent.ACTION_SENDTO); - i.setData(Uri.parse("mailto:")); + Intent i = new Intent(Intent.ACTION_SEND_MULTIPLE); + i.setType("message/rfc822"); + if (options.hasKey("subject") && !options.isNull("subject")) { i.putExtra(Intent.EXTRA_SUBJECT, options.getString("subject")); @@ -66,38 +68,46 @@ public void mail(ReadableMap options, Callback callback) { i.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(body)); } else { i.putExtra(Intent.EXTRA_TEXT, body); - } + } } if (options.hasKey("recipients") && !options.isNull("recipients")) { ReadableArray recipients = options.getArray("recipients"); i.putExtra(Intent.EXTRA_EMAIL, readableArrayToStringArray(recipients)); - } + } if (options.hasKey("ccRecipients") && !options.isNull("ccRecipients")) { ReadableArray ccRecipients = options.getArray("ccRecipients"); i.putExtra(Intent.EXTRA_CC, readableArrayToStringArray(ccRecipients)); } + + if (options.hasKey("bccRecipients") && !options.isNull("bccRecipients")) { + ReadableArray bccRecipients = options.getArray("bccRecipients"); + i.putExtra(Intent.EXTRA_BCC, readableArrayToStringArray(bccRecipients)); + } + if (options.hasKey("attachments") && !options.isNull("attachments")) { ReadableArray r = options.getArray("attachments"); int length = r.size(); ArrayList uris = new ArrayList(); for (int keyIndex = 0; keyIndex < length; keyIndex++) { ReadableMap clip = r.getMap(keyIndex); - if (clip.hasKey("path") && !clip.isNull("path")){ + if (clip.hasKey("path") && !clip.isNull("path")) { String path = clip.getString("path"); File file = new File(path); - Uri u = Uri.fromFile(file); - uris.add(u); + if (file.exists()) { + uris.add(Uri.fromFile(file)); + } } } i.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); } - if (options.hasKey("bccRecipients") && !options.isNull("bccRecipients")) { - ReadableArray bccRecipients = options.getArray("bccRecipients"); - i.putExtra(Intent.EXTRA_BCC, readableArrayToStringArray(bccRecipients)); - } + i.setType(null); // If we're using a selector, then clear the type to null. I don't know why this is needed, but it doesn't work without it. + final Intent restrictIntent = new Intent(Intent.ACTION_SENDTO); + Uri data = Uri.parse("mailto:?to=some@email.com"); + restrictIntent.setData(data); + i.setSelector(restrictIntent); PackageManager manager = reactContext.getPackageManager(); List list = manager.queryIntentActivities(i, 0); @@ -115,14 +125,12 @@ public void mail(ReadableMap options, Callback callback) { callback.invoke("error"); } } else { - Intent chooser = Intent.createChooser(i, "Send Mail"); - chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - - try { - reactContext.startActivity(chooser); - } catch (Exception ex) { - callback.invoke("error"); + Intent chooser = Intent.createChooser(i, "Send Mail"); + chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + reactContext.startActivity(chooser); + } catch (Exception ex) { + } } } } -} From 0128cb3f634f35a4c08c0986d41205585bcfc4e2 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Mon, 11 Dec 2017 09:41:45 +0000 Subject: [PATCH 04/11] Revert "Fix multimple attachments android" --- .../java/com/chirag/RNMail/RNMailModule.java | 64 ++++++++----------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/android/src/main/java/com/chirag/RNMail/RNMailModule.java b/android/src/main/java/com/chirag/RNMail/RNMailModule.java index 95e34d2..613e1bc 100644 --- a/android/src/main/java/com/chirag/RNMail/RNMailModule.java +++ b/android/src/main/java/com/chirag/RNMail/RNMailModule.java @@ -6,17 +6,15 @@ import android.net.Uri; import android.text.Html; -import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.Callback; -import java.io.File; -import java.util.ArrayList; import java.util.List; - +import java.io.File; /** * NativeModule that allows JS to open emails sending apps chooser. @@ -36,11 +34,12 @@ public String getName() { } /** - * Converts a ReadableArray to a String array - * - * @param r the ReadableArray instance to convert - * @return array of strings - */ + * Converts a ReadableArray to a String array + * + * @param r the ReadableArray instance to convert + * + * @return array of strings + */ private String[] readableArrayToStringArray(ReadableArray r) { int length = r.size(); String[] strArray = new String[length]; @@ -54,9 +53,8 @@ private String[] readableArrayToStringArray(ReadableArray r) { @ReactMethod public void mail(ReadableMap options, Callback callback) { - Intent i = new Intent(Intent.ACTION_SEND_MULTIPLE); - i.setType("message/rfc822"); - + Intent i = new Intent(Intent.ACTION_SENDTO); + i.setData(Uri.parse("mailto:")); if (options.hasKey("subject") && !options.isNull("subject")) { i.putExtra(Intent.EXTRA_SUBJECT, options.getString("subject")); @@ -68,46 +66,38 @@ public void mail(ReadableMap options, Callback callback) { i.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(body)); } else { i.putExtra(Intent.EXTRA_TEXT, body); - } + } } if (options.hasKey("recipients") && !options.isNull("recipients")) { ReadableArray recipients = options.getArray("recipients"); i.putExtra(Intent.EXTRA_EMAIL, readableArrayToStringArray(recipients)); - } + } if (options.hasKey("ccRecipients") && !options.isNull("ccRecipients")) { ReadableArray ccRecipients = options.getArray("ccRecipients"); i.putExtra(Intent.EXTRA_CC, readableArrayToStringArray(ccRecipients)); } - - if (options.hasKey("bccRecipients") && !options.isNull("bccRecipients")) { - ReadableArray bccRecipients = options.getArray("bccRecipients"); - i.putExtra(Intent.EXTRA_BCC, readableArrayToStringArray(bccRecipients)); - } - if (options.hasKey("attachments") && !options.isNull("attachments")) { ReadableArray r = options.getArray("attachments"); int length = r.size(); ArrayList uris = new ArrayList(); for (int keyIndex = 0; keyIndex < length; keyIndex++) { ReadableMap clip = r.getMap(keyIndex); - if (clip.hasKey("path") && !clip.isNull("path")) { + if (clip.hasKey("path") && !clip.isNull("path")){ String path = clip.getString("path"); File file = new File(path); - if (file.exists()) { - uris.add(Uri.fromFile(file)); - } + Uri u = Uri.fromFile(file); + uris.add(u); } } i.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); } - i.setType(null); // If we're using a selector, then clear the type to null. I don't know why this is needed, but it doesn't work without it. - final Intent restrictIntent = new Intent(Intent.ACTION_SENDTO); - Uri data = Uri.parse("mailto:?to=some@email.com"); - restrictIntent.setData(data); - i.setSelector(restrictIntent); + if (options.hasKey("bccRecipients") && !options.isNull("bccRecipients")) { + ReadableArray bccRecipients = options.getArray("bccRecipients"); + i.putExtra(Intent.EXTRA_BCC, readableArrayToStringArray(bccRecipients)); + } PackageManager manager = reactContext.getPackageManager(); List list = manager.queryIntentActivities(i, 0); @@ -125,12 +115,14 @@ public void mail(ReadableMap options, Callback callback) { callback.invoke("error"); } } else { - Intent chooser = Intent.createChooser(i, "Send Mail"); - chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - reactContext.startActivity(chooser); - } catch (Exception ex) { - } + Intent chooser = Intent.createChooser(i, "Send Mail"); + chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + try { + reactContext.startActivity(chooser); + } catch (Exception ex) { + callback.invoke("error"); } } } +} From 03665257ea4da34417cb5d2838a52ff58ef0172c Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Mon, 11 Dec 2017 09:43:33 +0000 Subject: [PATCH 05/11] Revert "Revert "Fix multimple attachments android"" --- .../java/com/chirag/RNMail/RNMailModule.java | 64 +++++++++++-------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/android/src/main/java/com/chirag/RNMail/RNMailModule.java b/android/src/main/java/com/chirag/RNMail/RNMailModule.java index 613e1bc..95e34d2 100644 --- a/android/src/main/java/com/chirag/RNMail/RNMailModule.java +++ b/android/src/main/java/com/chirag/RNMail/RNMailModule.java @@ -6,15 +6,17 @@ import android.net.Uri; import android.text.Html; +import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.ReadableMap; -import java.util.List; import java.io.File; +import java.util.ArrayList; +import java.util.List; + /** * NativeModule that allows JS to open emails sending apps chooser. @@ -34,12 +36,11 @@ public String getName() { } /** - * Converts a ReadableArray to a String array - * - * @param r the ReadableArray instance to convert - * - * @return array of strings - */ + * Converts a ReadableArray to a String array + * + * @param r the ReadableArray instance to convert + * @return array of strings + */ private String[] readableArrayToStringArray(ReadableArray r) { int length = r.size(); String[] strArray = new String[length]; @@ -53,8 +54,9 @@ private String[] readableArrayToStringArray(ReadableArray r) { @ReactMethod public void mail(ReadableMap options, Callback callback) { - Intent i = new Intent(Intent.ACTION_SENDTO); - i.setData(Uri.parse("mailto:")); + Intent i = new Intent(Intent.ACTION_SEND_MULTIPLE); + i.setType("message/rfc822"); + if (options.hasKey("subject") && !options.isNull("subject")) { i.putExtra(Intent.EXTRA_SUBJECT, options.getString("subject")); @@ -66,38 +68,46 @@ public void mail(ReadableMap options, Callback callback) { i.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(body)); } else { i.putExtra(Intent.EXTRA_TEXT, body); - } + } } if (options.hasKey("recipients") && !options.isNull("recipients")) { ReadableArray recipients = options.getArray("recipients"); i.putExtra(Intent.EXTRA_EMAIL, readableArrayToStringArray(recipients)); - } + } if (options.hasKey("ccRecipients") && !options.isNull("ccRecipients")) { ReadableArray ccRecipients = options.getArray("ccRecipients"); i.putExtra(Intent.EXTRA_CC, readableArrayToStringArray(ccRecipients)); } + + if (options.hasKey("bccRecipients") && !options.isNull("bccRecipients")) { + ReadableArray bccRecipients = options.getArray("bccRecipients"); + i.putExtra(Intent.EXTRA_BCC, readableArrayToStringArray(bccRecipients)); + } + if (options.hasKey("attachments") && !options.isNull("attachments")) { ReadableArray r = options.getArray("attachments"); int length = r.size(); ArrayList uris = new ArrayList(); for (int keyIndex = 0; keyIndex < length; keyIndex++) { ReadableMap clip = r.getMap(keyIndex); - if (clip.hasKey("path") && !clip.isNull("path")){ + if (clip.hasKey("path") && !clip.isNull("path")) { String path = clip.getString("path"); File file = new File(path); - Uri u = Uri.fromFile(file); - uris.add(u); + if (file.exists()) { + uris.add(Uri.fromFile(file)); + } } } i.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); } - if (options.hasKey("bccRecipients") && !options.isNull("bccRecipients")) { - ReadableArray bccRecipients = options.getArray("bccRecipients"); - i.putExtra(Intent.EXTRA_BCC, readableArrayToStringArray(bccRecipients)); - } + i.setType(null); // If we're using a selector, then clear the type to null. I don't know why this is needed, but it doesn't work without it. + final Intent restrictIntent = new Intent(Intent.ACTION_SENDTO); + Uri data = Uri.parse("mailto:?to=some@email.com"); + restrictIntent.setData(data); + i.setSelector(restrictIntent); PackageManager manager = reactContext.getPackageManager(); List list = manager.queryIntentActivities(i, 0); @@ -115,14 +125,12 @@ public void mail(ReadableMap options, Callback callback) { callback.invoke("error"); } } else { - Intent chooser = Intent.createChooser(i, "Send Mail"); - chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - - try { - reactContext.startActivity(chooser); - } catch (Exception ex) { - callback.invoke("error"); + Intent chooser = Intent.createChooser(i, "Send Mail"); + chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + reactContext.startActivity(chooser); + } catch (Exception ex) { + } } } } -} From e85c5265c659c18dd80625f428f88ffc26230ad3 Mon Sep 17 00:00:00 2001 From: Tim Scott Date: Thu, 28 Dec 2017 12:10:27 -0600 Subject: [PATCH 06/11] Fixed a syntax error in RNMailModule. --- android/src/main/java/com/chirag/RNMail/RNMailModule.java | 1 - 1 file changed, 1 deletion(-) diff --git a/android/src/main/java/com/chirag/RNMail/RNMailModule.java b/android/src/main/java/com/chirag/RNMail/RNMailModule.java index fc32b30..ded5476 100644 --- a/android/src/main/java/com/chirag/RNMail/RNMailModule.java +++ b/android/src/main/java/com/chirag/RNMail/RNMailModule.java @@ -150,4 +150,3 @@ public void mail(ReadableMap options, Callback callback) { } } } -} From ac92e5d8468aaebeaa6517a896789c485dcfd3d0 Mon Sep 17 00:00:00 2001 From: Tim Scott Date: Thu, 28 Dec 2017 13:52:59 -0600 Subject: [PATCH 07/11] Fixed various issue in android with multiple attachments. --- .../java/com/chirag/RNMail/RNMailModule.java | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/android/src/main/java/com/chirag/RNMail/RNMailModule.java b/android/src/main/java/com/chirag/RNMail/RNMailModule.java index ded5476..200a81e 100644 --- a/android/src/main/java/com/chirag/RNMail/RNMailModule.java +++ b/android/src/main/java/com/chirag/RNMail/RNMailModule.java @@ -80,21 +80,6 @@ public void mail(ReadableMap options, Callback callback) { ReadableArray ccRecipients = options.getArray("ccRecipients"); i.putExtra(Intent.EXTRA_CC, readableArrayToStringArray(ccRecipients)); } - if (options.hasKey("attachments") && !options.isNull("attachments")) { - ReadableArray r = options.getArray("attachments"); - int length = r.size(); - ArrayList uris = new ArrayList(); - for (int keyIndex = 0; keyIndex < length; keyIndex++) { - ReadableMap clip = r.getMap(keyIndex); - if (clip.hasKey("path") && !clip.isNull("path")){ - String path = clip.getString("path"); - File file = new File(path); - Uri u = Uri.fromFile(file); - uris.add(u); - } - } - i.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); - } if (options.hasKey("bccRecipients") && !options.isNull("bccRecipients")) { ReadableArray bccRecipients = options.getArray("bccRecipients"); @@ -110,6 +95,7 @@ public void mail(ReadableMap options, Callback callback) { if (clip.hasKey("path") && !clip.isNull("path")) { String path = clip.getString("path"); File file = new File(path); + file.setReadable(true, false); if (file.exists()) { uris.add(Uri.fromFile(file)); } @@ -118,12 +104,6 @@ public void mail(ReadableMap options, Callback callback) { i.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); } - i.setType(null); // If we're using a selector, then clear the type to null. I don't know why this is needed, but it doesn't work without it. - final Intent restrictIntent = new Intent(Intent.ACTION_SENDTO); - Uri data = Uri.parse("mailto:?to=some@email.com"); - restrictIntent.setData(data); - i.setSelector(restrictIntent); - PackageManager manager = reactContext.getPackageManager(); List list = manager.queryIntentActivities(i, 0); @@ -145,6 +125,7 @@ public void mail(ReadableMap options, Callback callback) { try { reactContext.startActivity(chooser); } catch (Exception ex) { + callback.invoke("error"); } } From 35e958a8687e3497b50b54842c1380a5f8d5c88a Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Thu, 28 Dec 2017 21:12:35 +0000 Subject: [PATCH 08/11] Update README for multiple attachments update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f0d9597..0e9f978 100644 --- a/README.md +++ b/README.md @@ -125,11 +125,11 @@ export default class App extends Component { bccRecipients: ['supportBCC@example.com'], body: 'A Bold Body', isHTML: true, - attachment: { + attachments: {[ path: '', // The absolute path of the file from which to read data. type: '', // Mime Type: jpg, png, doc, ppt, html, pdf name: '', // Optional: Custom filename for attachment - } + ]} }, (error, event) => { Alert.alert( error, From c32ed75df4d8519642cf85f791be7e9abbc7344e Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Thu, 28 Dec 2017 21:18:03 +0000 Subject: [PATCH 09/11] Fix bracket order typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0e9f978..550cf13 100644 --- a/README.md +++ b/README.md @@ -125,11 +125,11 @@ export default class App extends Component { bccRecipients: ['supportBCC@example.com'], body: 'A Bold Body', isHTML: true, - attachments: {[ + attachments: [{ path: '', // The absolute path of the file from which to read data. type: '', // Mime Type: jpg, png, doc, ppt, html, pdf name: '', // Optional: Custom filename for attachment - ]} + }] }, (error, event) => { Alert.alert( error, From e79eb57f7ba81ee5e6c04f9374456aa200900f42 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Tue, 15 May 2018 18:08:53 +0100 Subject: [PATCH 10/11] Copy attachments as temporary files before sending This was necessary in my case as the files were local to the app. May not be necessary in other cases, in which case a boolean switch should be added. --- .../java/com/chirag/RNMail/RNMailModule.java | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/chirag/RNMail/RNMailModule.java b/android/src/main/java/com/chirag/RNMail/RNMailModule.java index 200a81e..2cb81b2 100644 --- a/android/src/main/java/com/chirag/RNMail/RNMailModule.java +++ b/android/src/main/java/com/chirag/RNMail/RNMailModule.java @@ -95,9 +95,32 @@ public void mail(ReadableMap options, Callback callback) { if (clip.hasKey("path") && !clip.isNull("path")) { String path = clip.getString("path"); File file = new File(path); - file.setReadable(true, false); - if (file.exists()) { - uris.add(Uri.fromFile(file)); + + String name, suffix = ""; + if (clip.hasKey("name")) + name = clip.getString("name"); + else + name = file.getName(); + + if (clip.hasKey("type")) + suffix = "." + clip.getString("type"); + + File temporaryFile = null; + try { + temporaryFile = File.createTempFile(name, suffix, reactContext.getExternalCacheDir()); + copy (file, temporaryFile); + } catch (IOException e) { + e.printStackTrace(); + Log.e("RNMail", "Error copying to temporary file"); + } + + temporaryFile.setReadable(true, false); + if (temporaryFile.exists()) { + if (temporaryFile.length() == 0) + Log.d ("RNMail", "Warning, attaching empty file!"); + uris.add(Uri.fromFile(temporaryFile)); + } else { + Log.e("RNMail", "Attachment file does not exist"); } } } From a4a729168be176114b4b74d55c2edf0adceeb357 Mon Sep 17 00:00:00 2001 From: Adam Wilson Date: Tue, 15 May 2018 19:10:52 +0100 Subject: [PATCH 11/11] Add missing file copy method --- .../java/com/chirag/RNMail/RNMailModule.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/android/src/main/java/com/chirag/RNMail/RNMailModule.java b/android/src/main/java/com/chirag/RNMail/RNMailModule.java index 2cb81b2..0734745 100644 --- a/android/src/main/java/com/chirag/RNMail/RNMailModule.java +++ b/android/src/main/java/com/chirag/RNMail/RNMailModule.java @@ -153,4 +153,23 @@ public void mail(ReadableMap options, Callback callback) { } } + + protected static void copy(File src, File dst) throws IOException { + InputStream in = new FileInputStream(src); + try { + OutputStream out = new FileOutputStream(dst); + try { + // Transfer bytes from in to out + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + } finally { + out.close(); + } + } finally { + in.close(); + } + } }