2017-03-26 8 views
2

사용자가 여러 이미지를 선택하여 서버에 업로드 할 수있는 앱을 만들고 있습니다. PHP를 백엔드로 사용 중이며 retrofit2입니다.Retrofit 2 및 PHP를 백 엔드로 사용하여 하나의 요청에 여러 개의 이미지를 업로드하는 방법?

나는 stackoverflow에서 모든 대답을 시도했지만 여전히 해결하지 못했습니다. 전송 파일

Retrofit builder = new Retrofit.Builder().baseUrl(ROOT_URL).addConverterFactory(GsonConverterFactory.create()).build(); 
     FileUploadService fileUploadService = builder.create(FileUploadService.class); 
     Call<Response> call = fileUploadService.uploadImages(list) 
     for (Uri fileUri : path) { 
      MultipartBody.Part fileBody = prepareFilePart("files", fileUri); 
      images.add(fileBody); 
     } 


     Call<Response> call=fileUploadService.uploadImages(images); 

     call.enqueue(new Callback<Response>() { 
      @Override 
      public void onResponse(Call<Response> call, Response<Response> response) { 
       Log.e("MainActivity",response.body().toString()); 
       progressDialog.show(); 
      } 

      @Override 
      public void onFailure(Call<Response> call, Throwable t) { 
       Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); 
       Log.e("MainActivity",t.getLocalizedMessage()); 
       progressDialog.dismiss(); 
      } 
     }); 

    } 

에 대한

@Multipart 
@POST("URL/uploadImages.php") 
Call<Response> uploaImages(
     @Part List< MultipartBody.Part> files); 

코드는 여기에 내 PHP 코드입니다.

if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST"){ 
// Loop $_FILES to exeicute all files 
foreach ($_FILES['files']['name'] as $f => $name) {  
    if ($_FILES['files']['error'][$f] == 4) { 
     continue; // Skip file if any error found 
    }   
    if ($_FILES['files']['error'][$f] == 0) {    
     if ($_FILES['files']['size'][$f] > $max_file_size) { 
      $message[] = "$name is too large!."; 
      continue; // Skip large files 
     } 
     elseif(! in_array(pathinfo($name, PATHINFO_EXTENSION), $valid_formats)){ 
      $message[] = "$name is not a valid format"; 
      continue; // Skip invalid file formats 
     } 
     else{ // No error found! Move uploaded files 
      if(move_uploaded_file($_FILES["files"]["tmp_name"][$f], $path.$name)) 
      $count++; // Number of successfully uploaded file 
     } 
    } 
} 

}

해결 방법 :

나는 "file[]""file"에서 MultipartBodt.Part의 이름을 변경 .and $_FILES['file']에서 그들을받을 수 있습니다 .. 난 문제를 알아 냈 ... 전통적인 양식으로하는 것과 동일합니다 ... 콘텐츠를 양식 데이터로 보내므로 내 preparFfile() 메서드를 수정하십시오.

+0

시도 이 자습서 https://futurestud.io/tutorials/retrofit-2-how-to-upload-multiple-files-to-server –

답변

1

검색 후 묻는다면 여기에 전체 테스트를 거친 자체 포함 된 솔루션이 있습니다.

1. 서비스 인터페이스를 생성하십시오.

public interface FileUploadService { 

@Multipart 
@POST("YOUR_URL/image_uploader.php") 
Call<Response> uploadImages(@Part List<MultipartBody.Part> images); 
     } 

및 Response.java

public class Response{ 
    private String error; 
    private String message; 
    //getters and setters 

}


난 후, onActivityResult() 방법에서 URI의리스트를 전달 2- uploadImages 방법 I 실제 파일 경로를 FileUtiles의 도움으로 "클래스에 대한 링크가 주석"

//code to upload 
//the path is returned from the gallery 
void uploadImages(List<Uri> paths) { 
    List<MultipartBody.Part> list = new ArrayList<>(); 
    int i = 0; 
    for (Uri uri : paths) { 
     String fileName = FileUtils.getFile(this, uri).getName(); 
     //very important files[] 
     MultipartBody.Part imageRequest = prepareFilePart("file[]", uri); 
     list.add(imageRequest); 
    } 


    Retrofit builder = new Retrofit.Builder().baseUrl(ROOT_URL).addConverterFactory(GsonConverterFactory.create()).build(); 
      FileUploadService fileUploadService = builder.create(FileUploadService.class); 
    Call<Response> call = fileUploadService.uploadImages(list); 
    call.enqueue(new Callback<Response>() { 
     @Override 
     public void onResponse(Call<Response> call, Response<Response> response) { 
      Log.e("main", "the message is ----> " + response.body().getMessage()); 
      Log.e("main", "the error is ----> " + response.body().getError()); 

     } 

     @Override 
     public void onFailure(Call<Response> call, Throwable throwable) { 
      Log.e("main", "on error is called and the error is ----> " + throwable.getMessage()); 

     } 
    }); 


} 

및 도우미 방법은

@NonNull 
private MultipartBody.Part prepareFilePart(String partName, Uri fileUri) { 
    // https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java 
    // use the FileUtils to get the actual file by uri 
    File file = FileUtils.getFile(this, fileUri); 
      //compress the image using Compressor lib 
      Timber.d("size of image before compression --> " + file.getTotalSpace()); 
      compressedImageFile = new Compressor(this).compressToFile(file); 
      Timber.d("size of image after compression --> " + compressedImageFile.getTotalSpace()); 
    // create RequestBody instance from file 
    RequestBody requestFile = 
      RequestBody.create(
        MediaType.parse(getContentResolver().getType(fileUri)), 
        compressedImageFile); 

    // MultipartBody.Part is used to send also the actual file name 
    return MultipartBody.Part.createFormData(partName, file.getName(), requestFile); 
} 

3 내 PHP 코드 image_uploader.php 이상 사용 :

<?php 
$file_path = "upload/"; 
$full_path="http://bishoy.esy.es/retrofit/".$file_path; 
$img = $_FILES['file']; 
$response['message'] = "names : "; 
if(!empty($img)){ 

    for($i=0;$i<count($_FILES['file']['tmp_name']);$i++){ 

    $response['error'] = false; 
    $response['message'] = "number of files recieved is = ".count($_FILES['file']['name']); 
    if(move_uploaded_file($_FILES['file']['tmp_name'][$i],"upload/".$_FILES['file']['name'][$i])){ 
      $response['error'] = false; 
    $response['message'] = $response['message']. "moved sucessfully :: "; 

    }else{ 
    $response['error'] = true; 
    $response['message'] = $response['message'] ."cant move :::" .$file_path ; 

    } 
    } 
    } 
else{ 
    $response['error'] = true; 
    $response['message'] = "no files recieved !"; 
} 

echo json_encode($response); 
?> 
+0

코드가 정상적으로 작동하지만 이전에 이미지를 압축해야합니다. 로드 중입니다 ... 어떤 아이디어로주세요? –

+0

도움이 되니 기쁩니다. 나는 보통 Image compressor 라이브러리를 사용한다. 사용하기 쉽고 효율적입니다. –

+0

좀 더 설명해 주시겠습니까? 정확히 압축 할 위치와 압축 후 최종 파일 형식은 무엇입니까 –