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.
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.
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.
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.
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.';
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With