首页 > 解决方案 > 在 Android 应用上从 getfeedback.com 获取事件

问题描述

我正在尝试在我的应用程序上从这个网站实施一项调查。

根据文档,为了让 foucs 回到您的应用程序,您必须在 webview 上打开 url(工作正常)并为其注入一个类型的对象window.messageHandler

Web 视图需要使用 postMessage 函数注入 window.messageHandler 对象。例如:

window.messageHandler = {

  postMessage: function(message) { doSomethingInMyApp(message); }

}

经过一些研究,我发现您可以使用@JavascriptInterface将 JavaScript 对象注入 webview ,因此我在网站上进行了免费试用,并创建了一个调查和一个简单的活动,其中包含指向上述调查的 webview:

class MainActivity : AppCompatActivity() {

    private var webView: WebView? = null

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        webView = findViewById(R.id.webView)

        webView?.let {
            it.settings.javaScriptEnabled = true
            it.addJavascriptInterface(JsObject(this), "window.messageHandler")
            it.loadUrl("https://www.getfeedback.com/r/JgP2hwlZ")
        }
    }

    class JsObject(private val context: Context) {
        @JavascriptInterface
        fun postMessage(message: String) {
            Toast.makeText(context, "Something happened", Toast.LENGTH_LONG).show()
        }
    }
}

但是我无法postMessage执行该方法,有什么想法吗?

我也已经尝试过messageHandler作为名称传入,addJavascriptInterface但也不起作用。有趣的是,这最终在调查中引发了一条错误消息,指出我的回复无法发送。只有当我messageHandler作为名称传递时才会发生这种情况。

标签: androidkotlinwebview

解决方案


我自己想通了:

首先,您必须使用addJavascriptInterface()注入您的对象,然后使用webView.evaluateJavaScript()将脚本注入页面,您还可以在其中传递您的JavascriptInterface对象并调用它自己的方法。注意evaluateJavascript()需要在页面加载完成后调用,否则不起作用。这实际上设置了一个侦听器,将在调查完成后触发,这将导致调用您对象的方法。

把所有这些放在一起,你会得到这样的东西:

class MainActivity : AppCompatActivity() {

    private var webView: WebView? = null

    companion object {
        private const val SCRIPT =
            "window.messageHandler = { postMessage: function(message) { object.doSomethingInMyApp(message); } }"
    }

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        webView = findViewById(R.id.webView)

        webView?.let {
            it.settings.javaScriptEnabled = true
            it.addJavascriptInterface(JsObject(this), "object")
            it.webViewClient = object : WebViewClient() {
                override fun onPageFinished(view: WebView, url: String) {
                    webView?.evaluateJavascript(SCRIPT, null)
                }
            }
            it.loadUrl("https://www.getfeedback.com/r/JgP2hwlZ")
        }
    }

    class JsObject(private val context: Context) {
        @JavascriptInterface
        fun doSomethingInMyApp(message: String) {
            Toast.makeText(context, "Something happened", Toast.LENGTH_LONG).show()
        }
    }
}

推荐阅读