I am working on a Flutter App where I am working fine. Now for sending any SMS, I am moving to Android(Kotlin) from Flutter with passing the data(phone number, text message) and sending message from Android(Kotlin).
This task is working perfectly with the code shared below.
MainActivity.kt
package com.example.my_flutter_app
import ...
class SmsManager
class MainActivity : FlutterActivity() {
private val CHANNEL = "samples.flutter.dev/smscall"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
// Note: this method is invoked on the main thread.
call, result ->
if (call.method == "sendSMS") {
// Send SMS Via Native Code
val sentinelPhoneNumber = call.argument<String>("phoneno") // 923343381164
val message = call.argument<String>("text") // "Please Help Me"
var SENT = "SMS_SENT"
var DELIVERED = "SMS_DELIVERED"
lateinit var sentPI: PendingIntent
lateinit var deliveredPI: PendingIntent
val delay = 5000 // 1000 milliseconds == 1 second
var isSMSSent = false
var isSMSDelivered = false
sentPI = PendingIntent.getBroadcast(
ContextWrapper(applicationContext),
0,
Intent(SENT),
PendingIntent.FLAG_IMMUTABLE
)
deliveredPI = PendingIntent.getBroadcast(
ContextWrapper(applicationContext),
0,
Intent(DELIVERED),
PendingIntent.FLAG_IMMUTABLE
)
// if (requestSmsPermission()){
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage(sentinelPhoneNumber, null, message, sentPI, deliveredPI)
// }
ContextWrapper(applicationContext).registerReceiver(
object : BroadcastReceiver() {
override fun onReceive(arg0: Context, arg1: Intent) {
when (resultCode) {
Activity.RESULT_OK -> isSMSDelivered = true
Activity.RESULT_CANCELED -> { isSMSDelivered = false
}
}
}
}, IntentFilter(DELIVERED)
)
ContextWrapper(applicationContext).registerReceiver(
object : BroadcastReceiver() {
override fun onReceive(arg0: Context, arg1: Intent) {
Log.e("SMS", "SMS Sender In Native Reciver Running")
when (resultCode) {
Activity.RESULT_OK -> {
// Log.e("SMS","SMS sent to book on/off job")
isSMSSent = true
Log.e("SMS", "SMS Sent Successfully.")
}
SmsManager.RESULT_ERROR_GENERIC_FAILURE -> {
isSMSSent = false
Log.e("SMS", "SMS Not Sent Successfully.")
}
SmsManager.RESULT_ERROR_NO_SERVICE -> {
isSMSSent = false
Log.e("SMS", "SMS Not Sent Successfully.")
}
SmsManager.RESULT_ERROR_NULL_PDU -> {
isSMSSent = false
Log.e("SMS", "SMS Not Sent Successfully.")
}
SmsManager.RESULT_ERROR_RADIO_OFF -> {
isSMSSent = false
Log.e("SMS", "SMS Not Sent Successfully.")
}
else -> {
Log.e("SMS", "SMS Not Sent Successfully.")
}
}
}
}, IntentFilter(SENT)
)
// Send SMS Via Native Code
} else {
result.notImplemented()
}
}
}
}
main.dart
// Send SMS Via Native Android
static const platform = MethodChannel('samples.flutter.dev/smscall');
Future<void> _sendSMS(String phoneNo, String msgText) async {
try {
await platform.invokeMethod('sendSMS', {'phoneno': phoneNo, 'text': msgText});
// Want Map<String,dynamic> result Here Return From Android(Kotlin)
} on PlatformException catch (e) {
print("Failed To Send SMS: '${e.message}'.");
}
}
// Send SMS Via Native Android
Now my question is that I want to get the result from Android(Kotlin) that are shown in Log.e("","") as Key/Value paid in main.dart
where I called it as shown in the code.
For this I tried the below snippet but not working...
await platform.invokeMethod('sendSMS' , {'phoneno': phoneNo, 'text': msgText}).then((result) {
print("Return Map<String,dynamic> From Android Native: ${result.toString()}");
});
How to fix this up...???
CodePudding user response:
Finally after searching and trying too much, here I got what I want...
A Big thanks to https://github.com/liusilong/stack_q where I got help and here is the updated code as answer...
MainActivity.kt
package com.example.novus_guard_solo
import ...
class SmsManager
class MainActivity : FlutterActivity() {
// Receiving Channel From Flutter(Dart) To Android(Kotlin)
private val CHANNEL = "samples.flutter.dev/smscall"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
// Sending Channel From Android(Kotlin) To Flutter(Dart)
var _channel: MethodChannel = MethodChannel(flutterEngine!!.getDartExecutor(), "DATA_CHANNEL_FROM_ANDROID_KOTLIN")
var sendSMS_return: HashMap<String, String?> = HashMap()
//var sendSMS_return: HashMap<String, Object> = HashMap()
//sendSMS_return.put("name", params.get("name"));
// Sending Channel From Android(Kotlin) To Flutter(Dart)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
// Note: this method is invoked on the main thread.
call, result ->
if (call.method == "sendSMS") {
sendSMS_return.clear()
// Send SMS Via Native Code
val sentinelPhoneNumber = call.argument<String>("phoneno") // 923343381164
val message = call.argument<String>("text") // "Please Help Me"
var SENT = "SMS_SENT"
var DELIVERED = "SMS_DELIVERED"
lateinit var sentPI: PendingIntent
lateinit var deliveredPI: PendingIntent
val delay = 5000 // 1000 milliseconds == 1 second
var isSMSSent = false
var isSMSDelivered = false
sentPI = PendingIntent.getBroadcast(
ContextWrapper(applicationContext),
0,
Intent(SENT),
PendingIntent.FLAG_IMMUTABLE
)
deliveredPI = PendingIntent.getBroadcast(
ContextWrapper(applicationContext),
0,
Intent(DELIVERED),
PendingIntent.FLAG_IMMUTABLE
)
// if (requestSmsPermission()){
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage(sentinelPhoneNumber, null, message, sentPI, deliveredPI)
// }
ContextWrapper(applicationContext).registerReceiver(
object : BroadcastReceiver() {
override fun onReceive(arg0: Context, arg1: Intent) {
when (resultCode) {
Activity.RESULT_OK -> isSMSDelivered = true
Activity.RESULT_CANCELED -> { isSMSDelivered = false
}
}
}
}, IntentFilter(DELIVERED)
)
ContextWrapper(applicationContext).registerReceiver(
object : BroadcastReceiver() {
override fun onReceive(arg0: Context, arg1: Intent) {
Log.e("SMS", "SMS Sender In Native Receiver Running")
when (resultCode) {
Activity.RESULT_OK -> {
// Log.e("SMS","SMS sent to book on/off job")
isSMSSent = true
Log.e("SMS", "SMS Sent Successfully.")
//_channel.invokeMethod("sendSMS", "SMS Sent Successfully.");
sendSMS_return.put("phone", sentinelPhoneNumber);
sendSMS_return.put("status", "Successful.");
}
SmsManager.RESULT_ERROR_GENERIC_FAILURE -> {
isSMSSent = false
Log.e("SMS", "SMS Not Sent Successfully.")
//_channel.invokeMethod("sendSMS", "SMS Not Sent Successfully.");
sendSMS_return.put("phone", sentinelPhoneNumber);
sendSMS_return.put("status", "Not Successful.");
}
SmsManager.RESULT_ERROR_NO_SERVICE -> {
isSMSSent = false
Log.e("SMS", "SMS Not Sent Successfully.")
//_channel.invokeMethod("sendSMS", "SMS Not Sent Successfully.");
sendSMS_return.put("phone", sentinelPhoneNumber);
sendSMS_return.put("status", "Not Successful.");
}
SmsManager.RESULT_ERROR_NULL_PDU -> {
isSMSSent = false
Log.e("SMS", "SMS Not Sent Successfully.")
//_channel.invokeMethod("sendSMS", "SMS Not Sent Successfully.");
sendSMS_return.put("phone", sentinelPhoneNumber);
sendSMS_return.put("status", "Not Successful.");
}
SmsManager.RESULT_ERROR_RADIO_OFF -> {
isSMSSent = false
Log.e("SMS", "SMS Not Sent Successfully.")
//_channel.invokeMethod("sendSMS", "SMS Not Sent Successfully.");
sendSMS_return.put("phone", sentinelPhoneNumber);
sendSMS_return.put("status", "Not Successful.");
}
else -> {
Log.e("SMS", "SMS Not Sent Successfully.")
//_channel.invokeMethod("sendSMS", "SMS Not Sent Successfully.");
sendSMS_return.put("phone", sentinelPhoneNumber);
sendSMS_return.put("status", "Not Successful.");
}
}
// Send SMS Via Native Code
// Send Data To Flutter(Dart) via HashMap
_channel.invokeMethod("sendSMS", sendSMS_return);
// Send Data To Flutter(Dart) via HashMap
}
}, IntentFilter(SENT)
)
} else {
result.notImplemented()
}
}
}
}
main.dart
// Receiving Channel From Android(Kotlin) To Flutter(Dart)
final MethodChannel _channel = new MethodChannel("DATA_CHANNEL_FROM_ANDROID_KOTLIN");
main() { // Set Constructor Here Of Same Class Name Where You Put This Code In Your Whole Flutter/ Better To Keep On Main Page Like Dashboard/Home/Main
_channel.setMethodCallHandler(_methodCallHandler); // Call MethodCallHandler When Get Any Data Hit From Android(Kotlin)
}
Future<dynamic> _methodCallHandler(MethodCall call) async { // Manage And Filter All Incoming Calls Here
if(call.method == 'sendSMS'){ // Function Called From Android(Kotlin)
final map = call.arguments; // Get Arguments Sent From Android(Kotlin)
print("DATA_CHANNEL_FROM_ANDROID_KOTLIN ${map.toString()}");
String phone = map['phone'] as String;
String status = map['status'] as String;
print('SMS Sent To ${phone} Is ${status}');
}
}
// Receiving Channel From Android(Kotlin) To Flutter(Dart)
// Send SMS Via Native Android
static const platform = MethodChannel('samples.flutter.dev/smscall');
Future<void> _sendSMS(String phoneNo, String msgText) async {
try {
await platform.invokeMethod('sendSMS', {'phoneno': phoneNo, 'text': msgText});
} on PlatformException catch (e) {
print("Failed To Send SMS: '${e.message}'.");
}
}
// Send SMS Via Native Android
So I also added comments to the answer codes. Still if have any issues, feel free to comment here.