Flutter: How to receive post message communication from outer app?

Viewed 3783

I have standalone Android App. Then I developed smaller web app in Flutter and exported it to web server. It is loaded inside WebView as a part of that standalone App in Kotlin for Android.

Android supports postmessaging and I can send data directly to WebView through channels. My question is how to listen to these messages in Flutter Dart code (inside my Web App)?

This is code I used in Kotlin Android App:

private var port: WebMessagePort? = null
    @TargetApi(Build.VERSION_CODES.M)
    private fun initPostMessagePort(){
        val channelsAvailable = webView.createWebMessageChannel()
        port = channelsAvailable.firstOrNull()
        port?.apply {
            setWebMessageCallback(object : WebMessageCallback() {
                override fun onMessage(port: WebMessagePort, message: WebMessage) {
                    //TODO do something with message
                }
            })
        }?:kotlin.run {
            App.log("Port initialization failed - channels not available")
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    private fun sendMessageToPort(message: String){
        port?.let { p->
            webView.postWebMessage(WebMessage(message, arrayOf(p)), Uri.EMPTY)
        }?:kotlin.run {
            App.log("Port not initialized")
        }
    }

So there is my Flutter Web App startup code:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await di.init();

  //listen to message from mobile app, then run code below
  runApp(MyApp());
  bloc.dispatch(GetUserProfile());
}
4 Answers

With dart:html library we can establish communication channel between flutter web app and its host android WebView:

import 'dart:html' as html;

//...

    html.window.onMessage.listen((event) {

      // do something with received data
      myController.text = event.data; 

      // return a response
      event.ports[0].postMessage("response data");
    });

Corresponding Kotlin code from android side:

    val webView = findViewById<WebView>(R.id.webview)
    val (receiver, sender) = webView.createWebMessageChannel()
    receiver.setWebMessageCallback(object : WebMessagePort.WebMessageCallback() {
        override fun onMessage(port: WebMessagePort, message: WebMessage) {
            Log.i("example", "Received ${message.data}")
        }
    })
    val message = WebMessage("Original message", arrayOf(sender))
    webView.postWebMessage(message, Uri.EMPTY)

Not 100% sure if this will be helpful but try Interactive Webview. Using the didReceiveMessage.listen() method you should be able to listen to messages sent to the native webview.

You should use WebSockets (socket.io) for inter-communications. Keep a separate nodejs instance which serves as your socket server, send a socket request from android to socket server and emit that from socket server to your flutter web app

See - https://pub.dev/packages/adhara_socket_io

you can use from socketIO or firebase cloud messaging service for receive or send message

Related