Serve images on local server using NanoHttpd

5.2k views Asked by At

I need to create a local server which would be able to serve local files of device. I have found this library and it seems like it able to satisfy my needs.

I have tried sample inside this project and it works fine! But it posts .html page and I need pictures.

I was following this post where .mp3 was served. But that doesn't work for me. Probably that's because library was updated from that time.

@Override
public Response serve(IHTTPSession session) {

    FileInputStream fis = null;
    try {
        File file = new File(Environment.getExternalStoragePublicDirectory(ROOT)
                + PATH + "picture.jpg"); //path exists and its correct
        fis = new FileInputStream(file);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return new NanoHTTPD.Response(Response.Status.OK, "image/jpeg", fis, 1000000); //the last parameter is totalBytes. Not sure what to put there
}

Server is started in onCreate:

//start web server
    try {
        server = new WebServer();
        server.start();
    } catch (IOException e) {
        e.printStackTrace();
    }

The aim is to access files like that: 192.168.1.2:8080/picture.jpg

Can anyone suggest solution? Thanks in advance.

5

There are 5 answers

0
AnZ On

So I have downloaded previous version of NanoHttpd and that worked for me. Probably developers changed the behaviour somehow in new version. I didn't have time to dig inside the problem.

This worked for me.

@Override
public Response serve(String uri, Method method, Map<String, String> header, Map<String, String> parms, Map<String, String> files) {
    FileInputStream fis = null;
    try {
        File file = new File(Environment.getExternalStoragePublicDirectory(ROOT)
                + PATH + "picture.jpg");

        if (file.exists()){
            fis = new FileInputStream(file);
            Log.d(TAG, "File exists: " + file.getAbsolutePath());
        } else {
            Log.d(TAG, "File doesn't exist!");
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    return new NanoHTTPD.Response(Response.Status.OK, "image/jpeg", fis);
}

This is not actually a correct answer since it doesn't solve problem with new version.

0
Nasir Hussain On

try this one, if you don't know the total size of file then you have to give -T

@Override
public Response serve(IHTTPSession session) {
     FileInputStream fis = null;
     try {
        File file = new File(Environment.getExternalStoragePublicDirectory(ROOT)
            + PATH + "picture.jpg"); //path exists and its correct
        fis = new FileInputStream(file);
     } catch (FileNotFoundException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
     }
     return new NanoHTTPD.Response(Response.Status.OK, "image/jpeg", fis, -1); //the last parameter is totalBytes. Not sure what to put there
}

Edit: The correct parameters for the response are:

return new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK, "image/jpeg", fis, file.length());

The last parameter is the size of the FileInputStream.

1
Sherzodbek On

I am very excited about the answers. But, as far as I know last parameter is size of file (in (long) bytes). Hence, you can create new integer and initialize it inside try block, after initializing fis, as follows:

size=fis.available();   //  returns available size of file

and then set size to the last parameter.

0
Mariano L On

In the new version Response is protected.

I used this to download a APK file, I guess this will work for images too:

File f = new File("apk/app-release.apk");
FileInputStream fis = new FileInputStream(f);
Response res = newChunkedResponse(Response.Status.OK, "application/vnd.android.package-archive", fis);
res.addHeader("Content-Disposition", "attachment; filename=\"" + f.getName() + "\"");
return res;
0
Lorne K On

If you are on NanoHTTPD version 2.3.1+ the syntax has changed a bit. You can use newFixedLengthResponse(...)

    @Override
public Response serve(IHTTPSession session) {

    switch (session.getUri()) {
        case "/config.png": {
            try {
                FileInputStream fis = context.openFileInput("config.png");
                return newFixedLengthResponse(Status.OK, "image/png", fis, fis.available());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }