From d4b2579f90656e3da02ec17c788cb6df61842839 Mon Sep 17 00:00:00 2001 From: Dan Silk Date: Mon, 14 Feb 2022 16:55:09 +1030 Subject: [PATCH 1/4] Sends SMS directly on Android Addresses issue #57 --- .vscode/launch.json | 2 +- README.md | 13 +++++ .../example/flutter_sms/FlutterSmsPlugin.kt | 53 +++++++++++++++---- example/.flutter-plugins-dependencies | 2 +- .../android/app/src/main/AndroidManifest.xml | 6 ++- example/android/build.gradle | 2 +- example/lib/main.dart | 21 ++++++-- lib/flutter_sms.dart | 10 ++-- lib/flutter_sms_web.dart | 1 + lib/src/flutter_sms_platform.dart | 4 ++ 10 files changed, 92 insertions(+), 22 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 9f8693f..c021031 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "version": "0.2.0", "configurations": [ { - "name": "Flutter", + "name": "Example App", "request": "launch", "type": "dart", "program": "example/lib/main.dart" diff --git a/README.md b/README.md index 134bad3..651ac3d 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,19 @@ List recipents = ["1234567890", "5556787676"]; _sendSMS(message, recipents); ``` +On Android, you can skip the additional dialog with the sendDirect parameter. + +``` dart +String message = "This is a test message!"; +List recipents = ["1234567890", "5556787676"]; + + String _result = await sendSMS(message: message, recipients: recipents, sendDirect: true) + .catchError((onError) { + print(onError); + }); +print(_result); +``` + ## Screenshots iOS SMS | Android MMS 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 c9f4a7f..25af08c 100644 --- a/android/src/main/kotlin/com/example/flutter_sms/FlutterSmsPlugin.kt +++ b/android/src/main/kotlin/com/example/flutter_sms/FlutterSmsPlugin.kt @@ -1,21 +1,25 @@ package com.example.flutter_sms import android.annotation.TargetApi -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.MethodChannel.MethodCallHandler -import io.flutter.plugin.common.MethodChannel.Result -import io.flutter.plugin.common.PluginRegistry.Registrar import android.app.Activity -import android.net.Uri +import android.app.PendingIntent import android.content.Intent import android.content.pm.PackageManager +import android.net.Uri import android.os.Build +import android.telephony.SmsManager +import android.util.Log import androidx.annotation.NonNull import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.MethodCallHandler +import io.flutter.plugin.common.MethodChannel.Result +import io.flutter.plugin.common.PluginRegistry.Registrar + class FlutterSmsPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { private lateinit var mChannel: MethodChannel @@ -76,9 +80,10 @@ class FlutterSmsPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { "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") - sendSMS(result, recipients, message!!) + val message = call.argument("message") ?: "" + val recipients = call.argument("recipients") ?: "" + val sendDirect = call.argument("sendDirect") ?: false + sendSMS(result, recipients, message!!, sendDirect) } "canSendSMS" -> result.success(canSendSMS()) else -> result.notImplemented() @@ -95,7 +100,35 @@ class FlutterSmsPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { return !(activityInfo == null || !activityInfo.exported) } - private fun sendSMS(result: Result, phones: String?, message: String?) { + private fun sendSMS(result: Result, phones: String, message: String, sendDirect: Boolean) { + if (sendDirect) { + sendSMSDirect(result, phones, message); + } + 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 mSmsManager = SmsManager.getDefault() + val numbers = phones.split(";") + + for (num in numbers) { + Log.d("Flutter SMS", "msg.length() : " + message.toByteArray().size) + if (message.toByteArray().size > 80) { + val partMessage = mSmsManager.divideMessage(message) + mSmsManager.sendMultipartTextMessage(num, null, partMessage, null, null) + } else { + mSmsManager.sendTextMessage(num, null, message, sentIntent, null) + } + } + + result.success("SMS Sent!") + } + + private fun sendSMSDialog(result: Result, phones: String, message: String) { val intent = Intent(Intent.ACTION_SENDTO) intent.data = Uri.parse("smsto:$phones") intent.putExtra("sms_body", message) diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies index 01bacb8..1f87844 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/rodydavis/Developer/GitHub/plugins/packages/flutter_sms/","dependencies":["url_launcher"]},{"name":"url_launcher","path":"/usr/local/Caskroom/flutter/1.2.1/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.12/","dependencies":[]}],"android":[{"name":"flutter_sms","path":"/Users/rodydavis/Developer/GitHub/plugins/packages/flutter_sms/","dependencies":["url_launcher"]},{"name":"url_launcher","path":"/usr/local/Caskroom/flutter/1.2.1/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.12/","dependencies":[]}],"macos":[{"name":"url_launcher_macos","path":"/usr/local/Caskroom/flutter/1.2.1/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-2.0.2/","dependencies":[]}],"linux":[{"name":"url_launcher_linux","path":"/usr/local/Caskroom/flutter/1.2.1/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-2.0.2/","dependencies":[]}],"windows":[{"name":"url_launcher_windows","path":"/usr/local/Caskroom/flutter/1.2.1/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-2.0.2/","dependencies":[]}],"web":[{"name":"flutter_sms","path":"/Users/rodydavis/Developer/GitHub/plugins/packages/flutter_sms/","dependencies":[]},{"name":"url_launcher_web","path":"/usr/local/Caskroom/flutter/1.2.1/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-2.0.4/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_sms","dependencies":["url_launcher"]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-09-27 10:56:42.626795","version":"2.5.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/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 diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 55ca830..6fb01f8 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -5,8 +5,11 @@ In most cases you can leave this as-is, but you if you want to provide additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> + + +