1

I would like to deploy a web application on Android, stored in the assets directory. Since I use Html5 games I cannot load that HTML files directly from the file protocol.

myWebView.loadUrl("file:///android_asset/www/games/index.html");

because of it has some security issues like "Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https"

So I have successfully created a web server using NanoHTTPD, so that I can load that assets HTML file in http:// protocol

myWebView.loadUrl("http://localhost:8080/games/index.html");

but, The problem is that file:///android_asset/ is not an ordinary directory and I don't know any other way to access files inside it. I cannot set web root as file:///android_asset/ in Android.

So I need to know how to set webroot as file:///android_asset in nanohttpd response

mainactivity.java:

import android.content.res.AssetManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

import fi.iki.elonen.NanoHTTPD;

public class MainActivity extends AppCompatActivity {

    private static boolean isStarted = false;
    private AndroidWebServer androidWebServer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (!isStarted && startAndroidWebServer()) {
            isStarted = true;
            WebView simpleWebView=(WebView) findViewById(R.id.webview);
            simpleWebView.getSettings().setJavaScriptEnabled(true);
            simpleWebView.loadUrl("http://localhost:8080/games/index.html");
        }
    }

    private boolean startAndroidWebServer() {
        if (!isStarted) {
            try {
                int port = 8080;
                androidWebServer = new AndroidWebServer(port);
                androidWebServer.start();
                return true;
            }
            catch (Exception e) {
                Log.w("Httpd", "The server could not start."+e);
                e.printStackTrace();
            }
        }
        return false;
    }

    private boolean stopAndroidWebServer() {
        if (isStarted && androidWebServer != null) {
            androidWebServer.stop();
            return true;
        }
        return false;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopAndroidWebServer();
        isStarted = false;
    }

    private class AndroidWebServer extends NanoHTTPD {

        public AndroidWebServer(int port) {
            super(port);
        }

        @Override
        public Response serve(String uri, Method method,
                              Map<String, String> header, Map<String, String> parameters,
                              Map<String, String> files) {

            AssetManager am = getAssets();

            //  set web root as file:///android_asset/

            return newFixedLengthResponse(android_asset_directory_list);
        }
    }
}

This idea came from cordova-httpd which is a Cordova plugin using Nanohttpd. This plugin uses Cordova webview to access the assets/www/ content with HTTP protocol.

Or If you know any other way to access the android_asset directory in http protocol, explain it.

LucidKit
  • 28
  • 5

1 Answers1

0

Why not read the assets file using IOUtils:

/* code in Kotlin, but you get the meaning anyway */
val htmlContent = IOUtils.toString(assets.open("xml2json.txt")))
webView.loadData(htmlContent, "text/html", baseUrl)

ref: https://mvnrepository.com/artifact/commons-io/commons-io/2.5

also: 1. with the recent android support lib, it is no longer necessary to cast the findViewById(id) Java method, unless you do that in Kotlin:

val webView = findViewById<WebView>(R.id.webView)
Jack Cheung
  • 255
  • 2
  • 6
  • Thanks for the reply, Found another way to implement that web server on android using cordova-httpd – LucidKit May 09 '18 at 03:41