0

Really struggling with the correct way to achieve the following. If I want to make a native call to Android FROM my Flutter app, there are plenty of examples that I can follow. eg: create an EventChannel and then listen for events and respond to requests from within my Android/Kotlin onMessage listener.

However, what I cannot figure out is how to go the other way! I have a native event that is triggering in the background within native Android. When the event occurs, everything works fine and I can print / debug the data, but I cannot figure out the correct way to package this data up and send back up to Flutter to display in the app:

class MainActivity: FlutterActivity() {
....
....
....
fun somethingHappened(firstName: String, lastName: String, eMail: String) {
    Log.d("MyApp","An event has occurred...");
    // Log message is printing out correctly, but need to 
    // create Object / Hashmap / data structure and send to Flutter
}

....
....
}

Can anyone tell me the correct pattern / approach to use and ideally a link to a simple example that I can reference?

Thanks, Jab

6
  • api.flutter.dev/javadoc/io/flutter/plugin/common/… - here you can emit "normal" data - success(...) or error -error(...) Commented Sep 13, 2020 at 16:44
  • @pskink, thanks for that. I have tried implementing based on examples using EventChannel.EventSink, but I am obviously not doing it correctly as most of the examples that I am seeing are using the EventSink to listen for messages in Android and respond to Flutter. Do you have an example that I could review where the message originates in Android and is dispatched to Flutter? Thanks! Commented Sep 13, 2020 at 16:54
  • no, you listen by implementing onListen - api.flutter.dev/javadoc/io/flutter/plugin/common/… - that method gives you a sink i mentioned above Commented Sep 13, 2020 at 16:57
  • something like: EventChannel.StreamHandler handler = new EventChannel.StreamHandler() { @Override public void onListen(Object o, EventChannel.EventSink eventSink) { } @Override public void onCancel(Object o) { } }; FlutterView fv = getFlutterView(); new EventChannel(fv, "my.event.channel").setStreamHandler(handler); Commented Sep 13, 2020 at 17:03
  • Thank you @pskink, your comments along with Develocodes helped me to get it working Commented Sep 14, 2020 at 8:02

1 Answer 1

4

In MainActivity:

class MainActivity: FlutterActivity() {

    private val CHANNEL = "CHANNEL"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

       val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL);

        channel.invokeMethod("nameOfMethod", "dataToPass")

    }

}

and on flutter side:

MethodChannel channel = MethodChannel('CHANNEL');

  @override
  void initState() {
    
    channel.setMethodCallHandler((call){

      if(call.method == 'nameOfMethod'){
        print(call.arguments);
      }

      return null;
    });
    super.initState();
  }
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much. That helped 1000%. I must have tried 100 different ways and was way over complicating things. Only thing I had to do differently was wrap the Kotlin channel.invokeMethod in a Handler(Looper.getMainLooper()).post {...} or otherwise I was getting an exception in relation to executing on the UI thread. Hope this is the correct way to resolve?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.