Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i upload multi file using retrofit

How can i upload multi file using retrofit,

i tried to upload file using this code :

ApiService:

@Multipart
@POST("uploadData.php")
Call<ServerResponse> uploadFile(@Part MultipartBody.Part file,
                                @Part("name") RequestBody name,
                                @Part MultipartBody.Part img,
                                @Part("imgname") RequestBody imgname);

and the upload method:

private void uploadFile() {
    File file = new File(Environment.getExternalStorageDirectory() + "/Download/audio2.wav");
    File file2 = new File(Environment.getExternalStorageDirectory() + "/Download/Salty.png");

    RequestBody mFile = RequestBody.create(MediaType.parse("audio/*"), file);
    MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", file.getName(), mFile);
    RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), file.getName());

    RequestBody mFile2 = RequestBody.create(MediaType.parse("image/*"), file2);
    MultipartBody.Part fileToUpload2 = MultipartBody.Part.createFormData("file", file2.getName(), mFile2);
    RequestBody filename2 = RequestBody.create(MediaType.parse("text/plain"), file2.getName());

    ApiService uploadImage = ApiClient.getClient().create(ApiService.class);
    Call<ServerResponse> fileUpload = uploadImage.uploadFile(fileToUpload, filename, fileToUpload2, filename2);
    fileUpload.enqueue(new Callback<ServerResponse>() {
            @Override
            public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
                Toast.makeText(MainActivity.this, "Success " + response.message(), Toast.LENGTH_LONG).show();
                Toast.makeText(MainActivity.this, "Success " + response.body().toString(), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFailure(Call<ServerResponse> call, Throwable t) {
                Log.d("TAG", "Error " + t.getMessage());
            }
    });
}

and php code:

$result = array("success" => $_FILES["file"]["name"]);
$file_path = basename($_FILES['file']['name']);

$imgResult = array("success" => $_FILES["img"]["imgname"]);
$img_path = basename($_FILES['img']['imgname']);


if (move_uploaded_file($_FILES['img']['tmp_name2'], "$img_path") or
        move_uploaded_file($_FILES['file']['tmp_name'], "$file_path")) {
    $result = array("success" => "File successfully uploaded");
} else {
    $result = array("success" => "error uploading file");
}

echo json_encode($result, JSON_PRETTY_PRINT);

this code works only for one file and i don't know the reason,

any help, Thanks in advance.

like image 997
Mohamed Salama Avatar asked Apr 05 '18 11:04

Mohamed Salama


People also ask

How do I post multiple pictures on retrofit?

The solution for this problem is to pass a List or Array of MultipartBody. Part objects. Retrofit and OkHttp will then build an appropriate multipart request with all files. Java arrays or lists allow you to freely add files as required.

Can you upload multiple files at once?

Answer: Yes, dragging and dropping multiple files into the Documents area or using the New > Upload Files options will allow you to select more than one file at a time to be uploaded.

How do I post multiple files?

Windows – in Files Explorer, select multiple files > right-click > Send to > Compressed (ZIP) folder. macOS – in Finder, select multiple files > Ctrl +select or right-click > Compress n items.


2 Answers

You have to change code as to upload for multiple file in single request using retrofit as below.

Create a function which creates MultiPartBody.Part and will get its type extenstion automatically.

public static MultipartBody.Part prepareFilePart(String partName, String fileUri) {
    File file = new File(fileUri);
    String mimeType= URLConnection.guessContentTypeFromName(file.getName());
    Log.e("mimeType",mimeType);
    //create RequestBody instance from file
    RequestBody requestFile = RequestBody.create(MediaType.parse(mimeType), file);
    //MultipartBody.Part is used to send also the actual file name
    return MultipartBody.Part.createFormData(partName, file.getName(), requestFile);
}

Now in your code, to upload multiple file, create ArrayList<MultiPartBody.Part> as below.

public void uploadFile(){
    ArrayList<MultiPartBody.Part> files = new ArrayList<MultiPartBody.Part>();

    for(int i=0; i < selectedFiles.size; i++){
        files.add(prepareFilePart("file_"+(i+1), selectedFiles.get(i)));
        //Where selectedFiles is selected file URI list
    }

    RequestBody totalFiles = RequestBody.create(MediaType.parse("text/plain"), files.size);

    ApiService uploadImage = ApiClient.getClient().create(ApiService.class);
    Call<ServerResponse> fileUpload = uploadImage.uploadFile(files,totalFiles);
    fileUpload.enqueue(...);

}

and in your ApiService, make a change as

@Multipart
@POST("uploadData.php")
Call<ServerResponse> uploadFile(@Part ArrayLisy<MultipartBody.Part> files, @Part("totalFiles") RequestBody totalFiles);

and in your PHP file make a code change as

$totalFiles = $_REQUEST['totalFiles'];
$successUpload = 0;

for($i=1; $i <= $totalFiles; $i++){
    $fileName = 'file_'.$i;
    if(move_uploaded_file($_FILES[$fileName]['tmp_name'],"Valid_file_path"){
        $successUpload += 1;
    }
}

echo $successUpload.' Files uploaded successfully.';
like image 139
Chintak Patel Avatar answered Sep 20 '22 07:09

Chintak Patel


No Need to pass your filenames from Android, after you receive a file then get that filename here itself(in PHP Code)

@Multipart
@POST("uploadData.php")
Call<ServerResponse> uploadFile(@Part MultipartBody.Part file,
                                @Part MultipartBody.Part img);

File Upload code in Java

MultipartBody.Part audioFile= null;
        try {
            File file = new File(Environment.getExternalStorageDirectory() + "/Download/audio2.wav");
            if file != null) {                
                RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"),
                        file);
                audioFile = MultipartBody.Part.createFormData("AudioFile", file.getName(), requestFile);
            }
        }
        catch (Exception ex)
        {
            Log.d("UploadStatus", "Multipart Audio as exception occurs");
        }

MultipartBody.Part imageFile = null;
        try {
            File file = new File(Environment.getExternalStorageDirectory() + "/Download/Salty.png");
            if file != null) {                
                RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"),
                        file);
                imageFile = MultipartBody.Part.createFormData("ImageFile", file.getName(), requestFile);
            }
        }
        catch (Exception ex)
        {
            Log.d("UploadStatus", "Multipart Image as exception occurs");
        }


ApiService uploadImage = ApiClient.getClient().create(ApiService.class);
    Call<ServerResponse> fileUpload = uploadImage.uploadFile(audioFile, imageFile);
    fileUpload.enqueue(new Callback<ServerResponse>() {
            @Override
            public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
                Toast.makeText(MainActivity.this, "Success " + response.message(), Toast.LENGTH_LONG).show();
                Toast.makeText(MainActivity.this, "Success " + response.body().toString(), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFailure(Call<ServerResponse> call, Throwable t) {
                Log.d("TAG", "Error " + t.getMessage());
            }
    });

in your PHP Code

access that two files like

file 1    ==>   $_FILES["AudioFile"]["name"]

file 1    ==>   $_FILES["ImageFile"]["name"]

then get your file names here...

You have to avoid the facing setLenient error on your retrofit Builder

Gson gson = new GsonBuilder()
        .setLenient()
        .create();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .client(client)
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build(); 

Hope this will help you...

like image 39
Raja Avatar answered Sep 17 '22 07:09

Raja