Flutter: как получить сообщение post от внешнего приложения?

#flutter #flutter-web

#flutter #flutter-веб

Вопрос:

У меня есть автономное приложение для Android. Затем я разработал веб-приложение меньшего размера в Flutter и экспортировал его на веб-сервер. Оно загружается внутрь WebView как часть этого автономного приложения в Kotlin для Android.

Android поддерживает отправку сообщений, и я могу отправлять данные напрямую WebView по каналам. Мой вопрос в том, как прослушивать эти сообщения в коде Flutter Dart (внутри моего веб-приложения)?

Этот код я использовал в приложении Kotlin для Android:

 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")
        }
    }
  

Итак, вот мой код запуска веб-приложения Flutter:

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

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

Ответ №1:

С помощью библиотеки dart: html мы можем установить канал связи между flutter web приложением и его хостом 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");
    });
  

Соответствующий код Kotlin со стороны Android:

     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)

  

Комментарии:

1. Есть какие-либо советы о том, как справиться с изменением страницы внутри WebView? Вызываете ли вы createWebMessageChannel повторно при загрузке страницы? Насколько я могу судить, на самом деле нет метода уничтожения / очистки, а затем замены.

Ответ №2:

Не уверен на 100%, что это будет полезно, но попробуйте интерактивный веб-просмотр. Используя метод didReceiveMessage.listen(), вы должны иметь возможность прослушивать сообщения, отправленные в собственный webview.

Ответ №3:

Вы должны использовать WebSockets (сокет.ввод-вывод) для обмена сообщениями. Сохраните отдельный экземпляр nodejs, который служит вашим сервером сокетов, отправьте запрос сокета с Android на сервер сокетов и отправьте его с сервера сокетов в ваше веб-приложение flutter

Смотрите —https://pub.dev/packages/adhara_socket_io

Ответ №4:

вы можете использовать облачную службу обмена сообщениями SocketIO или firebase для получения или отправки сообщений