Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Android activity result in Flutter

I have a thirdparty Android control that can't be used in Flutter directly. I put it in an Android activity. Then, using information from https://flutter.io/docs/development/platform-integration/platform-channels#step-3b-add-an-android-platform-specific-implementation-using-kotlin, I can successfully launch that activity and perform some actions there. The only part that doesn't work is sending results back from the activity.

Flutter code:

void showDialog() async
    {
        try {
            final Map<String, List<double>> result = await platform.invokeMethod('show_dialog',
                <String, String>{
                    'address': widget.user.address
                });
            widget.user.address = result.keys.toList()[0];
        } on PlatformException catch (e) {
            print('Failed to pick address: ${e.message}.');
        }
    }

Android code:

class MainActivity: FlutterActivity() {
  private val CHANNEL = "dialog"
  private lateinit var _result: MethodChannel.Result
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    GeneratedPluginRegistrant.registerWith(this)
    MethodChannel(flutterView, CHANNEL).setMethodCallHandler { call, result ->
      if (call.method == "show_dialog") {
          _result = result
          val intent = Intent(this@MainActivity, DialogActivity::class.java)
          intent.putExtra("address", call.argument<String>("address"))
          startActivityForResult(intent, 9689)
      }
      else result.notImplemented()
    }
  }
  override fun onActivityResult(requestCode: Int, result: Int, intent: Intent?) {
      if(requestCode != 9689)
          return super.onActivityResult(requestCode, result, intent)
      if (result == Activity.RESULT_OK) {
          _result.success(mapOf(intent!!.getStringExtra("address") to
              listOf(intent.getDoubleExtra("latitude", 0.0),
                  intent.getDoubleExtra("longitude", 0.0))))
      }
      else
          _result.success(null)
  }
}

What's the problem? Breakpoint on the line widget.user.address = result.keys.toList()[0]; is never reached, suggesting the result is never sent back.

like image 341
ZzZombo Avatar asked Jan 11 '19 05:01

ZzZombo


1 Answers

Turns out the code was almost correct. The Android side didn't need any changes, but on the Flutter side I had to make this change:

turn

final Map<String, List<double>> result = await platform.invokeMethod(

into

final result = await platform.invokeMethod(

i. e. simply remove explicit type from the variable, because the return value of platform.invokeMethod was some kind of an internal hash map (in particular, it's name started with an underscore) rather than that of Map as specified. Flutter didn't show any errors in the console output, because for some reason it only captures Android log with debugger attached to the Android part of the application, and once I figured how to debug Android code in Android Studio, I immediately found the reason.

like image 150
ZzZombo Avatar answered Nov 17 '22 19:11

ZzZombo