Подавать изображения на локальном сервере с помощью NanoHttpd

Мне нужно создать локальный сервер, который сможет обслуживать локальные файлы устройства. Я нашел эту библиотеку, и похоже, что она способна удовлетворить мои потребности.

Я попробовал образец в этом проекте, и он отлично работает! Но он публикует страницу .html, и мне нужны картинки.

Я следил за этим сообщением , где .mp3 был подан. Но это не работает для меня. Вероятно, это потому, что библиотека была обновлена ​​с того времени.

@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
}

Сервер запускается в onCreate:

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

Цель состоит в том, чтобы получить доступ к таким файлам: 192.168.1.2:8080/picture.jpg

Кто-нибудь может предложить решение? Заранее спасибо.


person AnZ    schedule 08.06.2015    source источник
comment
Начните использовать другой метод serve(). Один с uri и параметрами. Как в ссылке на тот пост, который вы предоставили. Затем вы можете извлечь 'picture.jpg. первое или другие имена файлов. А вы не сказали, что именно у вас не работает. Thanks in advance. Очень неправильно. Вы должны пообещать поблагодарить, если вам хорошо помогли.   -  person greenapps    schedule 08.06.2015
comment
@greenapps, serve() с параметрами устарело. Во всяком случае, я тоже уже пробовал. Ни один из них не похож на обслуживание файлов. Я не могу получить к ним доступ по ip. На экране ничего не отображается   -  person AnZ    schedule 08.06.2015
comment
Ваш код должен быть в порядке, но удалите параметр: 1000000); //the last parameter is totalBytes.   -  person greenapps    schedule 08.06.2015
comment
@greenapps, это требуется конструктору Response. Response(IStatus status, String mimeType, InputStream data, long totalBytes). См. здесь.   -  person AnZ    schedule 08.06.2015
comment
Мммм, в моем NanaHTTPD.java есть три функции Response(). Похоже, я использую более старый файл .java. Хорошо, тогда вы должны указать в качестве суммы байтов длину файла или fis.available(). Попробуйте оба. Файл файл = новый файл (....полный путь..); file.length();.   -  person greenapps    schedule 08.06.2015
comment
@greenapps, ба, это все равно не работает... Я также пробовал возврат этого метода. Слушай, не мог бы ты залить куда-нибудь свою версию NanoHttpd? Я не особо гонюсь за новыми версиями. Все, что мне нужно, это его правильная работа   -  person AnZ    schedule 08.06.2015
comment
Завтра попробую новый файл с вашим кодом. Пожалуйста, дайте мне знак, если я забуду.   -  person greenapps    schedule 08.06.2015
comment
Но перед этим: каково значение file.getAbsolutePath() ? Пожалуйста, добавьте журнал `if (!file.exists()) (файл не существует); и вернуть текст вместо файла. Так что же такое ПУТЬ? Также, если произойдет уловка, верните текст, говорящий об этом.   -  person greenapps    schedule 08.06.2015
comment
@greenapps, абсолютный путь к файлу выглядит так: /sdcard/MyAppData/Routes/1/Resources/picture.jpg. Я проверяю его существование в другом классе. В этом посте file скорее манекен для проверки работы сервера.   -  person AnZ    schedule 09.06.2015
comment
Вы сказали: «Мне это не подходит». Но что происходит вместо этого? Я использовал новую библиотеку, но return new NanoHTTPD.Response(Response.Status.OK, "image/jpeg", fis, 1000000); даже не компилируется. Так что, пожалуйста, скажите. tried sample inside this project and it works fine! But it posts .html page . Ok. Пожалуйста, покажите этот код.   -  person greenapps    schedule 09.06.2015
comment
Тем временем я заставил его работать с новой версией. Подача jpg. Пожалуйста, покажите, как вы обслуживали этот html. Хотите сравнить.   -  person greenapps    schedule 09.06.2015
comment
@greenapps, это не компилируется, так как в примере есть другое возвращаемое значение. Проверьте это . Я попробовал код 1to1, и это сработало.   -  person AnZ    schedule 09.06.2015
comment
У вас была проблема, что этот staement также не скомпилировался? А ты не то говорил?   -  person greenapps    schedule 09.06.2015
comment
@greenapps, скомпилировалось без проблем. Но не сработало.   -  person AnZ    schedule 09.06.2015


Ответы (5)


В новой версии Response защищен.

Я использовал это для загрузки APK-файла, думаю, это сработает и для изображений:

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;
person Mariano L    schedule 25.02.2017

попробуйте этот, если вы не знаете общий размер файла, вам нужно указать -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
}

Изменить: правильные параметры для ответа:

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

Последний параметр — размер FileInputStream.

person Nasir Hussain    schedule 08.08.2016

Я очень взволнован ответами. Но, насколько я знаю, последний параметр - это размер файла (в (длинных) байтах). Следовательно, вы можете создать новое целое число и инициализировать его внутри блока try после инициализации fis следующим образом:

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

а затем установите размер в последний параметр.

person Sherzodbek    schedule 14.08.2016
comment
Это выглядит лучше, чем мое редактирование выше. Шерзодбек берет размер фиса; что более правильно, чем размер файла. (Хотя должно быть так же) - person Ivo Renkema; 26.08.2016

Итак, я загрузил предыдущую версию NanoHttpd, и это сработало для меня. . Возможно разработчики как-то изменили поведение в новой версии. У меня не было времени копаться в проблеме.

Это сработало для меня.

@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);
}

На самом деле это неправильный ответ, поскольку он не решает проблему с новой версией.

person AnZ    schedule 09.06.2015

Если вы используете NanoHTTPD версии 2.3.1+, синтаксис немного изменился. Вы можете использовать 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;
        }
person Lorne K    schedule 21.01.2020