it-swarm.com.de

Android Web-View: Lokale Javascript-Datei in die Remote-Webseite einfügen

Es wurde schon oft gefragt, ich habe alles durchgesehen, noch keine klaren Antworten.

Frage vereinfacht: Ist es möglich, eine lokale Javascript-Datei (von Asset oder Speicher) in eine in eine Android-Web-Ansicht geladene Remote-Webseite einzufügen? Ich weiß, dass es möglich ist, solche Dateien in lokale Webseiten (Assets HTML) einzufügen, die in einer Webansicht geladen sind.

Warum brauche ich das, um zu arbeiten? : Um das Surfen schneller zu machen, müssen Sie nicht jedes Mal größere Dateien wie Js und CSS-Dateien herunterladen. Ich möchte das Web-View-Caching vermeiden.

33
sumit

Es gibt eine Möglichkeit, die Injektion Ihrer lokalen Javascript-Dateien aus lokalen Assets (z. B. assets/js/script.js) zu "erzwingen" und die Option "Nicht zum Laden lokaler Ressourcen erlaubt" zu umgehen: file: /// Android_assets/js /script.js ... 'Problem.

Es ist ähnlich wie in einem anderen Thread beschrieben ( Android-Webview, Laden der Javascript-Datei in den Assets-Ordner ), mit zusätzlicher BASE64-Codierung/-Decodierung zum Darstellen Ihrer Javascript-Datei als druckbare Zeichenfolge.

Ich verwende ein virtuelles Gerät mit Android 4.4.2, API-Ebene 19.

Hier sind einige Codeausschnitte:

[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");

    ...
49
Raffaele N.

loadUrl funktioniert nur in der alten Version. use evaluJavascript

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"}
                }
            });
5
rinkesh

Ja, Sie können shouldInterceptRequest () verwenden, um das Laden von URLs abzufangen und lokal gespeicherte Inhalte zurückzugeben.

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);
       }
    }
});
5
cyberflohr

Seien Sie vorsichtig bei der Verwendung von evaluateJavascript: Wenn in Ihrem Javascript ein Syntaxfehler oder eine Ausnahme ausgegeben wird, ruft es Ihre onReceiveValue mit einer Null auf. Die gebräuchlichste Art, sowohl SDK 19 als auch niedriger zu unterstützen, scheint folgendermaßen zu sein: Formular in WebView mit Javascript ausfüllen

Wenn Sie verzweifelt verzweifelt nach einer Art von Browserfunktionalität suchen (in meinem Fall könnte ich nie herausfinden, wie man DRM gut zum Laufen bringt), können Sie ein Bookmarklet innerhalb von normalem Chrome verwenden. Dies funktioniert nur, wenn Sie den Namen des Lesezeichens in die Omnibox eingeben aber funktioniert und injiziert Javascript.

Beachten Sie auch, dass Sie mit der Standardvariable WebView keine JavaScript-Alarme verwenden können, um etwas zu testen. Sie werden nicht angezeigt. Beachten Sie auch, dass "video" standardmäßig (wie html <video> -Tags) nicht "wirklich" funktioniert und auch DRM-Video nicht standardmäßig funktioniert. Sie haben alle Konfigurationsoptionen: \

0
rogerdpack