4

I have an app (Let's call it the Main App) which has an index.html page in the assets folder. The index.html is a simple HTML file with some JavaScript. It doesn't need PHP or MySql.

What I'm trying to do is embed the NanoHttpd server within my Main app, and automatically start the Nano server when the app starts or resumes, and view my index.html file within my app. While I know I can use the

webView.loadUrl("file:///android_asset/index.html"); 

to access the index.html file, it is impossible to do that for this scenario. Hence the need to use a webserver.

Right now I have a different dedicated app as a web server, which runs at http://localhost:8080. When I open the Main app, it works automatically. As you can see, in order to view the HTML file, you need to launch the web server, start it, then go back to the Main app and start it. I wanted a solution where the NanoHttpd server starts automatically when I lunch my Main App and starts showing the index.html contents on the webview. Here is my code which works perfectly using my Main App and a web server

   WebView wv;
   wv = (WebView) findViewById(R.id.webView1);
   WebSettings webSettings = wv.getSettings();
   webSettings.setJavaScriptEnabled(true);
   wv.loadUrl("http://localhost:8080/index.html");   

While O couldn't find the exact documentation for it, I tried two different approaches from the following links

  1. Using NanoHTTPD in Android

  2. http://programminglife.io/android-http-server-with-nanohttpd/

Both didn't work, One just shows a white page while the others just gives me a response that the server is running.

So how can I automatically start NanoHttpd server when my app starts and automatically launch an html file from my assets folder to a webview? If it's too much to ask for the NanoHttpd, is there another way to embed a webserver with an app and launch the index.html?

Zoe
  • 27,060
  • 21
  • 118
  • 148
user3659497
  • 445
  • 1
  • 6
  • 15
  • Just a plain **WebView.loadUrl(asset.html)** does not fit for your project? If you have a built website without too much complications (php, mysql etc for example), just copy this website into your assets folder and open it on your webview. On this case, no httpd daemon is needed. – statosdotcom Feb 14 '19 at 19:10
  • @statosdotcom The index.html is actually an html document with lots of JavaScript. No php, no MySQL required. Loading the file via file:/// doesn’t work due to browser security – user3659497 Feb 14 '19 at 19:27

2 Answers2

2

Given you have your HTML structure on your assets folder following this hierarchy:

+ src
++ main
+++ assets
+++ java
+++ res

You can use the following method to open a local file without security restriction:

webView.loadUrl("file:///android_asset/index.html");

Also you should set this to enable Javascript to run locally before load content:

webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setJavaScriptEnabled(true);

Additionally you can set some other settings to best fit your demands like:

setBuiltInZoomControls(true);
setSupportZoom(true);
setDefaultTextEncodingName("utf-8"); // support international chars
setUserAgentString("myVeryOwnUserAgent");  // personalize UA

And so on.

statosdotcom
  • 3,109
  • 2
  • 17
  • 40
  • Thanks but webView.loadUrl("file:///android_asset/index.html") doesn’t work due to browser security restrictions, that’s why I needed the web server. I’ve update the question with this information – user3659497 Feb 14 '19 at 20:04
  • I am sorry. I think you are wrong, with all my respect, sir. Have you tried my proposal? I have many working projects following this format. Read carefully, implement and then return here, please. Look: `f:///` is one thing, `file:///` is another one. Also: there are tons of examples out there instructing how to open a local file into a webView. No security questions at all. Try with a simple helloworld html. Maybe the matter is another point, maybe a js trying to load outside content. – statosdotcom Feb 14 '19 at 20:17
  • My mistake, f:/// was a typo. While you are absolutely right that i can access files that way, i can't do that for this project. That's why i have to use the web server. If you want details on why i can't do it, please check the following link (It's a long url, so copy the whole url and paste it ) http://www.kolor.com/wiki-en/action/view/Panotour_-_FAQ_-_Viewing_the_tour_offline#Local_usage_with_file:.2F.2F_urls_is_limited_due_to_browser_security_restrictions.21 – user3659497 Feb 14 '19 at 20:37
  • I followed you first comment: `Loading the file via file:/// doesn’t work due to browser security`, which only now, after all of that, we see it was (at best) incomplete. Thanks for your respect with people who is trying to help you. – statosdotcom Feb 14 '19 at 20:41
  • my apologies for not asking a complete question at first, as you can see, i'm trying to update my question to better provide accurate information about the problem. Anyways, thank you very much for your valuable time. I really appreciate it – user3659497 Feb 14 '19 at 20:47
  • My friend, thank you for your follow up. I wish you find a solution for your case. Sorry for anything here, too. Best luck. Gracias. – statosdotcom Feb 14 '19 at 20:52
  • My friend, reading again your question, I was thinking: if you can get a `response that the server is running`, then all you have to do is figure out **from where** your server is running. I mean: where is the root folder of the httpd at you mobile's filesystem. Once the root is located, all you have to do is copy (or save) your files there then load'em trough `wv.loadUrl("http://localhost:8080/index.html");`, as is actually working. – statosdotcom Feb 14 '19 at 21:04
  • thank you friend, I also though I should dig further when it started showing a response that the server is running – user3659497 Feb 14 '19 at 21:10
0

Assuming there is really only a single HTML file, the following works in Java, try running it on your computer:

public class Server extends NanoHTTPD {
    final private String indexString = readFile("in/index.html");

    public static void main(String[] args) throws IOException {
        Server server = new Server();
        server.start();
        while(true){};
    }

    public Server() throws IOException {
        super(8080);
    }

    @Override
    public Response serve(IHTTPSession session) {
        return newFixedLengthResponse(indexString);
    }

    private static String readFile(String path) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(path));
        try {
            StringBuilder sb = new StringBuilder();
            String line = br.readLine();

            while (line != null) {
                sb.append(line);
                sb.append("\n");
                line = br.readLine();
            }
            return sb.toString();
        } finally {
            br.close();
        }
    }
}

The main method is an example usage. To make it work on your application, start the server as exemplified, then use webView.loadUrl("http://localhost:8080"); instead of the infinite loop (which is there to ensure the example application doesn't quit early).