从 Android 应用上的 getfeedback.com 获取事件

Get event from getfeedback.com on Android app

我正在尝试在我的应用程序上实施来自 this 网站的调查。

根据 docs 为了让 focs 返回到您的应用程序,您必须在 webview(工作正常)上打开 url 并注入类型为 [= 的对象14=] 到它。

Web views need to inject a window.messageHandler object with a postMessage function. For example:

window.messageHandler = {

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

}

经过一些研究,我发现您可以使用 @JavascriptInterface 将 JavaScript 对象注入到 webview 中,所以我在网站上进行了免费试用,并创建了一个调查和一个简单的 activity 带有指向上述调查的网络视图:

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 作为名称传递时才会发生这种情况。

我自己想出来了:

首先你必须使用 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()
        }
    }
}