Как использовать события backpress на стороне веб-приложения в Android WebView? - PullRequest
1 голос
/ 05 июля 2019

Работает на Kotlin WebView с JS-интерфейсом, где моему веб-приложению требуется обнаружить событие KeyEvent.KEYCODE_BACK с собственной стороны, чтобы закрыть диалоговое окно веб-приложения при его представлении.Если диалоговое окно закрыто, я ничего не должен делать на нативной стороне (вернуть true в super), в противном случае мне нужно завершить просмотр веб-страниц (вернуть false в super).Чтобы поймать мое намерение, пожалуйста, прочитайте приведенный ниже код, который я включил в свой пользовательский WebView в качестве подсказки,

override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {

    if (event.action == KeyEvent.ACTION_DOWN) {
        when (keyCode) {
            KeyEvent.KEYCODE_BACK -> {

                this.evaluateJavascript("onDeviceBackPressed();", ValueCallback {
                    if (it == "1") {
                        // "Web app consumed onDeviceBackPressed event!"
                    } else {
                        // "Web app did not consume onDeviceBackPressed event!"
                        // super.onKeyDown(keyCode, event) won't work
                    }
                })

                // I am required to make the return call wait
                // return true/false base on status returned by js func
            }
        }
    }
    return super.onKeyDown(keyCode, event)
}

Но я знаю, что невозможно ожидать супер-вызова асинхронно.Как мне справиться с этой ситуацией по-другому?

Ответы [ 2 ]

1 голос
/ 05 июля 2019

Вы можете использовать KeyEvent во время первого события нажатия клавиши при ожидании JS, а затем повторно использовать его, когда получите результат.

Я однажды использовал такой прием для сенсорных событий, поэтому он должен работать.

var delayedKeyCode : Int? = null
var delayedKeyEvent : KeyEvent? = null
var keyDownJSResult : String? = null

override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
    if (event.action == KeyEvent.ACTION_DOWN) {
        when (keyCode) {
            KeyEvent.KEYCODE_BACK -> {
                // see if there's "result" provided from JS
                keyDownJSResult?.let{
                    keyDownJSResult = null    // wipe out result so it's not triggered twice
                    if (it == "1") {
                        // "Web app consumed onDeviceBackPressed event!"
                        return true
                    } else {
                        // "Web app did not consume onDeviceBackPressed event!"
                        return super.onKeyDown(keyCode, event)
                    }
                }
                // otherwise store keyDown arguments for later and trigger JS
                delayedKeyCode = keyCode
                delayedKeyEvent = event
                this.evaluateJavascript("onDeviceBackPressed();", ValueCallback {
                     // when JS returns value, trigger this onKeyDown event again
                     val oldCode = delayedKeyCode
                     val oldEv = delayedKeyEvent
                     delayedKeyCode = null
                     delayedKeyEvent = null
                     keyDownJSResult = it
                     onKeyDown(oldCode, oldEv)
                })
                // always consume event when waiting for JS result
                return true 
            }
        }
    }
    return super.onKeyDown(keyCode, event)
}
0 голосов
/ 08 июля 2019

Наконец-то я с помощью небольшого трюка решаю мою проблему,

override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {

    if (event.action == KeyEvent.ACTION_DOWN) {
        when (keyCode) {
            KeyEvent.KEYCODE_BACK -> {
                this.evaluateJavascript("onDeviceBackPressed();", ValueCallback {
                    if (it == "1") {
                        // consumed by web app, do nothing
                    } else {
                        // not consumed by web app, fire explicit back press event
                        mContext.onBackPressed()
                    }
                })
                return true
            }
        }
    }
    return super.onKeyDown(keyCode, event)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...