簡體   English   中英

如何使用Retrofit2將照片上傳到服務器

[英]How to Upload a photo using Retrofit2 to server

有誰知道使用改造2將映像上傳到服務器的方法。大多數在線解決方案都使用改造1。

謝謝我嘗試了這個:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    //GALLERY
    if ((isGalleryCalled(requestCode) && resultCode == RESULT_OK)) {
        Log.w(TAG, "onActivityResult > isGalleryCalled > data.getData(): " + data.getData());
        Uri originalUri = data.getData();
        if (originalUri != null) {
            mImageUri = originalUri;
        }
    }
    //CAPTURE
    else if ((isCaptureCalled(requestCode)) && resultCode == RESULT_OK) {
        Log.w(TAG, "onActivityResult > isCaptureCalled > data.getData(): " + data.getData());
        Uri originalUri = data.getData();
        if (originalUri != null) {
            mImageUri = originalUri;

        }
    }



private void prepareImage(String mImageUri ) {

    File file = new File(mImageUri );

    mRequestBodyImage =  RequestBody.create(MediaType.parse("multipart/form-data"), file);

    isUploadImage = true;
    Log.d(TAG, "isUploadImage: " + isUploadImage + " | \nuri: " + uri + " | \nfile getPath: " + file.getPath());

}//end sendReport




    Call<DefaultResponse> call = RestClient.get().uploadImage(file);

....


    @Multipart
    @POST(Constant.API_UPLOADIMAGE)
    Call<DefaultResponse> uploadImage(
            //Upload File
            @Part("myfile\"; filename=\"image.png\" ") RequestBody file
    ); 

我得到這些錯誤:

sendErrorReport - file: com.squareup.okhttp.RequestBody$3@2f83a2f9
stat failed: ENOENT (No such file or directory) : content:/media/external/images/media/2720
java.io.FileNotFoundException: content:/media/external/images/media/2720: open failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:456)
at java.io.FileInputStream.<init>(FileInputStream.java:76)
at okio.Okio.source(Okio.java:163)
at com.squareup.okhttp.RequestBody$3.writeTo(RequestBody.java:117)
at com.squareup.okhttp.MultipartBuilder$MultipartRequestBody.writeOrCountBytes(MultipartBuilder.java:277)
at com.squareup.okhttp.MultipartBuilder$MultipartRequestBody.writeTo(MultipartBuilder.java:297)

[UPDATE]

更新@Anton Shkurenko反饋的代碼

圖像路徑開始處理

UtilApiHelp.getPath:/storage/emulated/0/DCIM/Camera/20151210_124246.jpg

private void prepareImage(String uri) {


    File file = new File(uri);

    mRequestBodyImage =  RequestBody.create(MediaType.parse("multipart/form-data"), file);

    isUploadImage = true;
    Log.d(TAG, "prepareImage isUploadImage: " + isUploadImage + " | \nuri: " + uri + " | \nfile getPath: " + file.getPath());


    sendErrorReport("", mRequestBodyImage);// test1
uploadImage(file.getPath());//test 2
}//end sendReport



//API Send Image test 1 - FAILED
private void sendErrorReport(String s, String msg, RequestBody file){

    Log.e(TAG, "sendErrorReport - file: " + file.toString());

    String user_id = Preferences.getInstance().getUserId();

    Call<DefaultResponse> call = RestClient.get().sendErrorReport(s, file);
    call.enqueue(new Callback<DefaultResponse>() {
        @Override
        public void onResponse(Response<DefaultResponse> response, Retrofit retrofit) {

            Log.w("sendErrorLog > onResponse => ", String.valueOf(response.isSuccess()));

        }

        @Override
        public void onFailure(Throwable t) {
            t.printStackTrace();
        }
    });
}

錯誤:com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:預期為BEGIN_OBJECT,但位於第3行第2列路徑$

//Upload test 2 -> not working
private void uploadImage(final String path) {


    final RequestBody photo =
            UtilApiHelp.getImageBodyBuilder(new HashMap<String, String>() {{
                put("image", path);
            }})
                    //.addFormDataPart("here_you_can_add_another_form_data", anotherFormData)
                    .build();


    Call<DefaultResponse> call = RestClient.get().sendErrorReport(photo);
    call.enqueue(new Callback<DefaultResponse>() {
        @Override
        public void onResponse(Response<DefaultResponse> response, Retrofit retrofit) {

        }

        @Override
        public void onFailure(Throwable t) {
            t.printStackTrace();
        }
    });
}

錯誤:原因:java.lang.IllegalArgumentException:@Body參數不能與表單或多部分編碼一起使用。 (參數#1)用於方法APIService.sendErrorReport

用了這個電話

@FormUrlEncoded
@POST(Constant.API_POST_error_log)
Call<DefaultResponse> sendErrorReport(@Body RequestBody multipartBody);

[UPDATE]
自從您更新了問題。 您只是無法從給定的Uri中找到文件。 使用我的代碼中的util函數getPath來獲取圖像路徑,希望getPath起作用。

[舊解決方案]
我有這個工作的解決方案:

實用功能:

public static RequestBody getImageBody(Map<String, String> map) {
  return getImageBodyBuilder(map).build();
}

public static MultipartBuilder getImageBodyBuilder(Map<String, String> map) {

  MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM);
  for (String key : map.keySet()) {
    final String filePlace = map.get(key);
    Log.d(TAG, "File place: " + filePlace);
    final String[] args = filePlace.split("\\.");
    final String fileExt = args[args.length - 1];
    Log.d(TAG, "File extension: " + fileExt);

    // Old solution, porting from one project to another
    // It's about problems with jpeg
    builder.addPart(Headers.of("Content-Disposition",
        "form-data; name=\"" + key + "\"; filename=\"" + filePlace + "\""), RequestBody.create(
        MediaType.parse("image/" + fileExt.toLowerCase().replace("jpg", "jpeg")),
        new File(map.get(key))));
  }

  return builder;
}

public static String getPath(Context ctx, Uri uri) {
  String[] projection = { MediaStore.Images.Media.DATA };
  Cursor cursor = ctx.getContentResolver().query(uri, projection, null, null, null);
  if (cursor == null) return null;
  int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
  cursor.moveToFirst();
  String s = cursor.getString(columnIndex);
  cursor.close();
  return s;
}

照片上傳。

final RequestBody photo =
    ImageUploadUtils.getImageBodyBuilder(new HashMap<String, String>() {{
                put("photo", imagePathWhateverYouWant);
              }})
              .addFormDataPart("here_you_can_add_another_form_data", anotherFormData).build();

 mApiService.attachPhoto("Token " + getToken(), photo);

ApiService.java(接口):

// I user here RxJava, but I think it's easy to use Calls here.
@POST("deliveries/photos") Observable<Map<String, String>> attachPhoto(
     @Header("Authorization") String token, 
     @Body RequestBody multipartBody);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM