2015-04-03 15 views
8

Będę musiał przesłać obraz z aplikacji, którą rozwijam, do serwera i chciałbym wiedzieć, w jaki sposób mogę utworzyć żądanie Multipart, aby załadować obraz za pomocą Google Volley.Załaduj obraz za pomocą Google Volley

Dzięki

Odpowiedz

12

Mam przykład do przesyłania obrazów przez Google Volley. Spójrz:

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

I można go używać tak:

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

Mam nadzieję, że te kody będą cię zainspirować.

+0

Dzięki za odpowiedź. Zaimportowałem twój kod do mojej aplikacji, ale dostaję błąd dla następujących bibliotek: 'import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; ' Jakie biblioteki należy zaimportować? Dzięki – BigNick

+0

wejdź na oficjalną stronę 'Apache', a następnie pobierz plik' httpclient_x.x.x.zip', a następnie zdekompresuj ten plik zip, aby pobrać plik httpclient_x.x.x.jar, a następnie dodaj go do 'libs' swojego projektu. – SilentKnight

+0

Czy jesteś dobry ze swoimi kodami? – SilentKnight

4

@silverknight „s prace odpowiedź, jednak miałem również dodać następujące w build.gradle rozwiązać httpcomponents zależności:

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' 
} 

UWAGA: Nie używaj org.apache.httpcomponents: httpclient

należy unikać stosując standardową wersję 'org.apache.httpcomponents:httpclient:4.5.2'

Jeśli spróbujesz:

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' 
} 

dostaniesz:

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) 

lub coś podobnego do istniejących komentarzy [1][2][3].

Należy raczej używać Androida portu httpclient, jak za this SO answer

UWAGA: Używaj org.apache.httpcomponents: httpmime: 4.3.6

Masz używać org.apache.httpcomponents:httpmime:4.3.6, ty nie może przekroczyć wersji 4.3.x. Na przykład, może być skłonny do korzystania z najnowszej wersji httpmime, która w chwili pisania jest 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' 

z tej konfiguracji, otrzymasz następujące po wywołaniu 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) 
1

Skopiowałem tę klasę z https://gist.github.com/ishitcno1/11394069 Pokażę ci, jak z niej korzystasz. Działało w moim przypadku. Skopiuj tę klasę. Dokonaj niezbędnych zmian.

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

Tutaj można przesłać obraz.

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

How are you gonna get 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); 

    } 

Wreszcie określić to w swojej działalności,

private int GALERIDEN_RESIM = 2; 

Ważna część, to jest kod PHP na serwerze,

<?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); 
    } 
} 
?> 

Należy upewnić się, aby wysłać plik w tej metodzie

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(); 
} 

i zwracać uwagę na to,

public static final String KEY_PICTURE = "kullanici_resmi"; 

kullanici_resmi

jest stosowany w kodzie PHP, aby wskazać plik obrazu. Zgaduję, że w ten sposób możesz wysłać dowolny plik. Przepraszam za moje słabe wyjaśnienia, starałem się wszystko wyjaśnić.

Powiązane problemy