From 3102f9c9029324fb401551a728d80196bddf5e1f Mon Sep 17 00:00:00 2001 From: mirland Date: Mon, 11 Jul 2022 17:44:59 -0300 Subject: [PATCH 1/4] Fix send direct messages issue. The library don't allow you to send direct messages if the device has not an app to send sms --- .../example/flutter_sms/FlutterSmsPlugin.kt | 22 ++++++++++++++----- example/.flutter-plugins-dependencies | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/android/src/main/kotlin/com/example/flutter_sms/FlutterSmsPlugin.kt b/android/src/main/kotlin/com/example/flutter_sms/FlutterSmsPlugin.kt index 25af08c..ab335f5 100644 --- a/android/src/main/kotlin/com/example/flutter_sms/FlutterSmsPlugin.kt +++ b/android/src/main/kotlin/com/example/flutter_sms/FlutterSmsPlugin.kt @@ -77,12 +77,22 @@ class FlutterSmsPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { result.error( "device_not_capable", "The current device is not capable of sending text messages.", - "A device may be unable to send messages if it does not support messaging or if it is not currently configured to send messages. This only applies to the ability to send text messages via iMessage, SMS, and MMS.") + "A device may be unable to send messages if it does not support messaging or if it is not currently configured to send messages. This only applies to the ability to send text messages via iMessage, SMS, and MMS.", + ) return } val message = call.argument("message") ?: "" val recipients = call.argument("recipients") ?: "" val sendDirect = call.argument("sendDirect") ?: false + + if (!sendDirect && !canSendSMSViaApp()) { + result.error( + "app_to_send_sms_not_available", + "The current device has not an app to send sms.", + "To send a non direct sms, an sms application is required", + ) + return + } sendSMS(result, recipients, message!!, sendDirect) } "canSendSMS" -> result.success(canSendSMS()) @@ -91,13 +101,15 @@ class FlutterSmsPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { } @TargetApi(Build.VERSION_CODES.ECLAIR) - private fun canSendSMS(): Boolean { - if (!activity!!.packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) - return false + private fun canSendSMS(): Boolean = + activity!!.packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) + + @TargetApi(Build.VERSION_CODES.ECLAIR) + private fun canSendSMSViaApp(): Boolean { val intent = Intent(Intent.ACTION_SENDTO) intent.data = Uri.parse("smsto:") val activityInfo = intent.resolveActivityInfo(activity!!.packageManager, intent.flags.toInt()) - return !(activityInfo == null || !activityInfo.exported) + return canSendSMS() && !(activityInfo == null || !activityInfo.exported) } private fun sendSMS(result: Result, phones: String, message: String, sendDirect: Boolean) { diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies index 1f87844..12da8ba 100644 --- a/example/.flutter-plugins-dependencies +++ b/example/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_sms","path":"/Users/dsilk/Development/flutter/packages/flutter_sms/","dependencies":[]},{"name":"url_launcher_ios","path":"/Users/dsilk/.pub-cache/hosted/pub.dartlang.org/url_launcher_ios-6.0.15/","dependencies":[]}],"android":[{"name":"flutter_sms","path":"/Users/dsilk/Development/flutter/packages/flutter_sms/","dependencies":[]},{"name":"url_launcher_android","path":"/Users/dsilk/.pub-cache/hosted/pub.dartlang.org/url_launcher_android-6.0.15/","dependencies":[]}],"macos":[{"name":"url_launcher_macos","path":"/Users/dsilk/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-3.0.0/","dependencies":[]}],"linux":[{"name":"url_launcher_linux","path":"/Users/dsilk/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-3.0.0/","dependencies":[]}],"windows":[{"name":"url_launcher_windows","path":"/Users/dsilk/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-3.0.0/","dependencies":[]}],"web":[{"name":"flutter_sms","path":"/Users/dsilk/Development/flutter/packages/flutter_sms/","dependencies":[]},{"name":"url_launcher_web","path":"/Users/dsilk/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-2.0.8/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_sms","dependencies":["url_launcher"]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2022-02-14 16:50:47.982162","version":"2.10.1"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_sms","path":"/Users/mirland/AndroidStudioProjects/Samples/flutter_sms/","native_build":true,"dependencies":[]},{"name":"url_launcher_ios","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_ios-6.0.17/","native_build":true,"dependencies":[]}],"android":[{"name":"flutter_sms","path":"/Users/mirland/AndroidStudioProjects/Samples/flutter_sms/","native_build":true,"dependencies":[]},{"name":"url_launcher_android","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_android-6.0.17/","native_build":true,"dependencies":[]}],"macos":[{"name":"url_launcher_macos","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-3.0.1/","native_build":true,"dependencies":[]}],"linux":[{"name":"url_launcher_linux","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-3.0.1/","native_build":true,"dependencies":[]}],"windows":[{"name":"url_launcher_windows","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-3.0.1/","native_build":true,"dependencies":[]}],"web":[{"name":"flutter_sms","path":"/Users/mirland/AndroidStudioProjects/Samples/flutter_sms/","dependencies":[]},{"name":"url_launcher_web","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-2.0.12/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_sms","dependencies":["url_launcher"]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2022-07-11 17:57:27.817410","version":"3.0.1"} \ No newline at end of file From 310a0df9e0d8d656d3c3a547aef3ccdcfc5fa179 Mon Sep 17 00:00:00 2001 From: mirland Date: Mon, 11 Jul 2022 18:08:04 -0300 Subject: [PATCH 2/4] Minor changes --- example/.flutter-plugins-dependencies | 1 - example/.gitignore | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 example/.flutter-plugins-dependencies diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies deleted file mode 100644 index 12da8ba..0000000 --- a/example/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_sms","path":"/Users/mirland/AndroidStudioProjects/Samples/flutter_sms/","native_build":true,"dependencies":[]},{"name":"url_launcher_ios","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_ios-6.0.17/","native_build":true,"dependencies":[]}],"android":[{"name":"flutter_sms","path":"/Users/mirland/AndroidStudioProjects/Samples/flutter_sms/","native_build":true,"dependencies":[]},{"name":"url_launcher_android","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_android-6.0.17/","native_build":true,"dependencies":[]}],"macos":[{"name":"url_launcher_macos","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-3.0.1/","native_build":true,"dependencies":[]}],"linux":[{"name":"url_launcher_linux","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-3.0.1/","native_build":true,"dependencies":[]}],"windows":[{"name":"url_launcher_windows","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-3.0.1/","native_build":true,"dependencies":[]}],"web":[{"name":"flutter_sms","path":"/Users/mirland/AndroidStudioProjects/Samples/flutter_sms/","dependencies":[]},{"name":"url_launcher_web","path":"/Users/mirland/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-2.0.12/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_sms","dependencies":["url_launcher"]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2022-07-11 17:57:27.817410","version":"3.0.1"} \ No newline at end of file diff --git a/example/.gitignore b/example/.gitignore index 437cb45..0da56b9 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -34,3 +34,5 @@ lib/generated_plugin_registrant.dart # Exceptions to above rules. !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages + +example/.flutter-plugins-dependencies From d17b1ed7fe28f1f620604f6db0ecc74e3f4840ad Mon Sep 17 00:00:00 2001 From: mirland Date: Mon, 11 Jul 2022 19:26:50 -0300 Subject: [PATCH 3/4] Rollback git ignore change --- example/.gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/example/.gitignore b/example/.gitignore index 0da56b9..437cb45 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -34,5 +34,3 @@ lib/generated_plugin_registrant.dart # Exceptions to above rules. !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages - -example/.flutter-plugins-dependencies From 8a3e6f495e467bed50154c9bf590e39f8b5f57a8 Mon Sep 17 00:00:00 2001 From: mirland Date: Wed, 13 Jul 2022 17:47:36 -0300 Subject: [PATCH 4/4] Handle send status --- .../example/flutter_sms/FlutterSmsPlugin.kt | 106 +++++++++++------- 1 file changed, 65 insertions(+), 41 deletions(-) diff --git a/android/src/main/kotlin/com/example/flutter_sms/FlutterSmsPlugin.kt b/android/src/main/kotlin/com/example/flutter_sms/FlutterSmsPlugin.kt index ab335f5..e3552fd 100644 --- a/android/src/main/kotlin/com/example/flutter_sms/FlutterSmsPlugin.kt +++ b/android/src/main/kotlin/com/example/flutter_sms/FlutterSmsPlugin.kt @@ -3,7 +3,10 @@ package com.example.flutter_sms import android.annotation.TargetApi import android.app.Activity import android.app.PendingIntent +import android.content.BroadcastReceiver +import android.content.Context import android.content.Intent +import android.content.IntentFilter import android.content.pm.PackageManager import android.net.Uri import android.os.Build @@ -21,7 +24,20 @@ import io.flutter.plugin.common.MethodChannel.Result import io.flutter.plugin.common.PluginRegistry.Registrar -class FlutterSmsPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { +class FlutterSmsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { + // V1 embedding entry point. This is deprecated and will be removed in a future Flutter + // release but we leave it here in case someone's app does not utilize the V2 embedding yet. + companion object { + private const val SENT_INTENT_ACTION = "SMS_SENT_ACTION" + + @JvmStatic + fun registerWith(registrar: Registrar) { + val inst = FlutterSmsPlugin() + inst.activity = registrar.activity() + inst.setupCallbackChannels(registrar.messenger()) + } + } + private lateinit var mChannel: MethodChannel private var activity: Activity? = null private val REQUEST_CODE_SEND_SMS = 205 @@ -59,44 +75,34 @@ class FlutterSmsPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { mChannel.setMethodCallHandler(null) } - // V1 embedding entry point. This is deprecated and will be removed in a future Flutter - // release but we leave it here in case someone's app does not utilize the V2 embedding yet. - companion object { - @JvmStatic - fun registerWith(registrar: Registrar) { - val inst = FlutterSmsPlugin() - inst.activity = registrar.activity() - inst.setupCallbackChannels(registrar.messenger()) - } - } override fun onMethodCall(call: MethodCall, result: Result) { when (call.method) { - "sendSMS" -> { - if (!canSendSMS()) { - result.error( - "device_not_capable", - "The current device is not capable of sending text messages.", - "A device may be unable to send messages if it does not support messaging or if it is not currently configured to send messages. This only applies to the ability to send text messages via iMessage, SMS, and MMS.", - ) - return - } - val message = call.argument("message") ?: "" - val recipients = call.argument("recipients") ?: "" - val sendDirect = call.argument("sendDirect") ?: false - - if (!sendDirect && !canSendSMSViaApp()) { - result.error( - "app_to_send_sms_not_available", - "The current device has not an app to send sms.", - "To send a non direct sms, an sms application is required", - ) - return - } - sendSMS(result, recipients, message!!, sendDirect) + "sendSMS" -> { + if (!canSendSMS()) { + result.error( + "device_not_capable", + "The current device is not capable of sending text messages.", + "A device may be unable to send messages if it does not support messaging or if it is not currently configured to send messages. This only applies to the ability to send text messages via iMessage, SMS, and MMS.", + ) + return + } + val message = call.argument("message") ?: "" + val recipients = call.argument("recipients") ?: "" + val sendDirect = call.argument("sendDirect") ?: false + + if (!sendDirect && !canSendSMSViaApp()) { + result.error( + "app_to_send_sms_not_available", + "The current device has not an app to send sms.", + "To send a non direct sms, an sms application is required", + ) + return } - "canSendSMS" -> result.success(canSendSMS()) - else -> result.notImplemented() + sendSMS(result, recipients, message!!, sendDirect) + } + "canSendSMS" -> result.success(canSendSMS()) + else -> result.notImplemented() } } @@ -108,22 +114,42 @@ class FlutterSmsPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { private fun canSendSMSViaApp(): Boolean { val intent = Intent(Intent.ACTION_SENDTO) intent.data = Uri.parse("smsto:") - val activityInfo = intent.resolveActivityInfo(activity!!.packageManager, intent.flags.toInt()) + val activityInfo = + intent.resolveActivityInfo(activity!!.packageManager, intent.flags.toInt()) return canSendSMS() && !(activityInfo == null || !activityInfo.exported) } private fun sendSMS(result: Result, phones: String, message: String, sendDirect: Boolean) { if (sendDirect) { sendSMSDirect(result, phones, message); - } - else { + } else { sendSMSDialog(result, phones, message); } } private fun sendSMSDirect(result: Result, phones: String, message: String) { // SmsManager is android.telephony - val sentIntent = PendingIntent.getBroadcast(activity, 0, Intent("SMS_SENT_ACTION"), PendingIntent.FLAG_IMMUTABLE) + val sentIntent = PendingIntent.getBroadcast( + activity, + 0, + Intent(SENT_INTENT_ACTION), + PendingIntent.FLAG_IMMUTABLE + ) + + activity?.registerReceiver(object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + activity?.unregisterReceiver(this) + when (resultCode) { + Activity.RESULT_OK -> result.success("SMS Sent!") + else -> result.error( + "sent_sms_error", + "Error sending the sms", + "Error code $resultCode" + ) + } + } + }, IntentFilter(SENT_INTENT_ACTION)) + val mSmsManager = SmsManager.getDefault() val numbers = phones.split(";") @@ -136,8 +162,6 @@ class FlutterSmsPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { mSmsManager.sendTextMessage(num, null, message, sentIntent, null) } } - - result.success("SMS Sent!") } private fun sendSMSDialog(result: Result, phones: String, message: String) {