简体   繁体   中英

Get Return Result In Flutter From Android(Kotlin) After Calling An Android(Kotlin) Function From Flutter

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...???

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM