Dado que los desarrolladores de Android recomiendan usar la HttpURLConnection
clase, me preguntaba si alguien puede proporcionarme un buen ejemplo sobre cómo enviar un "archivo" de mapa de bits (en realidad un flujo en memoria) a través de POST a un servidor HTTP Apache. No me interesan las cookies, la autenticación ni nada complicado, pero solo quiero tener una implementación confiable y lógica. Todos los ejemplos que he visto por aquí se parecen más a "intentemos esto y tal vez funcione".
En este momento, tengo 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();
}
}
donde showDialog solo debe mostrar un AlertDialog
(en caso de una URL no válida?).
Ahora, digamos que genero un mapa de bits como este: Bitmap image = this.getBitmap()
dentro de un control derivado de View
y quiero enviarlo a través de POST. ¿Cuál sería el procedimiento adecuado para lograr tal cosa? ¿Qué clases necesito usar? ¿Puedo usar HttpPost
like en este ejemplo ? Si es así, ¿cómo construiría el InputStreamEntity
para mi mapa de bits? Me resultaría repugnante que se requiera almacenar primero el mapa de bits en un archivo en el dispositivo.
También debo mencionar que realmente necesito enviar cada píxel inalterado del mapa de bits original al servidor, por lo que no puedo convertirlo a JPEG.
fuente
Respuestas:
No tengo idea de por qué la
HttpURLConnection
clase no proporciona ningún medio para enviar archivos sin tener que componer el contenedor de archivos manualmente. Esto es lo que terminé haciendo, pero si alguien conoce una mejor solución, hágamelo saber.Datos de entrada:
Material estático:
Configurar la solicitud:
Iniciar contenedor de contenido:
Convierte
Bitmap
aByteBuffer
:Contenedor de contenido final:
Búfer de salida de lavado:
Obtener una respuesta:
Cerrar flujo de respuesta:
Cierra la conexión:
PD: Por supuesto, tuve que completar la solicitud
private class AsyncUploadBitmaps extends AsyncTask<Bitmap, Void, String>
para hacer feliz a la plataforma Android, porque no le gusta tener solicitudes de red en el hilo principal.fuente
url
variable, así:URL url = new URL("http://example.com/?param1=val1¶m2=val2");
. Puede agregar tantos como desee (aunque creo que hay algunos límites).En realidad, encontré una mejor manera de enviar archivos usando HttpURLConnection usando MultipartEntity
Suponiendo que está cargando una imagen con datos de mapa de bits:
¡Y voilá! Sus datos de publicación contendrán un campo de imagen junto con el nombre de archivo y la ruta en su servidor.
fuente
Para cargar archivos en el servidor con algún parámetro utilizando
MultipartUtility
de manera simple.MultipartUtility.java
A
upload
ustedfile
junto con los parámetros.NOTA: coloque este código a continuación en un subproceso que no sea ui para obtener respuesta.
fuente
La solución de Jaydipsinh Zala no funcionó para mí, no sé por qué, pero parece estar cerca de la solución.
Así que fusionando este con la gran solución y explicación de Mihai Todor , el resultado es esta clase que actualmente funciona para mí. Si ayuda a alguien:
MultipartUtility2V.java
fuente
Esta respuesta https://stackoverflow.com/a/33149413/6481542 me consiguió el 90% del camino cargando archivos grandes en un servidor Django de desarrollo, pero tuve que usar setFixedLengthStreamingMode para que funcionara. Eso requiere establecer la longitud del contenido antes de escribir el contenido, lo que requiere una reescritura bastante significativa de la respuesta anterior. Aquí está mi resultado final
El uso es en gran medida el mismo que en la respuesta anterior, pero he incluido el soporte CSRF que Django usa de forma predeterminada con los formularios
fuente
basado en la solución de Mihai, si alguien tiene el problema de guardar imágenes en el servidor como lo que sucedió en mi servidor. cambie el mapa de bits a la parte bytebuffer a:
fuente
No he probado esto, pero puedes intentar usar PipedInputStream y PipedOutputStream. Puede verse algo así como:
fuente
Esto es lo que hice para subir fotos usando la solicitud de publicación.
NOTA: Este código requiere bibliotecas, así que siga las instrucciones aquí para obtener las bibliotecas.
fuente
HttpClient
(su enlace está desactualizado. Use este en su lugar), que los chicos de Android mantienen solo por compatibilidad con versiones anteriores, en lugar de usar el incorporadoHttpURLConnection
. Por otro lado, parece que requiere más trabajo configurarlo, por lo que tal vez no valga la pena el esfuerzo.Encontré el uso de okHttp mucho más fácil ya que no pude lograr que ninguna de estas soluciones funcionara: https://stackoverflow.com/a/37942387/447549
fuente
Probé las soluciones anteriores y ninguna funcionó para mí fuera de la caja.
Sin embargo, http://www.baeldung.com/httpclient-post-http-request . La línea 6 POST Multipart Request funcionó en segundos
fuente