Почтовый многопользовательский запрос с Android SDK

Я пытаюсь сделать то, что, как я думал, будет относительно простым: загрузить изображение на сервер с Android SDK. Я нашел много примеров кода:

http://groups.google.com/group/android-developers/browse_thread/thread/f9e17bbaf50c5fc/46145fcacd450e48

http://linklens.blogspot.com/2009/06/android-multipart-upload.html

Но я не работаю для меня. Путаница, с которой я все время сталкиваюсь, – это то, что действительно необходимо для многопрофильного запроса. Каков самый простой способ иметь многостраничную загрузку (с изображением) для Android?

Любая помощь или совет будут очень признательны!

Обновление 29 апреля 2014 года:

Мой ответ уже довольно старый, и я думаю, вы скорее захотите использовать какую-то библиотеку высокого уровня, такую ​​как « Дооснащение» .


Основываясь на этом блоге, я придумал следующее решение: http://blog.tacticalnuclearstrike.com/2010/01/using-multipartentity-in-android-applications/

Вам нужно будет загрузить дополнительные библиотеки, чтобы запустить MultipartEntity !

1) Загрузите httpcomponents-client-4.1.zip из http://james.apache.org/download.cgi#Apache_Mime4J и добавьте apache-mime4j-0.6.1.jar в свой проект.

2) Загрузите httpcomponents-client-4.1-bin.zip из http://hc.apache.org/downloads.cgi и добавьте httpclient-4.1.jar, httpcore-4.1.jar и httpmime-4.1.jar в свой проект.

3) Используйте приведенный ниже примерный код.

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

Поскольку MultiPartEntity устарел . Итак, вот новый способ сделать это! И вам нужны только httpcore.jar(latest) и httpmime.jar(latest) загружающие их с сайта 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(); } 

Вот решение LIGHT WEIGHTED, которое работало для меня без внешнего HTTPCore и таких библиотек. Я столкнулся с проблемой 64K-методов, поэтому не нужно оставлять возможности, чтобы избежать библиотек HTTPCore

 import java.util.List; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; /** * This utility class provides an abstraction layer for sending multipart HTTP * POST requests to a web server. * * @author www.codejava.net */ public class MultipartUtility { private final String boundary; private static final String LINE_FEED = "\r\n"; private HttpURLConnection httpConn; private String charset; private OutputStream outputStream; private PrintWriter writer; /** * This constructor initializes a new HTTP POST request with content type * is set to multipart/form-data * * @param requestURL * @param charset * @throws IOException */ public MultipartUtility(String requestURL, String charset) throws IOException { this.charset = charset; // creates a unique boundary based on time stamp boundary = "===" + System.currentTimeMillis() + "==="; URL url = new URL(requestURL); httpConn = (HttpURLConnection) url.openConnection(); httpConn.setUseCaches(false); httpConn.setDoOutput(true); // indicates POST method httpConn.setDoInput(true); httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); httpConn.setRequestProperty("User-Agent", "CodeJava Agent"); httpConn.setRequestProperty("Test", "Bonjour"); outputStream = httpConn.getOutputStream(); writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), true); } /** * Adds a form field to the request * * @param name field name * @param value field value */ public void addFormField(String name, String value) { writer.append("--" + boundary).append(LINE_FEED); writer.append("Content-Disposition: form-data; name=\"" + name + "\"") .append(LINE_FEED); writer.append("Content-Type: text/plain; charset=" + charset).append( LINE_FEED); writer.append(LINE_FEED); writer.append(value).append(LINE_FEED); writer.flush(); } /** * Adds a upload file section to the request * * @param fieldName name attribute in  * @param uploadFile a File to be uploaded * @throws IOException */ public void addFilePart(String fieldName, File uploadFile) throws IOException { String fileName = uploadFile.getName(); writer.append("--" + boundary).append(LINE_FEED); writer.append( "Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"") .append(LINE_FEED); writer.append( "Content-Type: " + URLConnection.guessContentTypeFromName(fileName)) .append(LINE_FEED); writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED); writer.append(LINE_FEED); writer.flush(); FileInputStream inputStream = new FileInputStream(uploadFile); byte[] buffer = new byte[4096]; int bytesRead = -1; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.flush(); inputStream.close(); writer.append(LINE_FEED); writer.flush(); } /** * Adds a header field to the request. * * @param name - name of the header field * @param value - value of the header field */ public void addHeaderField(String name, String value) { writer.append(name + ": " + value).append(LINE_FEED); writer.flush(); } /** * Completes the request and receives response from the server. * * @return a list of Strings as response in case the server returned * status OK, otherwise an exception is thrown. * @throws IOException */ public List finish() throws IOException { List response = new ArrayList(); writer.append(LINE_FEED).flush(); writer.append("--" + boundary + "--").append(LINE_FEED); writer.close(); // checks server's status code first int status = httpConn.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) { BufferedReader reader = new BufferedReader(new InputStreamReader( httpConn.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { response.add(line); } reader.close(); httpConn.disconnect(); } else { throw new IOException("Server returned non-OK status: " + status); } return response; } } 

ПРИМЕНЕНИЕ

 private void uploadMedia() { try { String charset = "UTF-8"; File uploadFile1 = new File("/sdcard/myvideo.mp4"); String requestURL = Data.BASE_URL+Data.URL_UPLOAD_REACTION_TEST; MultipartUtility multipart = new MultipartUtility(requestURL, charset); // multipart.addHeaderField("User-Agent", "CodeJava"); // multipart.addHeaderField("Test-Header", "Header-Value"); multipart.addFormField("friend_id", "Cool Pictures"); multipart.addFormField("userid", "Java,upload,Spring"); multipart.addFilePart("uploadedfile", uploadFile1); List response = multipart.finish(); Log.v("rht", "SERVER REPLIED:"); for (String line : response) { Log.v("rht", "Line : "+line); } } catch (Exception e) { e.printStackTrace(); } } 

PHP-код для приема загрузки

  

Более легкая, легкая (32k) и еще более высокая производительность:

Android-асинхронная клиентская библиотека Http: http://loopj.com/android-async-http/

Реализация:

Как отправить POST в формате «multipart / form-data» в Android с помощью Volley

Попробуй это:

  public void SendMultipartFile() { Log.d(TAG, "UPLOAD: SendMultipartFile"); DefaultHttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(  ); 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(); } } 

Я очень рекомендую Loopj.

Я успешно использовал его для загрузки нескольких файлов одновременно, включая различные типы mime. Просто сделайте следующее:

 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) {} 

Для больших или многих файлов вам может потребоваться увеличить тайм-аут, иначе используется таймаут по умолчанию, который может быть слишком коротким:

 client.setTimeout(500000) //make this the appropriate timeout in milliseconds 

Пожалуйста, ознакомьтесь с этими ссылками для полного описания loopj и того, как его использовать, на сегодняшний день самая простая асинхронная http-библиотека, с которой я столкнулся:

http://loopj.com/android-async-http/ http://loopj.com/android-async-http/doc/com/loopj/android/http/AsyncHttpClient.html

Удалите всю вашу httpclient, зависимость httpmime и добавьте эту зависимую compile 'commons-httpclient:commons-httpclient:3.1' . Эта зависимость построена в MultipartRequestEntity, так что вы можете легко загрузить один или несколько файлов на сервер

 public class FileUploadUrlConnection extends AsyncTask { private Context context; private String url; private List files; public FileUploadUrlConnection(Context context, String url, List files) { this.context = context; this.url = url; this.files = files; } @Override protected String doInBackground(String... params) { HttpClient client = new HttpClient(); PostMethod post = new PostMethod(url); HttpClientParams connectionParams = new HttpClientParams(); post.setRequestHeader(// Your header goes here ); try { Part[] parts = new Part[files.size()]; for (int i=0; i 

Вы также можете добавить время ожидания запроса и ответа

 client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000); client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000); 

Я могу рекомендовать библиотеку Ion использовать 3 зависимости, и вы можете найти все три файла jar на этих двух сайтах:
https://github.com/koush/ion#jars (ионный и androidasync)

https://code.google.com/p/google-gson/downloads/list (gson)

 try { Ion.with(this, "http://sofru.miximages.com/android/testfile.jpg")) .asString() .setCallback(new FutureCallback() { @Override public void onCompleted(Exception e, String result) { System.out.println(result); }}); } catch(Exception e) { // Do something about exceptions System.out.println("exception: " + e); } 

это запустит async, и обратный вызов будет выполнен в streamе пользовательского интерфейса после получения ответа. Я настоятельно рекомендовал, чтобы вы перешли на https://github.com/koush/ion для дальнейшей информации

Вот простой подход, если вы используете библиотеку AOSP Volley .

Расширьте class Request следующим образом:

 public class MultipartRequest extends Request { private static final String FILE_PART_NAME = "file"; private final Response.Listener mListener; private final Map mFilePart; private final Map mStringPart; MultipartEntityBuilder entity = MultipartEntityBuilder.create(); HttpEntity httpentity; public MultipartRequest(String url, Response.ErrorListener errorListener, Response.Listener listener, Map file, Map mStringPart) { super(Method.POST, url, errorListener); mListener = listener; mFilePart = file; this.mStringPart = mStringPart; entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); buildMultipartEntity(); } public void addStringBody(String param, String value) { mStringPart.put(param, value); } private void buildMultipartEntity() { for (Map.Entry entry : mFilePart.entrySet()) { // entity.addPart(entry.getKey(), new FileBody(entry.getValue(), ContentType.create("image/jpeg"), entry.getKey())); try { entity.addBinaryBody(entry.getKey(), Utils.toByteArray(new FileInputStream(entry.getValue())), ContentType.create("image/jpeg"), entry.getKey() + ".JPG"); } catch (FileNotFoundException e) { e.printStackTrace(); } } for (Map.Entry entry : mStringPart.entrySet()) { if (entry.getKey() != null && entry.getValue() != null) { entity.addTextBody(entry.getKey(), entry.getValue()); } } } @Override public String getBodyContentType() { return httpentity.getContentType().getValue(); } @Override public byte[] getBody() throws AuthFailureError { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { httpentity = entity.build(); httpentity.writeTo(bos); } catch (IOException e) { VolleyLog.e("IOException writing to ByteArrayOutputStream"); } return bos.toByteArray(); } @Override protected Response parseNetworkResponse(NetworkResponse response) { Log.d("Response", new String(response.data)); return Response.success(new String(response.data), getCacheEntry()); } @Override protected void deliverResponse(String response) { mListener.onResponse(response); } } 

Вы можете создать и добавить запрос,

 Map params = new HashMap<>(); params.put("name", name.getText().toString()); params.put("email", email.getText().toString()); params.put("user_id", appPreferences.getInt( Utils.PROPERTY_USER_ID, -1) + ""); params.put("password", password.getText().toString()); params.put("imageName", pictureName); Map files = new HashMap<>(); files.put("photo", new File(Utils.LOCAL_RESOURCE_PATH + pictureName)); MultipartRequest multipartRequest = new MultipartRequest(Utils.BASE_URL + "editprofile/" + appPreferences.getInt(Utils.PROPERTY_USER_ID, -1), new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // TODO Auto-generated method stub Log.d("Error: ", error.toString()); FugaDialog.showErrorDialog(ProfileActivity.this); } }, new Response.Listener() { @Override public void onResponse(String jsonResponse) { JSONObject response = null; try { Log.d("jsonResponse: ", jsonResponse); response = new JSONObject(jsonResponse); } catch (JSONException e) { e.printStackTrace(); } try { if (response != null && response.has("statusmessage") && response.getBoolean("statusmessage")) { updateLocalRecord(); } } catch (JSONException e) { e.printStackTrace(); } FugaDialog.dismiss(); } }, files, params); RequestQueue queue = Volley.newRequestQueue(this); queue.add(multipartRequest); 

Для потомков я не видел упоминаемого охх. Похожие сообщения.

В основном вы создаете тело с помощью MultipartBody.Builder, а затем публикуете его в запросе.

Пример в котлине:

  val body = MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file) ) .addFormDataPart("timestamp", Date().time.toString()) .build() val request = Request.Builder() .url(url) .post(body) .build() httpClient.newCall(request).enqueue(object : okhttp3.Callback { override fun onFailure(call: Call?, e: IOException?) { ... } override fun onResponse(call: Call?, response: Response?) { ... } }) 
 public class Multipart{ private final Map headrs; private String url; private HttpURLConnection con; private OutputStream os; private String delimiter = "--"; private String boundary = "TRR" + Long.toString(System.currentTimeMillis()) + "TRR"; public Multipart (String url, Map headers) { this.url = url; this.headrs = headers; } public void connectForMultipart() throws Exception { con = (HttpURLConnection) (new URL(url)).openConnection(); con.setRequestMethod("POST"); con.setDoInput(true); con.setDoOutput(true); con.setRequestProperty("Connection", "Keep-Alive"); for (Map.Entry entry : headrs.entrySet()) { con.setRequestProperty(entry.getKey(), entry.getValue()); } con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); con.connect(); os = con.getOutputStream(); } public void addFormPart(String paramName, String value) throws Exception { writeParamData(paramName, value); } public void addFilePart(String paramName, String fileName, byte[] data) throws Exception { os.write((delimiter + boundary + "\r\n").getBytes()); os.write(("Content-Disposition: form-data; name=\"" + paramName + "\"; filename=\"" + fileName + "\"\r\n").getBytes()); os.write(("Content-Type: application/octet-stream\r\n").getBytes()); os.write(("Content-Transfer-Encoding: binary\r\n").getBytes()); os.write("\r\n".getBytes()); os.write(data); os.write("\r\n".getBytes()); } public void finishMultipart() throws Exception { os.write((delimiter + boundary + delimiter + "\r\n").getBytes()); } public String getResponse() throws Exception { InputStream is = con.getInputStream(); byte[] b1 = new byte[1024]; StringBuffer buffer = new StringBuffer(); while (is.read(b1) != -1) buffer.append(new String(b1)); con.disconnect(); return buffer.toString(); } private void writeParamData(String paramName, String value) throws Exception { os.write((delimiter + boundary + "\r\n").getBytes()); os.write("Content-Type: text/plain\r\n".getBytes());//;charset=utf-8 os.write(("Content-Disposition: form-data; name=\"" + paramName + "\"\r\n").getBytes()); ; os.write(("\r\n" + value + "\r\n").getBytes()); } } 

Затем позвоните ниже

 Multipart multipart = new Multipart(url__, map); multipart .connectForMultipart(); multipart .addFormPart(entry.getKey(), entry.getValue()); multipart .addFilePart(KeyName, "FileName", imagedata); multipart .finishMultipart(); 
  • Загрузка файла с помощью запроса POST в Node.js
  • Источник впрыска Джерси 2 для многочастных форм
  • Давайте будем гением компьютера.