Загрузите изображение с помощью Google Volley

Мне нужно загрузить изображение из приложения, которое я разрабатываю, на сервер, и я хотел бы знать, как я могу разработать запрос Multipart для загрузки изображения с помощью Google Volley.

благодаря

У меня есть пример для загрузки изображений Google Volley . Взглянуть:

 package net.colaborativa.exampleapp.api; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import com.android.volley.AuthFailureError; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.Response.ErrorListener; import com.android.volley.Response.Listener; import com.android.volley.VolleyLog; import com.android.volley.toolbox.HttpHeaderParser; public class PhotoMultipartRequest<T> extends Request<T> { private static final String FILE_PART_NAME = "file"; private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create(); private final Response.Listener<T> mListener; private final File mImageFile; protected Map<String, String> headers; public PhotoMultipartRequest(String url, ErrorListener errorListener, Listener<T> listener, File imageFile){ super(Method.POST, url, errorListener); mListener = listener; mImageFile = imageFile; buildMultipartEntity(); } @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = super.getHeaders(); if (headers == null || headers.equals(Collections.emptyMap())) { headers = new HashMap<String, String>(); } headers.put("Accept", "application/json"); return headers; } private void buildMultipartEntity(){ mBuilder.addBinaryBody(FILE_PART_NAME, mImageFile, ContentType.create("image/jpeg"), mImageFile.getName()); mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8")); } @Override public String getBodyContentType(){ String contentTypeHeader = mBuilder.build().getContentType().getValue(); return contentTypeHeader; } @Override public byte[] getBody() throws AuthFailureError{ ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { mBuilder.build().writeTo(bos); } catch (IOException e) { VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request."); } return bos.toByteArray(); } @Override protected Response<T> parseNetworkResponse(NetworkResponse response) { T result = null; return Response.success(result, HttpHeaderParser.parseCacheHeaders(response)); } @Override protected void deliverResponse(T response) { mListener.onResponse(response); } } 

И вы можете использовать его следующим образом:

 RequestQueue mQueue = Volley.newRequestQueue(context); PhotoMultipartRequest imageUploadReq = new PhotoMultipartRequest(url, ErrorListener, Listener, imageFile); mQueue.add(imageUploadReq); 

Надеюсь, эти коды вдохновят вас.

Ответ @silverknight работает, однако мне также пришлось добавить следующее в build.gradle для разрешения зависимостей httpcomponents :

 android { ... // have to exclude these otherwise you'll get: // Error:Gradle: Execution failed for task: ... com.android.builder.packaging.DuplicateFileException: ... packagingOptions { exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' exclude 'META-INF/DEPENDENCIES' } } dependencies { ... compile 'com.android.volley:volley:1.0.0' compile('org.apache.httpcomponents:httpmime:4.3.6') { exclude module: 'httpclient' } compile 'org.apache.httpcomponents:httpclient-android:4.3.5.1' } 

ПРИМЕЧАНИЕ. Не используйте org.apache.httpcomponents: httpclient

Вам следует избегать использования стандартной версии 'org.apache.httpcomponents:httpclient:4.5.2'

Если вы пытаетесь:

 android { ... } dependencies { ... compile 'com.android.volley:volley:1.0.0' compile 'org.apache.httpcomponents:httpcore:4.4.4' compile 'org.apache.httpcomponents:httpmime:4.5.2' compile('org.apache.httpcomponents:httpclient:4.5.2' } 

ты получишь:

 java.lang.NoSuchFieldError: No static field INSTANCE of type Lorg/apache/http/message/BasicHeaderValueFormatter; in class Lorg/apache/http/message/BasicHeaderValueFormatter; or its superclasses (declaration of 'org.apache.http.message.BasicHeaderValueFormatter' appears in /system/framework/ext.jar) 

Или что-то похожее на существующие комментарии [1] [2] [3] .

Вы должны скорее использовать порт Android httpclient , так как это ответ SO

ПРИМЕЧАНИЕ. Используйте org.apache.httpcomponents: httpmime: 4.3.6

Вы должны использовать org.apache.httpcomponents:httpmime:4.3.6 , вы не можете перейти выше версии 4.3.x Например, у вас может возникнуть соблазн использовать последнюю версию httpmime , которая на момент написания была бы 4.5.2 :

 android { ... } dependencies { ... compile('org.apache.httpcomponents:httpmime:4.5.2') { exclude module: 'httpclient' } compile 'org.apache.httpcomponents:httpclient-android:4.3.5.1' 

С этой конфигурацией вы получите следующее при вызове PhotoMultipartRequest :

 java.lang.NoSuchMethodError: No static method create(Ljava/lang/String;[Lorg/apache/http/NameValuePair;)Lorg/apache/http/entity/ContentType; in class Lorg/apache/http/entity/ContentType; or its super classes (declaration of 'org.apache.http.entity.ContentType' appears in /xxx/base.apk) 

Я скопировал этот класс из https://gist.github.com/ishitcno1/11394069. Я покажу вам, как вы его используете. Это сработало в моем случае. Скопируйте этот класс. Сделайте необходимые изменения.

 package com.tagero.watchfriend; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import android.util.Log; import com.android.volley.AuthFailureError; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.VolleyLog; public class PhotoMultipartRequest extends Request<String> { static final String TAG = "xxxxxx"; public static final String KEY_PICTURE = "kullanici_resmi"; public static final String KEY_PICTURE_NAME = "kullanici_resmi_dosya_adi"; private HttpEntity mHttpEntity; @SuppressWarnings("rawtypes") private Response.Listener mListener; public PhotoMultipartRequest(String url, String filePath, Response.Listener<String> listener, Response.ErrorListener errorListener) { super(Method.POST, url, errorListener); mListener = listener; mHttpEntity = buildMultipartEntity(filePath); } public PhotoMultipartRequest(String url, File file, Response.Listener<String> listener, Response.ErrorListener errorListener) { super(Method.POST, url, errorListener); mListener = listener; mHttpEntity = buildMultipartEntity(file); } private HttpEntity buildMultipartEntity(String filePath) { File file = new File(filePath); return buildMultipartEntity(file); } private HttpEntity buildMultipartEntity(File file) { MultipartEntityBuilder builder = MultipartEntityBuilder.create(); String fileName = file.getName(); logYazdir("fileName : " + fileName); FileBody fileBody = new FileBody(file); builder.addPart(KEY_PICTURE, fileBody); builder.addTextBody(KEY_PICTURE_NAME, fileName); return builder.build(); } @Override public String getBodyContentType() { return mHttpEntity.getContentType().getValue(); } @Override public byte[] getBody() throws AuthFailureError { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { mHttpEntity.writeTo(bos); } catch (IOException e) { VolleyLog.e("IOException writing to ByteArrayOutputStream"); } return bos.toByteArray(); } @Override protected Response<String> parseNetworkResponse(NetworkResponse response) { return Response.success("Uploaded", getCacheEntry()); } @SuppressWarnings("unchecked") @Override protected void deliverResponse(String response) { mListener.onResponse(response); } private void logYazdir(String str) { if (Sabitler.LOG_KONTROL) { Log.d(TAG, str); } } } 

И вот этот способ загрузки изображения.

  public void resimYukle(final String filePath) { logYazdir("KaydolActivity-uploadImage çağırıldı!"); logYazdir("\nfilePath : " + filePath); RequestQueue rq = Volley.newRequestQueue(this); PhotoMultipartRequest stringRequest = new PhotoMultipartRequest( Sabitler.URL_RESIM_YUKLE, filePath, new Response.Listener<String>() { @Override public void onResponse(String response) { logYazdir("response : " + response); JSONObject veri_json; try { veri_json = new JSONObject(response); int success = 0; String message = ""; try { success = veri_json .getInt(Sabitler.SERVER_RESP_SUCCESS); message = veri_json .getString(Sabitler.SERVER_RESP_MESSAGE); Log.d(TAG, "success : " + success + "\nmessage : " + message); } catch (JSONException e) { e.printStackTrace(); } } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { logYazdir("Error [" + error + "]"); Toast.makeText(getBaseContext(), "Sunucuya bağlanılamadı!", Toast.LENGTH_LONG) .show(); } }) { @Override protected Map<String, String> getParams() { Map<String, String> params = new HashMap<String, String>(); params.put("kullanici_resmi_dosya_adi", ""); return params; } }; rq.add(stringRequest); } 

Как вы собираетесь получить filePath

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { logYazdir("KaydolActivity-onActivityResult çağırıldı!"); if (requestCode == GALERIDEN_RESIM && resultCode == RESULT_OK && data != null) { logYazdir("KaydolActivity-GALERIDEN_RESIM çağırıldı!"); Uri selectedImage = data.getData(); String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); cursor.close(); Bitmap bmp = null; try { bmp = getBitmapFromUri(selectedImage); } catch (IOException e) { e.printStackTrace(); } kullanici_resmi_iview.setImageBitmap(bmp); resimYukle(picturePath); } super.onActivityResult(requestCode, resultCode, data); } 

Наконец, определите это в своей деятельности,

 private int GALERIDEN_RESIM = 2; 

Важная часть, это PHP-код для вашего сервера,

 <?php $target_dir = "resimler/"; $target_file = $target_dir . basename($_FILES["kullanici_resmi"]["name"]); $uploadOk = 1; $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION); // Check if image file is a actual image or fake image if(isset($_POST["kullanici_resmi_dosya_adi"])) { $check = getimagesize($_FILES["kullanici_resmi"]["tmp_name"]); if($check !== false) { $response["success"] = 1; $response["message"] = "File is an image - " . $check["mime"] . "."; echo json_encode($response); $uploadOk = 1; } else { $response["success"] = 0; $response["message"] = "File is not an image."; echo json_encode($response); $uploadOk = 0; } } // Check if file already exists if (file_exists($target_file)) { $response["success"] = 0; $response["message"] = "Sorry, file already exists."; echo json_encode($response); $uploadOk = 0; } // Check file size if ($_FILES["kullanici_resmi"]["size"] > 750000) { $response["success"] = 0; $response["message"] = "Sorry, your file is too large."; echo json_encode($response); $uploadOk = 0; } // Allow certain file formats if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg" && $imageFileType != "gif" ) { $response["success"] = 0; $response["message"] = "Sorry, only JPG, JPEG, PNG & GIF files are allowed."; echo json_encode($response); $uploadOk = 0; } // Check if $uploadOk is set to 0 by an error if ($uploadOk == 0) { $response["success"] = 0; $response["message"] = "Sorry, your file was not uploaded."; echo json_encode($response); // if everything is ok, try to upload file } else { if (move_uploaded_file($_FILES["kullanici_resmi"]["tmp_name"], $target_file)) { $response["success"] = 0; $response["message"] = "The file ". basename( $_FILES["kullanici_resmi"]["name"]). " has been uploaded."; echo json_encode($response); } else { $response["success"] = 0; $response["message"] = "Sorry, there was an error uploading your file."; echo json_encode($response); } } ?> 

Вы должны обязательно отправить свой файл в этот метод,

 private HttpEntity buildMultipartEntity(File file) { MultipartEntityBuilder builder = MultipartEntityBuilder.create(); String fileName = file.getName(); logYazdir("fileName : " + fileName); FileBody fileBody = new FileBody(file); builder.addPart(KEY_PICTURE, fileBody); builder.addTextBody(KEY_PICTURE_NAME, fileName); return builder.build(); } 

И обратите внимание на это,

 public static final String KEY_PICTURE = "kullanici_resmi"; 

kullanici_resmi

Используется в PHP-коде для указания файла изображения. Я так думаю, вы можете отправить любой файл. Извините за мои плохие объяснения, я попытался все объяснить.

Intereting Posts
Android: какой из них использовать для имени пакета? Пакетное имя манифеста или приложение GradleId? Ошибка: ваш проект содержит файлы C ++, но он не использует поддерживаемую встроенную систему сборки Как поместить определенные классы в основной файл DEX? Загрузите все изображения из папки на сервере на локальный Классы против деятельности на Android Передача данных с помощью ультразвука Пустое пространство, когда в Android открывается мягкая клавиатура Ошибка: в проекте используется неподдерживаемая версия подключаемого модуля Android Gradle (0.12.2) Не зажимайте страницы ViewPager Android – проблемы с элементами меню с возможностью проверки Время ожидания в DefaultHttpClient Class Android Android getText из поля EditText Расширение GridLayout Захват звука для анализа и визуализации частот в Android Подключение к пространству имен socket.io с использованием библиотеки socket.io-client.java