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();
}
Related
Here is how I get the image from photo library:
private void presentPhotoSelector() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 0);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0 && resultCode == Activity.RESULT_OK && data != null) {
mSelectedPhotoUri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), mSelectedPhotoUri);
photoCircleImageView.setImageBitmap(bitmap);
photoCircleImageView.setVisibility(View.VISIBLE);
selectPhotoButton.setVisibility(View.INVISIBLE);
uploadImageToServer(mSelectedPhotoUri);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here is how I try to upload it:
public class JSONResponse {
boolean userUploadedProfileImage;
User user;
}
private void uploadImageToServer(Uri selectedPhotoUri) {
if (selectedPhotoUri == null) {
Log.d(TAG, "uploadImageToServer: selectedPhotoUri is null");
return;
}
if (!AuthService.getInstance(mContext).isLoggedIn()) {
Log.d(TAG, "uploadImageToServer: User not logged in");
return;
}
showLoading("Laster opp bilde...", "Vennligst vent mens prosess foregÄr");
File file = new File(selectedPhotoUri.getPath());
final MediaType MEDIA_TYPE_JPG = MediaType.parse("image/jpeg");
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", "image.jpg",
RequestBody.create(MEDIA_TYPE_JPG, file))
.build();
Request request = new Request.Builder()
.header("Authorization", "Bearer " + AuthService.getInstance(mContext).getToken())
.url(Config.URL + "/api/user/upload-profile-image")
.post(requestBody)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, final IOException e) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
hideLoading();
}
});
Log.d(TAG, "onFailure: response failed: " + e.getLocalizedMessage());
}
#Override
public void onResponse(Call call, Response response) throws IOException {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
hideLoading();
}
});
String responseBodyString = response.body().string();
Log.d(TAG, "onResponse: responseBodyString: " + responseBodyString);
Gson gson = new Gson();
SettingsFragment.JSONResponse jsonResponse = gson.fromJson(responseBodyString, SettingsFragment.JSONResponse.class);
if (jsonResponse != null) {
UserService.getInstance(mContext).setMyUser(jsonResponse.user);
Log.d(TAG, "onResponse: jsonResponse.userUploadedProfileImage: " + jsonResponse.userUploadedProfileImage);
Log.d(TAG, "onResponse: jsonResponse.user: " + jsonResponse.user.toString());
}
}
});
}
This does not work, the loader never stops spinning and on server side I get this error: multipart: NextPart: client disconnected
However, if I change the code above from:
File file = new File(selectedPhotoUri.getPath());
to:
String file = selectedPhotoUri.getPath();
Then request is successful, however, when I try to open the image on a browser it says "the image cannot be displayed because it contains errors". When I look at the database I can see that it interpreted its mime type as: application/octet-stream, and not image/jpeg.
I am stuck and I don't know what to do.
I am now getting this error on console: onFailure: response failed: /-1/1/content:/media/external/images/media/69/ORIGINAL/NONE/656735600 (No such file or directory)
I am running this on a simulator, if that helps.
One way is:
You have to convert Bitmap to Base64(String) and send that base64 to server.
I need to handle a functionality based on the retrofit response.
The post method has the request as json format and getting the response as Text true
I have tried to get this response as the following code snippet. But always I get false though I get true in postman response.
private void callPostLoginAPI(String webServiceResponse) {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<ResponseBody> result = apiService.getPostDealer(postLoginAPI(webServiceResponse));
result.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
String postLoginResponse = null;
try {
postLoginResponse = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
if (postLoginResponse != null || (!postLoginResponse.equals(""))) {
if (postLoginResponse.equals("true")) {
try {
if (PreferenceClass.getInstallationID(Loginpage.this) == null ||
PreferenceClass.getInstallationID(Loginpage.this).equals("")) {
request_appInstallation_API(0);
} else {
checkAppUpdate();
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(Loginpage.this, "Please contact CMS Admin", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(Loginpage.this, "Something went wrong... Please try again", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(Loginpage.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
UPDATE:
As I tried the following,and I havent gotten the respective "Postman response value" .
ApiInterface apiService = ApiClient.getClient1().create(ApiInterface.class);
Call<Boolean> result = apiService.getPostDealer(postLoginAPI(webServiceResponse));
result.enqueue(new Callback<Boolean>() {
#Override
public void onResponse(Call<Boolean> call, Response<Boolean> response) {
Log.i("Response", response.body().toString());
if (response.isSuccessful()) {
if (response.body() != null) {
Log.i("callPostLoginAPI", response.body().toString());
Toast.makeText(Dealer_Loginpage.this, "returned", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(Dealer_Loginpage.this, "Nothing returned", Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onFailure(Call<Boolean> call, Throwable t) {
Toast.makeText(Dealer_Loginpage.this, "Nothing returned", Toast.LENGTH_LONG).show();
}
});
ApiClient.getClient1() :
public static Retrofit getClient1() {
if (retrofit1 == null) {
retrofit1 = new Retrofit.Builder().baseUrl(GlobalClass.sBase_Url).
addConverterFactory(ScalarsConverterFactory.create()).
addConverterFactory(GsonConverterFactory.create()).build();
}
return retrofit1;
}
Solution:
Attach this:
postLoginResponse.replaceAll("[^A-Za-z]+", "");
After the line:
postLoginResponse = response.body().string();
and try.
I am trying to upload a video file using multipart by retrofit and I get the following error in response
Response{protocol=http/1.1, code=405, message=Method Not Allowed, url=serverurl/Upload/Videos/}
This is my code for file upload
void uploadVideo(String videoPath) {
dialog.show();
File videoFile = new File(videoPath);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), videoPath);
MultipartBody.Part vFile = MultipartBody.Part.createFormData("file", videoFile.getName(), requestFile);
apiCall.uploadVideoToServer(presenter.getUserInfo().getUploadVideoPath(), vFile).enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
dialog.dismiss();
}
#Override
public void onFailure(Call<String> call, Throwable t) {
dialog.dismiss();
}
});
}
This is the path I am uploading the file to
http://serverurl.com/Upload/Videos/
Can someone tell me whats wrong with my code?
Retrofir API interface
#Multipart
#POST
Call<String> uploadVideoToServer(#Url String url, #Part MultipartBody.Part video);
in your api service interface :
#Multipart
#POST("Upload/Videos") // *** DONT FORGET UR END POINT HERE ***
Call<urmodel> uploadVideoToServer(#PartMap Map<String, RequestBody> map);
and write a method to upload ur video file like this :
private void uploadVideoToServer(String path) {
File videoFile = new File(path);
if (videoFile.exists()) {
//create request body
Map<String, RequestBody> map = new HashMap<>();
RequestBody requestBody = RequestBody.create(MediaType.parse("video/*"), videoFile);
map.put("video\"; filename=\"" + videoFile.getName() + "\"", requestBody);
//make call
Call<urmodel> call = mTService.uploadVideoToServer(map);
call.enqueue(new Callback<urmodel>() {
#Override
public void onResponse(Call<urmodel> call, Response<urmodel> response) {
if (response.isSuccess()) {
// DO SOMETHING
} else {
// DO SOMETHING
}
}
#Override
public void onFailure(Call<urmodel> call, Throwable t) {
//occur when fail to deserialize || no network connection || server unavailable
Toast.makeText(getBaseContext(), "Fail it >> " + t.getMessage(), Toast.LENGTH_LONG).show();
}
});
} else {
Toast.makeText(getBaseContext(), "can not upload file since the file is not exist :|", Toast.LENGTH_SHORT).show();
}
}
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
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.