javaandroidnanohttpd

File Directory Navigation with Android Nanohttpd lightweight server


With the code below, i was able to create a mobile server on android phone with the Nanohttpd lightweight server. The code basically loop through the root directory of the host android device and list both files and folders as links. What i want to implement is when a user clicks on any of the link (the folder links), the browser should display the files and folder contained in the clicked folder link. How do i do this as i can not find any Nanohttpd documentation for beginners.

import java.io.File;
import java.util.Map;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.widget.TextView;

public class MainActivity extends Activity {
    private static final int PORT = 8080;
    private TextView hello;
    private WebServer server;
    private Handler handler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        hello = (TextView) findViewById(R.id.hello);
    }

    /*
     * There are some earlier versions of android that can not implement this
     * method of getting IP address and isEmpty() method. The
     * 
     * @SupreesLint("NewAPI") helps to suppress the error that will arise in
     * such devices when implementing these methods . For the application
     * however, a minimum version of API that can be able to execute the
     * application flawlessly is set. The enables error checking as lower
     * version that can not implement this methods wouldn't be able to install
     * the application.
     */
    @SuppressLint("NewApi")
    @Override
    protected void onResume() {
        super.onResume();

        TextView textIpaddr = (TextView) findViewById(R.id.ipaddr);
        if (Utils.getIPAddress(true).trim().isEmpty()) {
            textIpaddr.setText(Utils.getIPAddress(false) + ":" + PORT);
        } else {
            textIpaddr.setText(Utils.getIPAddress(true) + ":" + PORT);
        }

        try {
            server = new WebServer();
            server.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String intToIp(int i) {

        return ((i >> 24) & 0xFF) + "." + ((i >> 16) & 0xFF) + "."
                + ((i >> 8) & 0xFF) + "." + (i & 0xFF);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (server != null)
            server.stop();
    }

    private class WebServer extends NanoHTTPD {

        public WebServer() {
            super(8080);
        }

        @Override
        public Response serve(String uri, Method method,
                Map<String, String> header, Map<String, String> parameters,
                Map<String, String> files) {
            File rootDir = Environment.getExternalStorageDirectory();
            File[] files2 = rootDir.listFiles();
            String answer = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>sdcard0 - TECNO P5 - WiFi File Transfer Pro</title>";
            for (File detailsOfFiles : files2) {
                answer += "<a href=\"" + detailsOfFiles.getAbsolutePath()
                        + "\" alt = \"\">" + detailsOfFiles.getAbsolutePath()
                        + "</a><br>";
            }
            answer += "</head></html>";
            return new NanoHTTPD.Response(answer);
        }



    }

}

: Here is how the output looks like in my browser


Solution

  • i finally figure out how to do this after enough time of studying the NanoHTTPD Framework.The code below helps me to navigate within the directories in the host android device:

    @Override
            public Response serve(String uri, Method method,
                    Map<String, String> header, Map<String, String> parameters,
                    Map<String, String> files) {
                File rootDir = Environment.getExternalStorageDirectory();
                File[] filesList = null;
                String filepath = "";
                if (uri.trim().isEmpty()) {
                    filesList = rootDir.listFiles();
                } else {
                    filepath = uri.trim();
                }
                filesList = new File(filepath).listFiles();
                String answer = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>sdcard0 - TECNO P5 - WiFi File Transfer Pro</title>";
                if (new File(filepath).isDirectory()) {
                    for (File detailsOfFiles : filesList) {
                        answer += "<a href=\"" + detailsOfFiles.getAbsolutePath()
                                + "\" alt = \"\">"
                                + detailsOfFiles.getAbsolutePath() + "</a><br>";
                    }
                } else {
                }
                answer += "</head></html>" + "uri: " + uri + " \nfiles " + files
                        + " \nparameters " + parameters + " \nheader ";
                return new NanoHTTPD.Response(answer);
            }
    

    the uri parameter in the Response Method contains browser url at that point in time: Example if url displaying on the address bar is: /192.168.43.1:8080/storage/sdcard1/Smadav_2012_Rev._9.0, then uri contains /storage/sdcard1/Smadav_2012_Rev._9.0. What i did is to just pass the uri as a filepath and of course, this is not the case for first connection when the uri is empty.