Je souhaite passer un appel synchrone à un Java dans mon Android app.
J'utilise cette solution: https://stackoverflow.com/a/3338656
Mon 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;
}
}
Mon code 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>
Quand je tape sur le Java_call
, le bouton passe à l'état enfoncé. Je vois 'test'
dans le journal de la console. Tout est normal jusqu'à ici.
Le problème est que le bouton ne revient jamais à son état normal. Il reste à l'état pressé. Peut-être que l'exécution de JavaScript est cassée ou quelque chose?
Pourquoi le bouton ne revient jamais à son état normal?
Je ne pense pas que ce soit la meilleure solution pour que le javascript soit exécuté Java. Voir ici:
Si vous souhaitez exposer le code natif au code HTML pour qu'il soit appelable via javascript, procédez comme suit pour votre déclaration d'affichage Web:
JavaScriptInterface jsInterface = new JavaScriptInterface(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(jsInterface, "JSInterface");
Déclarez la classe 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);
}
}
Je déclare une fonction unique pour la lecture d'une vidéo, mais vous pouvez faire ce que vous voulez.
Enfin, vous appelez ceci dans le contenu WebView
via un simple appel 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>
L'exemple est tiré d'une autre de mes réponses, à propos de la lecture de vidéos, mais devrait en expliquer suffisamment.
EDIT D'après le commentaire de @ CedricSoubrie: si la version cible de l'application est définie sur 17 ou supérieure, vous devez ajouter une annotation @JavascriptInterface
au-dessus de chaque méthode que vous souhaitez exporter vers la vue Web.
Les méthodes définies dans la classe "YourJavaScriptInterface", n'oubliez pas d'annoter chaque méthode que vous souhaitez exposer avec "@JavascriptInterface", sinon la méthode ne sera pas déclenchée.
Par exemple, le code ci-dessous provient de l'interface JavaScript de Google Cloud Print pour les appels provenant d'une page d'affichage Web:
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();
}
}
}
Votre fonction retourne 'true'. Cela rend la propriété 'onclick' de votre code HTML égale à true, donc le bouton reste 'cliqué'.