I can't make nanohttpd work. It seems not be able to find the www
directory in app's root.
My code is at https://github.com/tlkahn/neonx
My code at MainActivity.java:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navView = findViewById(R.id.nav_view);
mWebView = findViewById(R.id.webkit);
navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
WebSettings webSettings = mWebView.getSettings();
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
webSettings.setDomStorageEnabled(true);
mWebView.getSettings().setLoadsImagesAutomatically(true);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return false;
}
});
if (!haveNetworkConnection()) {
new AlertDialog.Builder(this)
.setTitle("You are not connected to internet.")
.setMessage("Are you sure you want to exit?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finishAffinity();
System.exit(0);
}
}).setNegativeButton("No", null).show();
}
startLocalServer(3000, "www", true, true );
}
public void startLocalServer(int port, String root, Boolean localhost, Boolean keepAlive) {
try {
File www_root = new File(root);
server = new WebServer("localhost", port, www_root.getAbsoluteFile());
server.start();
printIp();
} catch (IOException e) {
e.printStackTrace();
}
}
When I tried to visit localhost:3000
, I got the error: given path is not a directory. The error seems to come from this line: https://git.io/fjS3f
I guess the way I initialize the rootDir is wrong (this line: https://git.io/fjS3v). But how can I make this work? I mean to serve the whole directory, which means all CSS/JS/hypyerlinks should work, once nanohttpd starts serving...
LogCat:
2019-08-05 15:21:53.838 10650-10650/com.neonxorg.neonx E/MainActivity: -------Assets List-----
2019-08-05 15:21:53.838 10650-10650/com.neonxorg.neonx E/MainActivity: asset-manifest.json
2019-08-05 15:21:53.838 10650-10650/com.neonxorg.neonx E/MainActivity: favicon.ico
2019-08-05 15:21:53.838 10650-10650/com.neonxorg.neonx E/MainActivity: index.html
2019-08-05 15:21:53.838 10650-10650/com.neonxorg.neonx E/MainActivity: manifest.json
2019-08-05 15:21:53.838 10650-10650/com.neonxorg.neonx E/MainActivity: precache-manifest.81af63d07b6dd6ae8e331187c522b020.js
2019-08-05 15:21:53.838 10650-10650/com.neonxorg.neonx E/MainActivity: service-worker.js
2019-08-05 15:21:53.838 10650-10650/com.neonxorg.neonx E/MainActivity: static
2019-08-05 15:21:53.842 10650-10650/com.neonxorg.neonx E/MainActivity: copyFolderFromAssets rootDirFullPath-www targetDirFullPath-/storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www
2019-08-05 15:21:53.865 10650-10650/com.neonxorg.neonx E/MainActivity: copyFolderFromAssets rootDirFullPath-www/static targetDirFullPath-/storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/static
2019-08-05 15:21:53.867 10650-10650/com.neonxorg.neonx E/MainActivity: copyFolderFromAssets rootDirFullPath-www/static/css targetDirFullPath-/storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/static/css
2019-08-05 15:21:53.922 10650-10650/com.neonxorg.neonx E/MainActivity: copyFolderFromAssets rootDirFullPath-www/static/js targetDirFullPath-/storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/static/js
2019-08-05 15:21:54.352 10650-10650/com.neonxorg.neonx E/MainActivity: copyFolderFromAssets rootDirFullPath-www/static/media targetDirFullPath-/storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/static/media
2019-08-05 15:21:54.526 10650-10650/com.neonxorg.neonx E/MainActivity: -------Root File List-----
2019-08-05 15:21:54.528 10650-10650/com.neonxorg.neonx E/File: /storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/precache-manifest.81af63d07b6dd6ae8e331187c522b020.js
2019-08-05 15:21:54.528 10650-10650/com.neonxorg.neonx E/File: /storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/service-worker.js
2019-08-05 15:21:54.528 10650-10650/com.neonxorg.neonx E/File: /storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/static
2019-08-05 15:21:54.528 10650-10650/com.neonxorg.neonx E/File: /storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/favicon.ico
2019-08-05 15:21:54.528 10650-10650/com.neonxorg.neonx E/File: /storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/manifest.json
2019-08-05 15:21:54.528 10650-10650/com.neonxorg.neonx E/File: /storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/asset-manifest.json
2019-08-05 15:21:54.528 10650-10650/com.neonxorg.neonx E/File: /storage/emulated/0/Android/data/com.neonxorg.neonx/cache/www/index.html
2019-08-05 15:21:54.704 10650-10650/com.neonxorg.neonx E/MainActivity: Connected : Please access! http://192.168.1.2:3000 From a web browser
Code:
public final String TAG = getClass().getSimpleName();
public void startLocalServer(int port, String root, Boolean localhost, Boolean keepAlive) {
try {
String[] filePathList = (getAssets().list("www"));
Log.e(TAG,"-------Assets List-----");
for (String s : filePathList) {
Log.e(TAG, s);
}
File externalCache = getExternalCacheDir();
if (externalCache != null) {
String path = externalCache.getAbsolutePath() + "/" + root;
copyFolderFromAssets(getApplicationContext(), "www", path);
File www_root = new File(path);
Log.e(TAG,"-------Root File List-----");
for (File f : www_root.listFiles()) {
Log.e("File ", f.getAbsolutePath());
}
server = new WebServer("localhost", port, www_root.getCanonicalFile());
server.start();
printIp();
}
} catch (IOException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
public void copyFolderFromAssets(Context context, String rootDirFullPath, String targetDirFullPath) {
Log.e(TAG,"copyFolderFromAssets " + "rootDirFullPath-" + rootDirFullPath + " targetDirFullPath-" + targetDirFullPath);
File file = new File(targetDirFullPath);
if (!file.exists()) {
new File(targetDirFullPath).mkdirs();
}
try {
String[] listFiles = context.getAssets().list(rootDirFullPath);// 遍历该目录下的文件和文件夹
for (String string : listFiles) {// 看起子目录是文件还是文件夹,这里只好用.做区分了
if (isFileByName(string)) {// 文件
copyFileFromAssets(context, rootDirFullPath + "/" + string, targetDirFullPath + "/" + string);
} else {// 文件夹
String childRootDirFullPath = rootDirFullPath + "/" + string;
String childTargetDirFullPath = targetDirFullPath + "/" + string;
new File(childTargetDirFullPath).mkdirs();
copyFolderFromAssets(context, childRootDirFullPath, childTargetDirFullPath);
}
}
} catch (IOException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
public void copyFileFromAssets(Context context, String assetsFilePath, String targetFileFullPath) {
InputStream assestsFileInputStream;
try {
assestsFileInputStream = context.getAssets().open(assetsFilePath);
FileOutputStream fOS = new FileOutputStream(new File(targetFileFullPath));
int length = -1;
byte[] buf = new byte[1024];
while ((length = assestsFileInputStream.read(buf)) != -1) {
fOS.write(buf, 0, length);
}
fOS.flush();
} catch (IOException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
private boolean isFileByName(String str) {
return str.contains(".");
}
private void printIp() {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
final String formatedIpAddress = String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff),
(ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff));
Log.e(TAG,"Connected : " + "Please access! http://" + formatedIpAddress + ":" + server.getListeningPort() + " From a web browser");
}
given path is not a directory.
When nanphttpd is not able to locate the data then it gives this error.
Why You are not getting the actual error
In the catch block of copyFolderFromAssets
and copyFileFromAssets
you are using e.printStackTrace()
which may not be showing on your LogCat due to Show only selected application filter
In order to print the errors, you need to use the following:
Log.e(TAG, Log.getStackTraceString(e));
I replaced all of your System.out and e.printStackTrace with Log.e statements. Most likely the app wasn't able to copy contents from www directory to target directory. I changed target directory to cache directory and it worked on my device. (see below):
File externalCache = getExternalCacheDir();
if (externalCache != null) {
String path = externalCache.getAbsolutePath() + "/" + root;
File www_root = new File(path);
copyFolderFromAssets(getApplicationContext(), "www", path);
Log.e(TAG,"-------Root File List-----");
for (File f : www_root.listFiles()) {
Log.e("File ", f.getAbsolutePath());
}
server = new WebServer("localhost", port, www_root.getCanonicalFile());
server.start();
printIp();
}
Sidenote:
static
keyword in those function until or unless you want to copy them in a utility class