From 79258562596d739a7fdf80d8b8bd2c95733adbc1 Mon Sep 17 00:00:00 2001 From: fdecampredon Date: Wed, 17 Nov 2021 16:46:53 +0100 Subject: [PATCH 1/3] Add attachments options to include img to messages --- www/sms.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/www/sms.js b/www/sms.js index 1d68baf..b829189 100644 --- a/www/sms.js +++ b/www/sms.js @@ -22,6 +22,7 @@ sms.send = function(phone, message, options, success, failure) { // parsing options var replaceLineBreaks = false; var androidIntent = ''; + var attachments = null; if (typeof options === 'string') { // ensuring backward compatibility window.console.warn('[DEPRECATED] Passing a string as a third argument is deprecated. Please refer to the documentation to pass the right parameter: https://github.com/cordova-sms/cordova-sms-plugin.'); androidIntent = options; @@ -31,6 +32,13 @@ sms.send = function(phone, message, options, success, failure) { if (options.android && typeof options.android === 'object') { androidIntent = options.android.intent; } + if (options.attachments) { + if (Array.isArray(options.attachments)) { + attachments = options.attachments; + } else { + attachments = [options.attachments] + } + } } // fire @@ -38,7 +46,7 @@ sms.send = function(phone, message, options, success, failure) { success, failure, 'Sms', - 'send', [phone, message, androidIntent, replaceLineBreaks] + 'send', [phone, message, androidIntent, replaceLineBreaks, attachments] ); }; From fd16a945852b697abfc20dad4253fe8c41b46097 Mon Sep 17 00:00:00 2001 From: fdecampredon Date: Wed, 17 Nov 2021 16:47:06 +0100 Subject: [PATCH 2/3] Implement attachments for IOS --- src/ios/Sms.m | 15 +++++++++++++++ www/sms.js | 6 +----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/ios/Sms.m b/src/ios/Sms.m index 202cb8a..b39947e 100644 --- a/src/ios/Sms.m +++ b/src/ios/Sms.m @@ -47,6 +47,21 @@ - (void)send:(CDVInvokedUrlCommand*)command { [composeViewController setRecipients:recipients]; } + + NSMutableDictionary* attachments = [command.arguments objectAtIndex:4]; + if (attachments != nil && ![attachments isEqual:[NSNull null]]) { + for (NSString* filename in attachments) { + NSString* imgStr = [attachments objectForKey:filename]; + NSData *data = [[NSData alloc] initWithBase64EncodedString:imgStr options:0]; + UIImage *image = [UIImage imageWithData:data]; + if (image != nil) { + NSData* attachment = UIImageJPEGRepresentation(image, 1.0); + [composeViewController + addAttachmentData:attachment + typeIdentifier:@"public.jpeg" filename:filename]; + } + } + } [self.viewController presentViewController:composeViewController animated:YES completion:nil]; }); }]; diff --git a/www/sms.js b/www/sms.js index b829189..eb94bd5 100644 --- a/www/sms.js +++ b/www/sms.js @@ -33,11 +33,7 @@ sms.send = function(phone, message, options, success, failure) { androidIntent = options.android.intent; } if (options.attachments) { - if (Array.isArray(options.attachments)) { - attachments = options.attachments; - } else { - attachments = [options.attachments] - } + attachments = options.attachments; } } From 10f1082ef95d6aaab3a9b29d32a679cc3c2669bd Mon Sep 17 00:00:00 2001 From: fdecampredon Date: Fri, 19 Nov 2021 00:06:15 +0100 Subject: [PATCH 3/3] Partial implementation of attachments for Android --- plugin.xml | 15 ++++ src/android/Sms.java | 94 +++++++++++++++++++++-- src/android/xml/cordova_sms_filepaths.xml | 4 + 3 files changed, 106 insertions(+), 7 deletions(-) create mode 100644 src/android/xml/cordova_sms_filepaths.xml diff --git a/plugin.xml b/plugin.xml index eb282b4..ab777fd 100644 --- a/plugin.xml +++ b/plugin.xml @@ -23,12 +23,27 @@ + + + + + + + diff --git a/src/android/Sms.java b/src/android/Sms.java index 5244a07..c37eecb 100644 --- a/src/android/Sms.java +++ b/src/android/Sms.java @@ -12,13 +12,26 @@ import android.os.Build; import android.provider.Telephony; import android.telephony.SmsManager; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import android.util.Base64; import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.PluginResult; import org.json.JSONArray; +import org.json.JSONObject; import org.json.JSONException; +import androidx.core.content.FileProvider; + public class Sms extends CordovaPlugin { public final String ACTION_SEND_SMS = "send"; @@ -103,6 +116,11 @@ public void run() { String message = args.getString(1); String method = args.getString(2); boolean replaceLineBreaks = Boolean.parseBoolean(args.getString(3)); + JSONObject attachments = null; + + if (!args.isNull(4)) { + attachments = args.getJSONObject(4); + } // replacing \n by new line if the parameter replaceLineBreaks is set to true if (replaceLineBreaks) { @@ -113,9 +131,7 @@ public void run() { return; } if (method.equalsIgnoreCase("INTENT")) { - invokeSMSIntent(phoneNumber, message); - // always passes success back to the app - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK)); + invokeSMSIntent(phoneNumber, message, attachments); } else { send(callbackContext, phoneNumber, message); } @@ -134,18 +150,66 @@ private boolean checkSupport() { } @SuppressLint("NewApi") - private void invokeSMSIntent(String phoneNumber, String message) { + private void invokeSMSIntent(String phoneNumber, String message, JSONObject attachments) { Intent sendIntent; - if ("".equals(phoneNumber) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + List images = null; + + if (attachments != null) { + Iterator keys = attachments.keys(); + while(keys.hasNext()) { + String fileName = keys.next(); + String base64String; + try { + base64String = attachments.getString(fileName); + } catch (JSONException e) { + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); + return; + } + byte[] imgBytes = Base64.decode(base64String, Base64.DEFAULT); + + File tmpDir = cordova.getContext().getCacheDir(); + File imgFile = new File(tmpDir, fileName); + + try { + imgFile.createNewFile(); + } catch (IOException e) { + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION)); + } + + try (OutputStream stream = new FileOutputStream(imgFile)) { + stream.write(imgBytes); + } catch (NullPointerException e) { + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR)); + } catch (IOException e) { + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION)); + } + if (images == null) { + images = new ArrayList<>(); + } + images.add(imgFile); + } + } + + final boolean hasImage = images != null; + final boolean hasMultipleImages = hasImage && images.size() > 1; + final boolean emptyPhoneNumber = "".equals(phoneNumber); + + if ((emptyPhoneNumber || hasImage) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(this.cordova.getActivity()); - sendIntent = new Intent(Intent.ACTION_SEND); - sendIntent.setType("text/plain"); + sendIntent = new Intent(hasMultipleImages ? Intent.ACTION_SEND_MULTIPLE : Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, message); + if (!emptyPhoneNumber) { + // See http://stackoverflow.com/questions/7242190/sending-sms-using-intent-does-not-add-recipients-on-some-devices + sendIntent.putExtra("address", phoneNumber); + sendIntent.setData(Uri.parse("smsto:" + Uri.encode(phoneNumber))); + } + if (defaultSmsPackageName != null) { sendIntent.setPackage(defaultSmsPackageName); } + sendIntent.setType( hasImage ? "image/*" : "text/plain"); } else { sendIntent = new Intent(Intent.ACTION_VIEW); sendIntent.putExtra("sms_body", message); @@ -153,6 +217,22 @@ private void invokeSMSIntent(String phoneNumber, String message) { sendIntent.putExtra("address", phoneNumber); sendIntent.setData(Uri.parse("smsto:" + Uri.encode(phoneNumber))); } + + if (hasImage) { + String FILE_AUTHORITY = cordova.getContext().getPackageName() + ".cordova.plugins.sms.fileprovider"; + + ArrayList imageUris = images.stream() + .map(file -> FileProvider.getUriForFile(cordova.getContext(), FILE_AUTHORITY, file)) + .collect(Collectors.toCollection(ArrayList::new)); + if (hasMultipleImages) { + sendIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris); + } else { + sendIntent.putExtra(Intent.EXTRA_STREAM, imageUris.get(0)); + } + sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK)); this.cordova.getActivity().startActivity(sendIntent); } diff --git a/src/android/xml/cordova_sms_filepaths.xml b/src/android/xml/cordova_sms_filepaths.xml new file mode 100644 index 0000000..e7d109d --- /dev/null +++ b/src/android/xml/cordova_sms_filepaths.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file