onPostExecute in AsyncTask inside Retrofit is fired too early - android

I'm trying to upload multiple images to the server and sending them one by one through Asynctask. Once the image is uploaded, I save the url to a local list and send it for processing in onPostExecute. But, I'm having problems since the onPostExecute is firing too early and doInBackground only returns a null list.
Passing the URIs to the Asynctask
new UploadImages().execute(arrayUri);
My Asynctask
private class UploadImages extends AsyncTask<Uri,Void,List<String>>{
#Override
protected List<String> doInBackground(Uri... params) {
final ArrayList<String> urlList = new ArrayList<>();
for(Uri uri : params) {
File file = new File(uri.getPath());
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestBody);
RequestBody folderName = RequestBody.create(MediaType.parse("text/plain"), folder);
ApiEndpointInterface apiEndpointInterface = RetrofitManager.getApiInterface();
Call<FileInfo> call4File = apiEndpointInterface.postFile(body, folderName);
call4File.enqueue(new ApiCallback<FileInfo>() {
#Override
protected void do4Failure(Throwable t) {
Log.d(TAG, t.toString());
snackbar = Snackbar.make(newIncidentLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
snackbar.show();
}
#Override
protected void do4PositiveResponse(Response<FileInfo> response) {
FileInfo fileDetails = response.body();
urlList.add(fileDetails.getImage());
Log.d(TAG, "Uploaded Image");
}
#Override
protected void do4NegativeResponse(Response<FileInfo> response) {
String bodyMsg = "";
try {
bodyMsg = new String(response.errorBody().bytes());
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, bodyMsg);
snackbar = Snackbar.make(newIncidentLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
snackbar.show();
}
});
}
return urlList;
}
#Override
protected void onPostExecute(List<String> urlList) {
super.onPostExecute(urlList);
//Post Incident
setProgressMessage("Posting incident...");
//other code here
}
}
I've tried adding a thread.sleep but the outcomes are never the same. Sometimes I get a list in return, other times nothing happens.
I'm not sure why this is happening. I hope you can help me. Thanks.

In android, retrofit calls are made in a background thread by default. You shouldn't/don't need to use AsyncTask.
You can write the code for onPostExecute inside the method onResponse (or in your case do4PositiveResponse and do4NegativeResponse) of your retrofit callback.

There are two types of calls synchronous and asynchronous. You are using enqueue which is asynchronous so u dont need to use async task. Just remove async task from your code and use remaining of your code will do the job so instead of whole code above use following:
ArrayList<String> urlList = new ArrayList<>();
for(Uri uri : params) {
File file = new File(uri.getPath());
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestBody);
RequestBody folderName = RequestBody.create(MediaType.parse("text/plain"), folder);
ApiEndpointInterface apiEndpointInterface = RetrofitManager.getApiInterface();
Call<FileInfo> call4File = apiEndpointInterface.postFile(body, folderName);
call4File.enqueue(new ApiCallback<FileInfo>() {
#Override
protected void do4Failure(Throwable t) {
Log.d(TAG, t.toString());
snackbar = Snackbar.make(newIncidentLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
snackbar.show();
}
#Override
protected void do4PositiveResponse(Response<FileInfo> response) {
FileInfo fileDetails = response.body();
urlList.add(fileDetails.getImage());
Log.d(TAG, "Uploaded Image");
}
#Override
protected void do4NegativeResponse(Response<FileInfo> response) {
String bodyMsg = "";
try {
bodyMsg = new String(response.errorBody().bytes());
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, bodyMsg);
snackbar = Snackbar.make(newIncidentLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
snackbar.show();
}
});
}
After that what you are doing in onPostExecute do it after the completion of for loop.

Related

Not able to upload image file on server using retrofit

My file picked from gallery and set to imageview but after click on upload button not able upload my file on server
I am using local host,my server side code is correct because image is uploading via postman
File file = new File(mediaPath);
// parsing media type file
RequestBody requestBody1 = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part fileToUpload1 = MultipartBody.Part.createFormData("input_img", file.getName(), requestBody1);
ServiceApi call = ClientApi.getData().create(ServiceApi.class);
Call<ResponseData> data = call.update(fileToUpload1);
data.enqueue(new Callback<ResponseData>()
{
#Override
public void onResponse(Call<ResponseData> call, Response<ResponseData> response)
{
ResponseData data = response.body();
if(data.getStatus().equals("true"))
{
Toast.makeText(getApplicationContext(), "yes",Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(), "no",Toast.LENGTH_SHORT).show();
}
// Log.d("data",data.getUpdateUserData().toString());
}
#Override
public void onFailure(Call<ResponseData> call, Throwable t)
{
Toast.makeText(getApplicationContext(), "Please check once",Toast.LENGTH_SHORT).show();
}
});

Bad request while sending multpart image through retrofit 2.1.0

private void saveImageToServer(final String savedpath) {
showLoader();
NetworkUtil.checkInternetConnection(DetailActiveSRActivity.this, new NetworkUtil.NetworkStatusListener() {
#Override
public void onNetworkAvailable() {
File file = new File(savedpath);
// RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), savedpath);
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
Log.e(TAG, "onNetworkAvailable: requestFIle " + savedpath+"\n"+" file "+file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
Log.e(TAG, "onNetworkAvailable: body " + body);
RequestBody reqUserId = RequestBody.create(MediaType.parse("text/plain"), userId);
//RequestBody reqImageType =RequestBody.create(MediaType.parse("text/plain"), "1");
Call<SaveImageResponseModel> responseCall = mService.saveImages(body, reqUserId);
responseCall.enqueue(new Callback<SaveImageResponseModel>() {
#Override
public void onResponse(Call<SaveImageResponseModel> call, retrofit2.Response<SaveImageResponseModel> response) {
hideLoader();
if (response != null) {
SaveImageResponseModel apiResponse = response.body();
if (apiResponse != null && apiResponse.getStatus()) {
Log.e(TAG, "onRequestSuccess: " + apiResponse);
} else {
Toast.makeText(DetailActiveSRActivity.this, getString(R.string.noDataError), Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(DetailActiveSRActivity.this, getString(R.string.noDataError), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<SaveImageResponseModel> call, Throwable t) {
hideLoader();
}
});
}
#Override
public void onNetworkNotAvailable() {
Toast.makeText(DetailActiveSRActivity.this, getString(R.string.noNetworkMessage), Toast.LENGTH_SHORT).show();
hideLoader();
}
});
}
#Headers({
"authkey: ABCD#123"
})
#Multipart
#POST(UrlUtils.POST_IMAGES)
Call<SaveImageResponseModel> saveImages(#Part MultipartBody.Part file, #Part("userId") RequestBody userId);
First of all, no description, please add a little bit more.
Second:
show what is the content of mService.saveImages(body, reqUserId);
is the HTTP call of POST type?
is the endpoint really working? You should for example try to make call through Postman and you'll see, if it is going through

android - download file with retrofit 2.0

I am using retrofit 2.0 for download a file.the problem is enqueue method not called. there is no error and no catch. nothing happen, where is my mistake?
this is my interface:
public interface ApiService {
#GET("uploads/{file_name}")
Call<ServerResponse> downloadFile(#Path("file_name") String fileName);
}
and this is my downloading code :
private void downloadFile() {
progressDialog.show();
// Map is used to multipart the file using okhttp3.RequestBody
File file = new File(mediaPath);
// Parsing any Media type file
RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file);
ApiService getResponse = ApiClient.getClient().create(ApiService.class);
Call<ServerResponse> call = getResponse.downloadFile(file.getName());
call.enqueue(new Callback<ServerResponse>() {
#Override
public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
ServerResponse serverResponse = response.body();
if (serverResponse != null) {
if (serverResponse.getSuccess()) {
Toast.makeText(getApplicationContext(), serverResponse.getMessage(),Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), serverResponse.getMessage(),Toast.LENGTH_SHORT).show();
}
} else {
assert serverResponse != null;
Log.v("Response", serverResponse.toString());
}
progressDialog.dismiss();
}
#Override
public void onFailure(Call<ServerResponse> call, Throwable t) {
}
});
}
Probably, you are referring that the method "enqueue()" is called, but it's not the onResponse one.
Please wait some time (a minute is fine) and make sure that onResponse nor onFailure are called.
If you want more info, you can use the HTTP logging interceptor
#POST("uploads/{file_name}")
Observable<Document> getDocumentsList(#Path("file_name") String fileName);
and the code webservice call should be
Observable<Document> listObservable = mApiService.getDocumentsList(path);
subscribe(listObservable, new Consumer<Document>() {
#Override
public void accept(Document resourceDtos) throws Exception {
fillDocs(resourceDtos.getData());
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable throwable) throws Exception {
fillDocs(throwable.getMessage());
}
});

My ProgressDialog is Not Disappearing

I am working on a project in android to upload a file to server using file chooser But there is a problem, when i am Uploading more than 500 kB file. The file is uploaded but My Progress Dialog is not disappearing and if i uploaded file 100 KB it's uploaded to server and i got a message file uploaded successfully. But I'm not able to get server response if i uploaded more than 500 kB file. Please Help me. Thank You.
It's my UploadFile() Methods
private void uploadFile() {
dialog = ProgressDialog.show(getActivity(), "", "Uploading File...", true);
// Map is used to multipart the file using okhttp3.RequestBody
Map<String, RequestBody> map = new HashMap<>();
long maxLength = 10000000;
File file = new File(selectedFilePath);
if(file.length() > maxLength){
Toast.makeText(getActivity(), "can't upload file if size more than 10mb", Toast.LENGTH_LONG).show();
dialog.dismiss();
}else {
String name = tv_name.getText().toString();
String email = tv_email.getText().toString();
// Parsing any Media type file
RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file);
RequestBody requestBody1 = RequestBody.create(MediaType.parse("text/plain"), name);
RequestBody requestBody2 = RequestBody.create(MediaType.parse("text/plain"), email);
map.put("file\"; filename=\"" + selectedFilePath + "\"", requestBody);
map.put("name\"; username=\"" + name + "\"", requestBody1);
map.put("email\"; email=\"" + email + "\"", requestBody2);
ApiConfig getResponse = AppConfig.getRetrofit().create(ApiConfig.class);
Call<ServerResponse> call = getResponse.upload("token", map);
call.enqueue(new Callback<ServerResponse>() {
#Override
public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
ServerResponse serverResponse = response.body();
if (serverResponse != null) {
if (serverResponse.getSuccess()) {
Toast.makeText(getActivity(), serverResponse.getMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(), serverResponse.getMessage(), Toast.LENGTH_SHORT).show();
}
} else {
// Log.v("Response", serverResponse.toString());
}
dialog.dismiss();
goToProfile();
}
#Override
public void onFailure(Call<ServerResponse> call, Throwable t) {
}
});
}
}
When you get response you have to dismiss your progress dialog.
Example:
if (cls_networlconnection.isOnline())
{
progressdialog = ProgressDialog.showdialog(this,"Loading");
APICall();
}
else {
Toast.makeText(getApplicationContext(),UserToastMessage.NETWORKCONNECTION, Toast.LENGTH_LONG).show();
callNoconnection();
}
API Call Success()
{
if(progressDialog.isShowing)
progressDialog.dismiss();
//your logic
}
Update your onFailure code :
#Override
public void onFailure(Call<ServerResponse> call, Throwable t) {
dialog.dismiss();
}
Also in onResponse, first you need to dismiss dialog :
#Override
public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
if(progressDialog.isShowing){
dialog.dismiss();
}
ServerResponse serverResponse = response.body();
if (serverResponse != null) {
if (serverResponse.getSuccess()) {
Toast.makeText(getActivity(), serverResponse.getMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(), serverResponse.getMessage(), Toast.LENGTH_SHORT).show();
}
} else {
// Log.v("Response", serverResponse.toString());
}
goToProfile();
}

Retrofit 2 : send files with json object

I'm sending object in request body, something like that :
{
"title":"test",
"description":"test",
"images":[]
}
#POST("create-data")
Call<JsonObject> publishData(#Body MyObject object);
and it's work fine without the images. From the docs I can find how to upload file to server using MultipartBody.Part, my questions is :
How can I upload multiple images at the same time?
Is it possible to send the images inside the object, or I need to send it separately and how ?
thank you very much.
request success just now with server
I reference the article:
https://futurestud.io/blog/retrofit-2-how-to-upload-files-to-server
#Multipart
#POST("uploadHeadPic")
Call<UploadHeadPicResponseModel> uploadHeadPic(#Part MultipartBody.Part file, #Part("json") RequestBody json);
public void doUploadHeadPic(#NonNull String filePath) {
if (!MNetworkUtil.isNetworkAvailable()) {
MToastUtil.show("网络不能连接");
return;
}
File file = new File(filePath);
String json = new Gson().toJson(new UploadHeadPicRequestModel());
if (!file.exists()) {
MToastUtil.show("文件不存在");
return;
}
progressDialog.show();
avatarSimpleDraweeView.setEnabled(false);
MApiManager.getService().uploadHeadPic(
MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file)),
RequestBody.create(MediaType.parse("multipart/form-data"), json))
.enqueue(new OnRetrofitCallbackListener<UploadHeadPicResponseModel>(mActivity) {
#Override
public void onSuccess(UploadHeadPicResponseModel responseModel) {
progressDialog.dismiss();
avatarSimpleDraweeView.setEnabled(true);
if (responseModel != null) {
String serverAvatarUrl = responseModel.data.headPicPath;
if (!TextUtils.isEmpty(serverAvatarUrl)) {
UserModel userModel = MUserManager.getInstance().getUser();
if (userModel != null) {
userModel.setAvatarUrl(serverAvatarUrl);
MUserManager.getInstance().updateOrInsertUserInfo(userModel);
MToastUtil.show("上传头像成功");
}
}
}
}
#Override
public void onFailure(int status, String failureMsg) {
progressDialog.dismiss();
avatarSimpleDraweeView.setEnabled(true);
MToastUtil.show((TextUtils.isEmpty(failureMsg) ? "上传失败" : failureMsg) + " : " + status);
}
});
}
update for multi files
may be this could help , I did not try
#Multipart
#POST("uploadHeadPic")
Call<UploadHeadPicResponseModel> uploadHeadPic(#Part MultipartBody.Part file0, #Part MultipartBody.Part file1, #Part("json") RequestBody json);
public void doUploadHeadPic(#NonNull String filePath) {
MApiManager.getService().uploadHeadPic(
MultipartBody.Part.createFormData("file0", file0.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file0)),
MultipartBody.Part.createFormData("file1", file1.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file1)),
RequestBody.create(MediaType.parse("multipart/form-data"), json))
.enqueue(new OnRetrofitCallbackListener<UploadHeadPicResponseModel>(mActivity) {
#Override
public void onSuccess(UploadHeadPicResponseModel responseModel) {
}
#Override
public void onFailure(int status, String failureMsg) {
}
});
}
In my case (uploading to server built with Spring) I needed to change MediaType for RequestBody:
RequestBody.create(MediaType.parse("application/json"), json)
RequestBody.create(MediaType.parse("image/jpg"), file)

Categories

Resources