Home » Android » angularjs – Android Webview Javascript – References to Scripts not working

angularjs – Android Webview Javascript – References to Scripts not working

Posted by: admin June 15, 2020 Leave a comment

Questions:

Developing on Android Studio 1.0.1, API 21. Following is the folder structure –
enter image description here

It’s essentially an AngularJS based app that I want to wrap inside a webview container and run on Android.

My Android side of code is –

 WebView myWebView = (WebView) findViewById(R.id.webview);
 WebSettings webSettings = myWebView.getSettings();
 webSettings.setJavaScriptEnabled(true);
 webSettings.setDomStorageEnabled(true);
 myWebView.setWebChromeClient(new WebChromeClient());

 String filePath = "file:///android_asset/www/index.html";
 myWebView.loadUrl(filePath);

The references in html are all relative –

<script src="lib/jquery.min.js"></script>
<script src="lib/angular.min.js"></script>
<script src="lib/angular-route.min.js"></script>
<script src="lib/bootstrap.min.js"></script>

But interestingly enough, I’ve searched most places, and I’m not sure where am I going wrong. My references aren’t working at all! So I can’t access my lib files, my scripts, my css.
Also, if I run an external angular web page inside the webview, with the same Java code, it runs perfectly!

Any help is appreciated.

Note : Please don’t suggest using Cordova/PhoneGap. It’s a project requirement to go native(and I frankly don’t understand why, but I’m only a developer who has no say in it).

On a side note : I’m facing the same problem with the iOS webview. References aren’t working!


UPDATE

Tried the following things :

Tried loadDataWithBaseURL(), doesn’t work.

Tried all possible scenarios for paths. Nothing worked.

Removed all the scripts from the folder and put them at the root level, and modified links to have no paths, simply file names. Still doesn’t work. And this is way too weird.

How to&Answers:

I managed to do something similar in the following way:

WebView webView = (WebView) findViewById(R.id.webview);

WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webView.setWebChromeClient(new WebChromeClient());

try {
    String html = readAssetFile("www/index.html");
    webView.loadDataWithBaseURL("file:///android_asset/www/", html, "text/html", "UTF-8", null);
} catch (IOException e) {
}

Where ‘readAssetFile’ is:

private String readAssetFile(String fileName) throws IOException {
    StringBuilder buffer = new StringBuilder();
    InputStream fileInputStream = getAssets().open(fileName);
    BufferedReader bufferReader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
    String str;

    while ((str=bufferReader.readLine()) != null) {
        buffer.append(str);
    }
    fileInputStream.close();

    return buffer.toString();
}

Also, my page is a simple one – just to test an image, the angularjs lib and a css stylesheet:

<!DOCTYPE html>
<html>

<head>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
<script src="libs/angular.min.js"></script>
</head>

<body>

<img src="images/IMG_7765.JPG" alt="De nada" width="200" height="300">

<div ng-app="">

<p>Input something in the input box:</p>
<p>Name: <input type="text" ng-model="name" value="John"></p>
<p ng-bind="name"></p>

</div>

</body>
</html>

Also, my file structure is the following

enter image description here

Hope it helps 🙂

Answer:

try putting a forwardslash in front of “lib” in the path of your sources like this (since it is a relative call the browser will complete it for you http://domain/lib/jquery.min.js instead of http://domain.comlib/jquery.min.js).

UPDATE – I believe AngularJS uses the ng-src directive for including external sources:

<script ng-src="/lib/jquery.min.js"></script>
<script ng-src="/lib/angular.min.js"></script>
<script ng-src="/lib/angular-route.min.js"></script>
<script ng-src="/lib/bootstrap.min.js"></script>

Alternatively you could also complete the path yourself if you don’t really need the code to be dynamic like this (this is also a quick test to make sure everything is actually working):

<script ng-src="http://domain.com/lib/jquery.min.js"></script>
<script ng-src="http://domain.com/lib/angular.min.js"></script>
<script ng-src="http://domain.com/lib/angular-route.min.js"></script>
<script ng-src="http://domain.com/lib/bootstrap.min.js"></script>

Answer:

I haven’t tried this but put your index.html page into a string and pass it in as data. the baseUrl is then http://domain.com

public void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)

Webview with both local and interweb (internet and intranet) resources. You have to use loadDataWithBaseURL and all of the interweb resources have to be http:// or all of the file access has to be file:// resources in anything from the web also have to be specified with http:// that is the links and such in anything that comes from the web can not be //i/image.jpg they have to be http://www.example.com/i/image.jpg. That is web or file system have to be completely qualified.

Below I’m using a local directory in the file system by passing in the complete pathname of a file (it works to get a directory) The html is put into a string. Because I’m using loadDataWithBaseURL I can also access the interweb when it is prefixed by http://

StringBuilder sb = new StringBuilder();
                sb.append("<html><body><div style=\"width:100%; text-align:center; font-size:large;\">");
                sb.append(kmlmo.markeroptions.getTitle());
                sb.append("</div>");

                sb.append("<a href = \"http://www.example.com/link.html\">mylink</a>");

                sb.append(kmlmo.markeroptions.getSnippet());
                sb.append("</body></html>");
                View v = getView();
                if (v != null) {
                    wv = (WebView) v.findViewById(R.id.webView1);
                    if (wv != null) {
                        String localPath = "file://" + kmlmo.path;
                        String temp = sb.toString();
                        wv.loadDataWithBaseURL(localPath, temp, "text/html",
                                "UTF-8", "");
                    }

Answer:

After a lot of poking around, and a lot of help from the people who answered, the culprit in my code was the base tag. I removed it and also removed the html5mode thing. So, to sum it up, I removed the following :

 <base href="/">  

and

$locationProvider.html5Mode(true);

And everything started working.