Cela a été demandé à plusieurs reprises auparavant, j'ai parcouru tout, pas encore de réponses claires.
Question simplifiée: Est-il possible d’injecter un fichier Javascript local (depuis un actif ou un stockage) vers une page Web distante chargée dans une vue Web Android? Je sais qu’il est possible d’injecter de tels fichiers dans des pages Web locales (Assets HTML) chargées dans une vue Web.
Pourquoi ai-je besoin de ça pour fonctionner? : Pour rendre la navigation plus rapide, en évitant le téléchargement de fichiers plus volumineux tels que les fichiers Js et CSS. Je souhaite éviter la mise en cache Web-View.
Il existe un moyen de "forcer" l'injection de vos fichiers Javascript locaux à partir d'actifs locaux (par exemple, assets/js/script.js), et de contourner le "Non autorisé à charger la ressource locale: file: /// Android_assets/js /script.js ... 'numéro.
Il est similaire à ce qui est décrit dans un autre fil de discussion ( Webview Android, chargement du fichier javascript dans le dossier assets ), avec encodage/décodage BASE64 supplémentaire pour représenter votre fichier Javascript sous forme de chaîne imprimable.
J'utilise un périphérique virtuel Android 4.4.2, API de niveau 19.
Voici quelques extraits de code:
[assets/js/script.js]:
'use strict';
function test() {
// ... do something
}
// more Javascript
[MainActivity.Java]:
...
WebView myWebView = (WebView) findViewById(R.id.webView);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
myWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
injectScriptFile(view, "js/script.js"); // see below ...
// test if the script was loaded
view.loadUrl("javascript:setTimeout(test(), 500)");
}
private void injectScriptFile(WebView view, String scriptFile) {
InputStream input;
try {
input = getAssets().open(scriptFile);
byte[] buffer = new byte[input.available()];
input.read(buffer);
input.close();
// String-ify the script byte-array using BASE64 encoding !!!
String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
view.loadUrl("javascript:(function() {" +
"var parent = document.getElementsByTagName('head').item(0);" +
"var script = document.createElement('script');" +
"script.type = 'text/javascript';" +
// Tell the browser to BASE64-decode the string into your script !!!
"script.innerHTML = window.atob('" + encoded + "');" +
"parent.appendChild(script)" +
"})()");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
myWebView.loadUrl("http://www.example.com");
...
loadUrl ne fonctionnera que dans l'ancienne version, utilisez assessmentJavascript
webview.evaluateJavascript("(function() { document.getElementsByName('username')[0].value='USERNAME';document.getElementsByName('password')[0].value='PASSWORD'; "+
"return { var1: \"variable1\", var2: \"variable2\" }; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints: {"var1":"variable1","var2":"variable2"}
}
});
Oui, vous pouvez utiliser shouldInterceptRequest () pour intercepter le chargement d’URL à distance et renvoyer le contenu stocké local.
WebView webview = (WebView) findViewById(R.id.webview);
webview.setWebViewClient(new WebViewClient() {
@Override
public WebResourceResponse shouldInterceptRequest (final WebView view, String url) {
if (url.equals("script_url_to_load_local")) {
return new WebResourceResponse("text/javascript", "UTF-8", new FileInputStream("local_url")));
} else {
return super.shouldInterceptRequest(view, url);
}
}
});
Faites attention en utilisant evaluateJavascript
: s'il y a une erreur de syntaxe ou une exception renvoyée dans votre javascript, il appellera votre onReceiveValue
avec une valeur null. Le moyen le plus courant de prendre en charge à la fois le SDK 19 et le bas semble être le suivant: Remplir le formulaire dans WebView avec Javascript
De plus, si vous êtes terriblement désespéré par une sorte de fonctionnalité de navigateur (dans mon cas, vous ne pourrez jamais trouver comment faire fonctionner le DRM), vous pouvez utiliser un bookmarklet en chrome normal, qui ne fonctionne que si vous tapez le nom du signet dans la boîte aux lettres. mais fonctionne et injecte du javascript.
Sachez également qu'avec la variable WebView
par défaut, vous ne pouvez pas utiliser les alertes javascript pour tester quoi que ce soit, elles ne s'affichent pas. Sachez également que "vidéo" par défaut (comme les balises html <vidéo>) ne "fonctionne pas vraiment" par défaut et que la vidéo DRM ne fonctionne pas par défaut, elles sont toutes des options de configuration: \