1

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.

Community
  • 1
  • 1
AnZ
  • 1,040
  • 24
  • 54
  • Start using a different serve() method. One with the uri and parameters. Like in the link to that post you provided. Then you can extract 'picture.jpg. first or other filenames. And you did not tell what exactly does not work for you. `Thanks in advance.` Very wrong. You should promise to thank if you got helped well. – greenapps Jun 08 '15 at 14:21
  • @greenapps, `serve()` with parameters is deprecated. Anyway, I have already tried it too. Any of them doesn't seem like serving files. I can't access them by ip. Nothing is displayed on screen – AnZ Jun 08 '15 at 14:29
  • Your code should be ok but remove a parameter: `1000000); //the last parameter is totalBytes.` – greenapps Jun 08 '15 at 14:31
  • @greenapps, the constructor on `Response` requires it. `Response(IStatus status, String mimeType, InputStream data, long totalBytes)`. See [here](https://github.com/NanoHttpd/nanohttpd/blob/master/core/src/main/java/fi/iki/elonen/NanoHTTPD.java#L1190) – AnZ Jun 08 '15 at 14:36
  • 1
    Mmmm in my NanaHTTPD.java there are three Response() functions. It appears that i use an older .java file. Well than you should supply as amountofbytes the file length or fis.available(). Try both. File file = new File ( ....fullpath..); `file.length();`. – greenapps Jun 08 '15 at 15:09
  • @greenapps, bah, that doesn't work anyway... I also tried [this method to return](https://github.com/NanoHttpd/nanohttpd/blob/master/core/src/main/java/fi/iki/elonen/NanoHTTPD.java#L1773). Listen, could you please upload somewhere your version of NanoHttpd? I don't really chasing new versions. All I need is proper operation of it – AnZ Jun 08 '15 at 17:14
  • 1
    Will try the new file tomorrow with your code. Please give me a sign if i forget. – greenapps Jun 08 '15 at 18:24
  • But before that: What is the value of `file.getAbsolutePath()` ? Please add an `if (!file.exists()) Log ( file does not exist); and return a text instead of a file. So what is PATH? Also if the catch happens return a text saying so. – greenapps Jun 08 '15 at 18:29
  • @greenapps, absolute path of file is like: `/sdcard/MyAppData/Routes/1/Resources/picture.jpg`. I'm checking for its existance in another class. In this post `file` is rather a dummy for checking the server work. – AnZ Jun 09 '15 at 09:01
  • You said 'it does not work for me'. But what happens instead? I used the new library but `return new NanoHTTPD.Response(Response.Status.OK, "image/jpeg", fis, 1000000); ` does not even compile. So please tell. `tried sample inside this project and it works fine! But it posts .html page `. Ok. Please show that code. – greenapps Jun 09 '15 at 11:21
  • Meanwhile i got it to work with the new version. Serving a jpg. Please show how you served that html. Wanna compare. – greenapps Jun 09 '15 at 11:26
  • @greenapps, that doesn't compile since in Sample there's another return value. Check [this](https://github.com/NanoHttpd/nanohttpd/blob/master/samples/src/main/java/fi/iki/elonen/HelloServer.java#L58). I tried 1to1 code and that worked. – AnZ Jun 09 '15 at 11:29
  • Did you have the problem that that staement did not compile also? And you were not telling that? – greenapps Jun 09 '15 at 11:33
  • @greenapps, that compiled without any problems. But didn't work. – AnZ Jun 09 '15 at 11:53

5 Answers5

2

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;
Mariano L
  • 1,809
  • 4
  • 29
  • 51
1

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.

Ivo Renkema
  • 2,188
  • 1
  • 29
  • 40
Nasir Hussain
  • 11
  • 1
  • 1
1

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.

Skatox
  • 4,237
  • 12
  • 42
  • 47
Sherzodbek
  • 296
  • 3
  • 9
  • This looks better than my edit above. Sherzodbek takes the size of the fis; which is more correct than the size of the file. (Although it should be the same) – Ivo Renkema Aug 26 '16 at 07:38
0

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.

AnZ
  • 1,040
  • 24
  • 54
0

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;
        }
Lorne K
  • 109
  • 7