Wywołanie funkcji Java z JavaScript przez Android WebView
Chcę wykonać synchroniczne połączenie z kodem Javy w mojej aplikacji na Androida.
Używam tego rozwiązania: https://stackoverflow.com/a/3338656
Mój kod Javy:
final class MyWebChromeClient extends WebChromeClient {
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.d("LogTag", message);
result.confirm();
return true;
}
}
Mój kod 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>
Kiedy dotknę java_call
przycisk przechodzi do stanu wciśniętego. Widzę 'test'
w dzienniku konsoli. Do tej pory wszystko jest normalne.
Dlaczego przycisk nigdy nie wraca do normalnego stanu?
3 answers
Myślę, że nie jest to najlepsze rozwiązanie, aby zmusić javascript do wykonania kodu java. Zobacz tutaj:
Jeśli chcesz udostępnić kod macierzysty HTML do wywołania za pomocą javascript, wykonaj następujące czynności wokół deklaracji widoku sieci:
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);
}
}
Deklaruję jedną funkcję do odtwarzania wideo, ale możesz robić, co chcesz.
W końcu wywołujesz to w treści WebView
za pomocą prostego wywołania 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>
The przykład pochodzi z innej mojej odpowiedzi na temat odtwarzania filmów, ale powinien być wystarczająco wyjaśniony.
Edytuj zgodnie z komentarzem @ CedricSoubrie: jeśli docelowa wersja aplikacji jest ustawiona na 17 lub wyższą, musisz dodać adnotację @JavascriptInterface
nad każdą metodą, którą chcesz wyeksportować do widoku sieci web.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-19 13:54:58
Funkcja zwraca 'true'. To sprawia, że właściwość "onclick" Twojego kodu HTML jest równa true, stąd przycisk pozostaje "kliknięty".'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-30 16:12:54
Metody zdefiniowane w klasie " YourJavaScriptInterface", nie zapomnij dodać adnotacji do każdej metody, którą chcesz udostępnić za pomocą "@ JavascriptInterface", w przeciwnym razie metoda nie zostanie uruchomiona.
Na przykład poniższy kod pochodzi z interfejsu JavaScript Google Cloud Print dla połączeń ze strony webview:
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();
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-12 06:11:01