Вопрос по javascript, android – Вызов функции Java из JavaScript через Android WebView

65

Я хочу сделать синхронный вызов некоторого кода Java в моем приложении для Android.

Я использую это решение: https://stackoverflow.com/a/3338656

Мой код Java:

<code>final class MyWebChromeClient extends WebChromeClient {
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            Log.d("LogTag", message);
            result.confirm();
            return true;
        }
    }
</code>

Мой код JavaScript:

<code><html>
<script>
function java_request(){
    alert('test');
}
</script>
<body>
<h2>Welcome</h2>
<div id="area"></div>
<form>
<input type="button" value="java_call" onclick="java_request()">
</form>
</body>
</html>
</code>

Когда я нажимаю наjava_call Кнопка, кнопка переходит в нажатое состояние. я могу видеть'test' в логе консоли. Пока все здесь нормально.

Проблема в том, что кнопка никогда не возвращается в нормальное состояние. Он остается в нажатом состоянии. Может быть, выполнение JavaScript не работает или что-то?

Почему кнопка никогда не возвращается в нормальное состояние?

Ваш Ответ

3   ответа
1

HTML-кода равно true, поэтому кнопка остается «нажатой».

1

Методы, определенные в & quot;YourJavaScriptInterface& Quot; класс, не забудьте аннотировать каждый метод, который вы хотите предоставить, с помощью "@ JavascriptInterface", в противном случае метод не будет запущен.

Например, приведенный ниже код взят из интерфейса JavaScript Google Cloud Print для вызовов со страницы веб-просмотра:

        final class PrintDialogJavaScriptInterface {
        @JavascriptInterface
        public String toString() { return JS_INTERFACE; }

        @JavascriptInterface
        public String getType() {
            return cloudPrintIntent.getType();
        }

        @JavascriptInterface
        public String getTitle() {
            return cloudPrintIntent.getExtras().getString("title");
        }

        @JavascriptInterface
        public String getContent() {
            try {
                ContentResolver contentResolver = getActivity().getContentResolver();
                InputStream is = contentResolver.openInputStream(cloudPrintIntent.getData());
                ByteArrayOutputStream baos = new ByteArrayOutputStream();

                byte[] buffer = new byte[4096];
                int n = is.read(buffer);
                while (n >= 0) {
                    baos.write(buffer, 0, n);
                    n = is.read(buffer);
                }
                is.close();
                baos.flush();

                return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }

        @JavascriptInterface
        public String getEncoding() {
            return CONTENT_TRANSFER_ENCODING;
        }

        @JavascriptInterface
        public void onPostMessage(String message) {
            if (message.startsWith(CLOSE_POST_MESSAGE_NAME)) {
                finish();
            }
        }
    }
91

Я не думаю, что это лучшее решение, чтобы заставить javascript выполнять код java. Посмотреть здесь:

Если вы хотите предоставить HTML-код собственный код, который можно вызывать с помощью javascript, сделайте следующее вокруг объявления веб-представления:

JavaScriptInterface jsInterface = new JavaScriptInterface(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(jsInterface, "JSInterface");

Объявить классJavaScriptInterface:

public class JavaScriptInterface {
    private Activity activity;

    public JavaScriptInterface(Activity activity) {
        this.activity = activity;
    }

    @JavascriptInterface
    public void startVideo(String videoAddress){
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse(videoAddress), "video/3gpp"); 
        activity.startActivity(intent);
    }
}

Я объявляю одну функцию для воспроизведения видео, но вы можете делать все, что захотите.

Наконец вы называете это вWebView содержимое с помощью простого вызова JavaScript:

<video width="320" height="240" controls="controls" poster='poster.gif'
       onclick="window.JSInterface.startVideo('file:///sdcard/test.3gp');" >
   Your browser does not support the video tag.
</video>

Пример взят из другого моего ответа о воспроизведении видео, но объяснений должно быть достаточно.

EDIT Согласно комментарию @ CedricSoubrie: если целевая версия приложения установлена на 17 или выше, вам нужно добавить аннотацию@JavascriptInterface над каждым методом вы хотите экспортировать в веб-представление.

@BorisStrandjev Чрезвычайно четкий ответ! Обратите внимание, что вы должны добавить & quot; @ JavascriptInterface & quot; аннотации к любому методу, который вы хотите использовать в вашем JavaScript для версии 17 или выше. Источник :developer.android.com/guide/webapps/webview.html
@ ozkolonur Я использовал это со всеми версиями Android 2.2+, никогда не видел ошибок. Можете ли вы поделиться, что это такое. Ссылка также очень приветствуется.
спасибо за информацию, я видел это решение. поскольку в 2.3.X есть ошибка для этого решения, я не хочу ее использовать. Обходной путь был очень потрясающим. ozkolonur
@ Мартен: на самом деле это была не единственная ошибка в моем ответе. Я исправил это сейчас.

Похожие вопросы