Вызов функции Java из JavaScript через Android WebView
Я хочу сделать синхронный вызов некоторого кода Java в моем приложении для Android.
Я использую это решение: /questions/43384568/kak-poluchit-vozvraschaemoe-znachenie-iz-javascript-v-veb-obozrenie-android/43384573#43384573
Мой код Java:
final class MyWebChromeClient extends WebChromeClient {
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.d("LogTag", message);
result.confirm();
return true;
}
}
Мой код JavaScript:
<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>
Когда я нажимаю на java_call
Кнопка, кнопка переходит в нажатое состояние. я могу видеть 'test'
в логе консоли. Пока все здесь нормально.
Проблема в том, что кнопка никогда не возвращается в нормальное состояние. Он остается в нажатом состоянии. Может быть, выполнение JavaScript не работает или что-то?
Почему кнопка никогда не возвращается в нормальное состояние?
3 ответа
Я не думаю, что это лучшее решение, чтобы заставить 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;
}
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>
Пример взят из другого моего ответа о воспроизведении видео, но объяснений должно быть достаточно.
РЕДАКТИРОВАТЬ Согласно комментарию @CedricSoubrie: если целевая версия приложения установлена на 17 или выше, вам нужно добавить аннотацию @JavascriptInterface
над каждым методом вы хотите экспортировать в веб-представление.
Ваша функция возвращает "истина". Это делает свойство "onclick" вашего HTML-кода равным true, поэтому кнопка остается "нажатой".
Методы, определенные в классе "YourJavaScriptInterface", не забудьте аннотировать каждый метод, который вы хотите предоставить, с помощью "@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();
}
}
}