Publicar solicitud de varias partes con el SDK de Android
Estoy intentando hacer algo que pensé que sería relativamente simple: cargar una imagen a un servidor con el SDK de Android. Encontré muchos códigos de ejemplo:
http://groups.google.com/group/android-developers/browse_thread/thread/f9e17bbaf50c5fc/46145fcacd450e48
http://linklens.blogspot.com/2009/06/android-multipart-upload.html
Pero ninguno de los dos funciona para mí. La confusión con la que me sigo encontrando es qué es lo que realmente se necesita para realizar una solicitud de varias partes. ¿ Cuál es la forma más sencilla de realizar una carga de varias partes (con una imagen) para Android?
¡Cualquier ayuda o consejo será muy apreciado!
Actualización 29 de abril de 2014:
Mi respuesta ya es un poco antigua y supongo que prefieres utilizar algún tipo de biblioteca de alto nivel como Retrofit .
Basándome en este blog, se me ocurrió la siguiente solución: http://blog.tacticalnuclearstrike.com/2010/01/using-multipartentity-in-android-applications/
¡Tendrás que descargar bibliotecas adicionales para comenzar a MultipartEntity
ejecutarlo!
1) Descargue httpcomponents-client-4.1.zip desde http://james.apache.org/download.cgi#Apache_Mime4J y agregue apache-mime4j-0.6.1.jar a su proyecto.
2) Descargue httpcomponents-client-4.1-bin.zip desde http://hc.apache.org/downloads.cgi y agregue httpclient-4.1.jar, httpcore-4.1.jar y httpmime-4.1.jar a su proyecto.
3) Utilice el código de ejemplo siguiente.
private DefaultHttpClient mHttpClient;
public ServerCommunication() {
HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
mHttpClient = new DefaultHttpClient(params);
}
public void uploadUserPhoto(File image) {
try {
HttpPost httppost = new HttpPost("some url");
MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addPart("Title", new StringBody("Title"));
multipartEntity.addPart("Nick", new StringBody("Nick"));
multipartEntity.addPart("Email", new StringBody("Email"));
multipartEntity.addPart("Description", new StringBody(Settings.SHARE.TEXT));
multipartEntity.addPart("Image", new FileBody(image));
httppost.setEntity(multipartEntity);
mHttpClient.execute(httppost, new PhotoUploadResponseHandler());
} catch (Exception e) {
Log.e(ServerCommunication.class.getName(), e.getLocalizedMessage(), e);
}
}
private class PhotoUploadResponseHandler implements ResponseHandler<Object> {
@Override
public Object handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
HttpEntity r_entity = response.getEntity();
String responseString = EntityUtils.toString(r_entity);
Log.d("UPLOAD", responseString);
return null;
}
}
Como MultiPartEntity
está en desuso . ¡Así que aquí está la nueva forma de hacerlo! Y solo necesitas httpcore.jar(latest)
descargarlos httpmime.jar(latest)
del sitio de Apache.
try
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(URL);
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
entityBuilder.addTextBody(USER_ID, userId);
entityBuilder.addTextBody(NAME, name);
entityBuilder.addTextBody(TYPE, type);
entityBuilder.addTextBody(COMMENT, comment);
entityBuilder.addTextBody(LATITUDE, String.valueOf(User.Latitude));
entityBuilder.addTextBody(LONGITUDE, String.valueOf(User.Longitude));
if(file != null)
{
entityBuilder.addBinaryBody(IMAGE, file);
}
HttpEntity entity = entityBuilder.build();
post.setEntity(entity);
HttpResponse response = client.execute(post);
HttpEntity httpEntity = response.getEntity();
result = EntityUtils.toString(httpEntity);
Log.v("result", result);
}
catch(Exception e)
{
e.printStackTrace();
}
Más fácil, ligero (32k) y muchas más prestaciones:
Biblioteca de cliente HTTP asíncrono de Android: http://loopj.com/android-async-http/
Implementación:
Cómo enviar un POST “multipart/form-data” en Android con Volley
Prueba esto:
public void SendMultipartFile() {
Log.d(TAG, "UPLOAD: SendMultipartFile");
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost( <url> );
File file = new File("/sdcard/spider.jpg");
Log.d(TAG, "UPLOAD: setting up multipart entity");
MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
Log.d(TAG, "UPLOAD: file length = " + file.length());
Log.d(TAG, "UPLOAD: file exist = " + file.exists());
try {
mpEntity.addPart("datafile", new FileBody(file, "application/octet"));
mpEntity.addPart("id", new StringBody("1"));
} catch (UnsupportedEncodingException e1) {
Log.d(TAG, "UPLOAD: UnsupportedEncodingException");
e1.printStackTrace();
}
httppost.setEntity(mpEntity);
Log.d(TAG, "UPLOAD: executing request: " + httppost.getRequestLine());
Log.d(TAG, "UPLOAD: request: " + httppost.getEntity().getContentType().toString());
HttpResponse response;
try {
Log.d(TAG, "UPLOAD: about to execute");
response = httpclient.execute(httppost);
Log.d(TAG, "UPLOAD: executed");
HttpEntity resEntity = response.getEntity();
Log.d(TAG, "UPLOAD: respose code: " + response.getStatusLine().toString());
if (resEntity != null) {
Log.d(TAG, "UPLOAD: " + EntityUtils.toString(resEntity));
}
if (resEntity != null) {
resEntity.consumeContent();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Recomiendo ampliamente Loopj.
Lo he utilizado con éxito para cargar varios archivos a la vez, incluidos diferentes tipos de mime. Simplemente haz esto:
File myVideo = new File("/path/to/myvideo.mp4");
File myPic = new File("/path/to/mypic.jpg");
RequestParams params = new RequestParams();
try {
params.put("profile_picture", myPic);
params.put("my_video", myVideo);
} catch(FileNotFoundException e) {}
Para archivos grandes o con muchos archivos, es posible que deba aumentar la cantidad de tiempo de espera; de lo contrario, se utilizará el tiempo de espera predeterminado, que podría ser demasiado corto:
client.setTimeout(500000) //make this the appropriate timeout in milliseconds
Consulte estos enlaces para obtener una descripción completa de loopj y cómo usarlo, con diferencia la biblioteca http asíncrona más sencilla que he encontrado:
http://loopj.com/android-async-http/ http://loopj.com/android-async-http/doc/com/loopj/android/http/AsyncHttpClient.html