Como os desenvolvedores do Android recomendam usar a HttpURLConnection
classe, fiquei pensando se alguém pode me fornecer um bom exemplo de como enviar um "arquivo" de bitmap (na verdade, um fluxo de memória) via POST para um servidor HTTP Apache. Não estou interessado em cookies, autenticação ou qualquer coisa complicada, mas só quero ter uma implementação confiável e lógica. Todos os exemplos que eu vi por aqui parecem mais com "vamos tentar isso e talvez funcione".
No momento, eu tenho este código:
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL("http://example.com/server.cgi");
urlConnection = (HttpURLConnection) url.openConnection();
} catch (Exception e) {
this.showDialog(getApplicationContext(), e.getMessage());
}
finally {
if (urlConnection != null)
{
urlConnection.disconnect();
}
}
onde showDialog deve apenas exibir um AlertDialog
(no caso de um URL inválido?).
Agora, digamos que eu gere um bitmap da seguinte forma: Bitmap image = this.getBitmap()
dentro de um controle derivado de View
e quero enviá-lo via POST. Qual seria o procedimento adequado para conseguir isso? Quais classes eu preciso usar? Posso usar HttpPost
como neste exemplo ? Em caso afirmativo, como eu construiria o InputStreamEntity
para o meu bitmap? Eu achava revoltante ser necessário primeiro armazenar o bitmap em um arquivo no dispositivo.
Devo também mencionar que eu realmente preciso enviar todos os pixels inalterados do bitmap original para o servidor, para não poder convertê-lo para JPEG.
fonte
Respostas:
Não faço ideia por que a
HttpURLConnection
classe não fornece meios para enviar arquivos sem precisar compor o wrapper de arquivo manualmente. Aqui está o que eu acabei fazendo, mas se alguém souber uma solução melhor, entre em contato.Dados de entrada:
Coisas estáticas:
Configure a solicitação:
Inicie o wrapper de conteúdo:
Converter
Bitmap
emByteBuffer
:Wrapper de conteúdo final:
Buffer de saída nivelado:
Obter resposta:
Fechar fluxo de resposta:
Feche a conexão:
PS: É claro que eu tive que encerrar a solicitação
private class AsyncUploadBitmaps extends AsyncTask<Bitmap, Void, String>
para fazer a plataforma Android feliz, porque ela não gosta de ter solicitações de rede no segmento principal.fonte
url
variável, assim:URL url = new URL("http://example.com/?param1=val1¶m2=val2");
. Você pode adicionar quantos desejar (embora eu ache que haja alguns limites).Na verdade, encontrei uma maneira melhor de enviar arquivos usando HttpURLConnection usando MultipartEntity
Supondo que você esteja carregando uma imagem com dados de bitmap:
E Voila! Seus dados de postagem conterão um campo de imagem junto com o nome do arquivo e o caminho no seu servidor.
fonte
Carregar arquivo no servidor com algum parâmetro usando de
MultipartUtility
maneira simples.MultipartUtility.java
Para
upload
você,file
juntamente com os parâmetros.NOTA: coloque este código abaixo em um tópico que não seja da interface do usuário para obter resposta.
fonte
A solução de Jaydipsinh Zala não funcionou para mim, não sei por que, mas parece estar próxima da solução.
Então, mesclando esta com a ótima solução e explicação de Mihai Todor , o resultado é essa classe que atualmente funciona para mim. Se isso ajudar alguém:
MultipartUtility2V.java
fonte
Esta resposta https://stackoverflow.com/a/33149413/6481542 me levou 90% do caminho com o upload de arquivos grandes para um servidor Django de desenvolvimento, mas eu tive que usar setFixedLengthStreamingMode para fazê-lo funcionar. Isso requer a configuração do comprimento do conteúdo antes de escrever o conteúdo, exigindo uma reescrita bastante significativa da resposta acima. Aqui está o meu resultado final
O uso é basicamente o mesmo da resposta acima, mas incluí o suporte CSRF que o Django usa por padrão nos formulários
fonte
com base na solução de Mihai, se alguém tiver o problema de salvar imagens no servidor, como o que aconteceu no meu servidor. altere o Bitmap para bytebuffer parte para:
fonte
Não testei isso, mas você pode tentar usar o PipedInputStream e o PipedOutputStream. Pode parecer algo como:
fonte
Aqui está o que eu fiz para fazer upload de fotos usando a solicitação de postagem.
NOTA: Este código requer bibliotecas, portanto, siga as instruções aqui para obter as bibliotecas.
fonte
HttpClient
(seu link está desatualizado. Use este ), que os caras do Android mantêm apenas para compatibilidade com versões anteriores, em vez de usar o incorporadoHttpURLConnection
. Por outro lado, parece que requer mais trabalho para configurá-lo, portanto, talvez não valha a pena o esforço.Achei o uso do okHttp muito mais fácil, pois não consegui usar nenhuma dessas soluções: https://stackoverflow.com/a/37942387/447549
fonte
Eu tentei as soluções acima e nenhuma funcionou para mim imediatamente.
No entanto, http://www.baeldung.com/httpclient-post-http-request . A solicitação de multipartes da linha 6 POST funcionou em segundos
fonte