Como baixar dois ou vários arquivos de uma vez no Android usando o NanoHTTPD?

9

Eu uso o NanoHTTPD como servidor da Web no meu aplicativo para Android.

Eu passo dois nomes de arquivo do navegador cliente para o servidor NanoHTTPD, e espero fazer o download dos dois arquivos por vez, mas o código a seguir faz o download do arquivo1, e o arquivo2 não é baixado.

Como baixar dois ou vários arquivos por vez?

public class MyWebServer extends NanoHTTPD
{

    private final String rootDir;

    public MyWebServer(int port, String rootDir)
    {
        super("192.168.1.4", port);
        this.rootDir = rootDir;
    }

    @Override
    public Response serve(IHTTPSession session)
    {       
        Map<String, String> parms = session.getParms();

        String filename1=GetFilename(parms);
        String filename2=GetFilename(parms);

        File file1 = new File(rootDir + filename1);
        File file2 = new File(rootDir + filename2);

        return downloadFile(file1);
        return downloadFile(file2);
    }


    private Response downloadFile(File file)
    {
        FileInputStream fis = null;
        try
        {
            fis = new FileInputStream(file);
        } catch (FileNotFoundException ex)
        {
            Logger.getLogger(MyWebServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        return newFixedLengthResponse(Response.Status.OK, "application/octet-stream", fis, file.getTotalSpace());
    }



    @Override
    public Response newFixedLengthResponse(IStatus status, String mimeType, String message)
    {
        Response response = super.newFixedLengthResponse(status, mimeType, message);
        response.addHeader("Accept-Ranges", "bytes");
        return response;
    }


}
    
por HelloCW 15.02.2017 в 04:29
fonte

2 respostas

3

Abaixo NanoHTTPD construtor cria uma tarefa assíncrona quando você chama super(..) no construtor MyWebServer.

public NanoHTTPD(String hostname, int port) {
        this.hostname = hostname;
        this.myPort = port;
        setTempFileManagerFactory(new DefaultTempFileManagerFactory());
        setAsyncRunner(new DefaultAsyncRunner());

        // creates a default handler that redirects to deprecated serve();
        this.httpHandler = new IHandler<IHTTPSession, Response>() {

            @Override
            public Response handle(IHTTPSession input) {
                return NanoHTTPD.this.serve(input);
            }
        };
    }

Portanto, a resposta deve ser ter um downloadFile() para cada operação. Ou seja, você deve chamar new MyWebServer() para iniciar cada tarefa de download.

@Override
    public Response serve(IHTTPSession session)
    {       
        Map<String, String> parms = session.getParms();

        String filename=GetFilename(parms);

        File file = new File(rootDir + filename);

        return downloadFile(file);
    }

EDITAR:

Usando 2 instâncias da classe MyWebServer, você pode ouvir solicitações de clientes para cada um dos 2 parâmetros. (Eu não tentei isso, mas ele deve funcionar e eu recomendo que você envie várias solicitações no lado do cliente e uma instância do servidor web no lado do servidor).

public class MyWebServer extends NanoHTTPD
{

    private final String rootDir;
    private final int param_type = 1; //default 1

    public MyWebServer(int port, String rootDir, int param)
    {
        super("192.168.1.4", port);
        this.rootDir = rootDir;
        this.param_type = param;
    }

    @Override
    public Response serve(IHTTPSession session)
    {       
        Map<String, String> parms = session.getParms();
        File file;

        if (param_type == 1){
             String filename=parms.get("param1");
             file = new File(rootDir + filename);
        }else if(param_type == 2){ 
             String filename=parms.get("param2");
             file = new File(rootDir + filename);
        }


        return downloadFile(file);
    }


    private Response downloadFile(File file)
    {
        FileInputStream fis = null;
        try
        {
            fis = new FileInputStream(file);
        } catch (FileNotFoundException ex)
        {
            Logger.getLogger(MyWebServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        return newFixedLengthResponse(Response.Status.OK, "application/octet-stream", fis, file.getTotalSpace());
    }



    @Override
    public Response newFixedLengthResponse(IStatus status, String mimeType, String message)
    {
        Response response = super.newFixedLengthResponse(status, mimeType, message);
        response.addHeader("Accept-Ranges", "bytes");
        return response;
    }


}

Em MainActivity.java

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        MyWebServer server1 = new MyWebServer(port, rootDir, 1);
        MyWebServer server2 = new MyWebServer(port, rootDir, 2);

        server1.start();
        server2.start();

    }
    
por ugur 22.02.2017 / 23:45
fonte
-1

Em Java, quando você deseja que uma função retorne vários valores, você deve incorporar esses valores em um objeto retornado. Então você precisa definir uma classe (por exemplo: ReturnDownlowds ) que poderia ter dois objetos:

public class ReturnDownlowds {
    private File downloadFile1;
    private File downloadFile2;
  

// adiciona outros campos, construtor e acessadores

}

E no seu método do servidor de resposta, você precisa recuperar uma amostra dessa classe assim:

return new ReturnDownlowds(downloadFile1, downloadFile2) ;

Espero que isso seja uma pequena ajuda.

    
por Hossein Seifi 19.02.2017 / 22:34
fonte