in fact I am in the process of preparing an android application that makes the upload of an image on a server thanks to a REST API.
I tested lapi with POSTMAN and I have no errors.
but have an error in this part: I that the crash app before intent
this is my source codes:
public class FileShooser extends AppCompatActivity {
private static final int INTENT_REQUEST_CODE = 100;
private String name ;
private CompositeSubscription mSubscriptions;
ProgressDialog progressdialog ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSubscriptions = new CompositeSubscription();
// get name from last activity
name= getIntent().getStringExtra("Name");
// start file shooser intent
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
try {
startActivityForResult(intent, INTENT_REQUEST_CODE );
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==INTENT_REQUEST_CODE)
{
if(resultCode==RESULT_OK){
uploadImage( data.getData());
}
}
}
public byte[] getBytes(InputStream is) throws IOException {
ByteArrayOutputStream byteBuff = new ByteArrayOutputStream();
int buffSize = 1024;
byte[] buff = new byte[buffSize];
int len = 0;
while ((len = is.read(buff)) != -1) {
byteBuff.write(buff, 0, len);
}
return byteBuff.toByteArray();
}
private void uploadImage(Uri fileUri) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitInterface retrofitInterface = retrofit.create(RetrofitInterface.class);
// use the FileUtils to get the actual file by uri
File file = new File(fileUri.getPath());
showSnackBarMessage("name:"+file.getName());
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(
MediaType.parse(getContentResolver().getType(fileUri)),
file
);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("image", file.getName(), requestFile);
// progress dialog
progressdialog = new ProgressDialog(getApplicationContext());
progressdialog.setMessage("Please wait ...");
progressdialog.show();
retrofitInterface.upload(name,body).observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(this::handleResponse,this::handleError);
}
private void handleError(Throwable error) {
progressdialog.dismiss();
if (error instanceof HttpException) {
Gson gson = new GsonBuilder().create();
try {
String errorBody = ((HttpException) error).response().errorBody().string();
Response response = gson.fromJson(errorBody,Response.class);
showSnackBarMessage(response.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
} else {
showSnackBarMessage("Network Error !");
}
}
private void handleResponse(Response response) {
progressdialog.dismiss();
showSnackBarMessage(response.getMessage());
}
private void showSnackBarMessage(String message) {
Toast.makeText(getApplicationContext(),message,Toast.LENGTH_LONG).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
}
thank you very much for your answers
Related
I have a class that add a news with its images by Retrofit.
When Retrofit wants upload images, it shows me this error: FileNotFoundException
I have seen similar questions and answers but nothing was with multiple images.
So I could not find my solution and ask this question.
This is my Retrofit interface's method:
#POST("News/SaveNews")
Call<GetResualt> setNewsLetter(#Body NewsLetterModel newsLetter);
#Multipart
#POST("Products/Post")
Call<GetResualt> uploadNewsLetterImage(#Query("ProductID") String newsLetterId,
#Query("CompanyID") String coId,
#Query("UserID") String uID,
#Query("Token") String token,
#Part List<MultipartBody.Part> files);
This is my onActivityResult after image selecting:
ActivityResultLauncher<Intent> mLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == RESULT_OK) {
if (result.getData() != null) {
if (result.getData().getClipData() != null) {
int count = result.getData().getClipData().getItemCount();
int currentItem = 0;
while (currentItem < count) {
Uri imageUri = result.getData().getClipData().getItemAt(currentItem).getUri();
imageUriList.add(imageUri);
partNames.add(currentItem + "");
currentItem++;
}
} else if (result.getData().getData() != null) {
imageUriList.add(result.getData().getData());
}
}
NewsLetterModel newsLetter = new NewsLetterModel();
newsLetter.setActiveComment(false);
newsLetter.setActiveLike(false);
newsLetter.setActiveSave(false);
newsLetter.setCategory(category);
newsLetter.setCompanyId(BaseCodeClass.CompanyID);
newsLetter.setCreatorId(BaseCodeClass.userID);
newsLetter.setLinkOut("");
newsLetter.setLinkToInstagram("");
newsLetter.setNewsDescription(description);
newsLetter.setNewsTitle(title);
newsLetter.setShow(true);
newsLetter.setSpare1("#FFFFFF");
newsLetter.setSpare2("#FFFFFF");
newsLetter.setSpare3("#FFFFFF");
newsLetter.setToken(BaseCodeClass.token);
newsLetter.setUserId(BaseCodeClass.userID);
uploadNewsLetter(newsLetter);
}
}
);
This is uploadNewsLetter():
private void uploadNewsLetter(NewsLetterModel newsLetter) {
Retrofit retrofit;
JsonApi api;
retrofit = RetrofitInstance.getRetrofit();
api = retrofit.create(JsonApi.class);
Call<GetResualt> call = api.setNewsLetter(newsLetter);
call.enqueue(new Callback<GetResualt>() {
#Override
public void onResponse(Call<GetResualt> call, Response<GetResualt> response) {
if (response.body().getResualt().equals("100")) {
String newsId = response.body().getMsg();
List<MultipartBody.Part> files;
files = convertUriToFIle(partNames, imageUriList);
uploadNewsImages(newsId, files);
}
}
#Override
public void onFailure(Call<GetResualt> call, Throwable t) {
Log.e("Error", t.getMessage());
}
});
}
This is convertUriToFIle()
private List<MultipartBody.Part> convertUriToFIle(List<String> partNames, List<Uri> imageUriList) {
List<MultipartBody.Part> files = new ArrayList<>();
for (int i = 0; i < imageUriList.size(); i++) {
File file = new File(imageUriList.get(i).getPath());
RequestBody requestFile = RequestBody.create(MediaType.parse(FileUtils.MIME_TYPE_IMAGE), file);
files.add(MultipartBody.Part.createFormData(partNames.get(i), file.getName(), requestFile));
}
return files;
}
And This is uploadNewsMessage:
private void uploadNewsImages(String newsLetterId, List<MultipartBody.Part> files) {
Retrofit retrofit;
JsonApi api;
retrofit = RetrofitInstance.getRetrofit();
api = retrofit.create(JsonApi.class);
Call<GetResualt> call = api.uploadNewsLetterImage(newsLetterId, BaseCodeClass.CompanyID, BaseCodeClass.userID, BaseCodeClass.token, files);
call.enqueue(new Callback<GetResualt>() {
#Override
public void onResponse(Call<GetResualt> call, Response<GetResualt> response) {
if (response.body().getResualt().equals("100")) {
Toast.makeText(getContext(), "خبر با موفقیت ثبت شد", Toast.LENGTH_SHORT).show();
} else {
Log.e("Error", response.body().getResualt() + " " + response.body().getMsg());
}
}
#Override
public void onFailure(Call<GetResualt> call, Throwable t) {
Log.e("Error", t.getMessage());
}
});
}
So base on my code, at first application uploads news and other stuffs except of images, after that it uploads images.
But when it wants upload images it goes to onFailur of retrofit and shows me this error: FileNotFoundException.
In convertUriToFIle() use FileUtils.getFile(context,uri) instead of new File(imageUriList.get(i).getPath());
I am making one adforest classified alike app in my android studio and
below is the splash screen activity which executes first when i click on app icon but after that next activity does not open...progress bar on splash screen keeps on rotating but it is not openning next activity !!
SplashScreen.java
public class SplashScreen extends AppCompatActivity {
Activity activity;
SettingsMain setting;
JSONObject jsonObjectSetting;
boolean isRTL = false;
public static JSONObject jsonObjectAppRating, jsonObjectAppShare;
public static boolean gmap_has_countries = false, app_show_languages = false;
public static JSONArray app_languages;
public static String languagePopupTitle, languagePopupClose, gmap_countries;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
Configuration configuration = getResources().getConfiguration();
configuration.fontScale = (float) 1; //0.85 small size, 1 normal size, 1,15 big etc
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
metrics.scaledDensity = configuration.fontScale * metrics.density;
getBaseContext().getResources().updateConfiguration(configuration, metrics);
activity = this;
setting = new SettingsMain(this);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if (!prefs.getBoolean("firstTime", false)) {
setting.setUserLogin("0");
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstTime", true);
editor.apply();
}
if (getSupportActionBar() != null) {
getSupportActionBar().hide();
}
try {
PackageInfo info = getPackageManager().getPackageInfo(
"com.call4site.nearhaat",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (PackageManager.NameNotFoundException e)
{
e.printStackTrace();
}
if (SettingsMain.isConnectingToInternet(this)) {
adforest_getSettings(this);
} else {
AlertDialog.Builder alert = new AlertDialog.Builder(SplashScreen.this);
alert.setTitle(setting.getAlertDialogTitle("error"));
alert.setCancelable(false);
alert.setMessage(setting.getAlertDialogMessage("internetMessage"));
alert.setPositiveButton(setting.getAlertOkText(), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
SplashScreen.this.recreate();
}
});
alert.show();
}
}
public void adforest_getSettings(final Context context) {
RestService restService =
UrlController.createService(RestService.class);
Call<ResponseBody> myCall = restService.getSettings(UrlController.AddHeaders(this));
myCall.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> responseObj) {
try {
if (responseObj.isSuccessful()) {
Log.d("info settings Responce", "" + responseObj.toString());
JSONObject response = new JSONObject(responseObj.body().string());
Log.d("info settings object", "" + response.getJSONObject("data"));
if (response.getBoolean("success")) {
jsonObjectSetting = response.getJSONObject("data");
setting.setMainColor(jsonObjectSetting.getString("main_color"));
isRTL = jsonObjectSetting.getBoolean("is_rtl");
setting.setRTL(isRTL);
setting.setAlertDialogTitle("error", jsonObjectSetting.getJSONObject("internet_dialog").getString("title"));
setting.setAlertDialogMessage("internetMessage", jsonObjectSetting.getJSONObject("internet_dialog").getString("text"));
setting.setAlertOkText(jsonObjectSetting.getJSONObject("internet_dialog").getString("ok_btn"));
setting.setAlertCancelText(jsonObjectSetting.getJSONObject("internet_dialog").getString("cancel_btn"));
setting.setAlertDialogTitle("info", jsonObjectSetting.getJSONObject("alert_dialog").getString("title"));
setting.setAlertDialogMessage("confirmMessage", jsonObjectSetting.getJSONObject("alert_dialog").getString("message"));
setting.setAlertDialogMessage("waitMessage", jsonObjectSetting.getString("message"));
setting.setAlertDialogMessage("search", jsonObjectSetting.getJSONObject("search").getString("text"));
setting.setAlertDialogMessage("catId", jsonObjectSetting.getString("cat_input"));
setting.setAlertDialogMessage("location_type", jsonObjectSetting.getString("location_type"));
setting.setAlertDialogMessage("gmap_lang", jsonObjectSetting.getString("gmap_lang"));
setting.setGoogleButn(jsonObjectSetting.getJSONObject("registerBtn_show").getBoolean("google"));
setting.setfbButn(jsonObjectSetting.getJSONObject("registerBtn_show").getBoolean("facebook"));
JSONObject alertDialog = jsonObjectSetting.getJSONObject("dialog").getJSONObject("confirmation");
setting.setGenericAlertTitle(alertDialog.getString("title"));
setting.setGenericAlertMessage(alertDialog.getString("text"));
setting.setGenericAlertOkText(alertDialog.getString("btn_ok"));
setting.setGenericAlertCancelText(alertDialog.getString("btn_no"));
setting.isAppOpen(jsonObjectSetting.getBoolean("is_app_open"));
setting.checkOpen(jsonObjectSetting.getBoolean("is_app_open"));
setting.setGuestImage(jsonObjectSetting.getString("guest_image"));
JSONObject jsonObjectLocationPopup = jsonObjectSetting.getJSONObject("location_popup");
Log.d("info location_popup obj", "" + jsonObjectLocationPopup);
setting.setLocationSliderNumber(jsonObjectLocationPopup.getInt("slider_number"));
setting.setLocationSliderStep(jsonObjectLocationPopup.getInt("slider_step"));
setting.setLocationText(jsonObjectLocationPopup.getString("text"));
setting.setLocationBtnSubmit(jsonObjectLocationPopup.getString("btn_submit"));
setting.setLocationBtnClear(jsonObjectLocationPopup.getString("btn_clear"));
JSONObject jsonObjectLocationSettings = jsonObjectSetting.getJSONObject("gps_popup");
setting.setShowNearby(jsonObjectSetting.getBoolean("show_nearby"));
Log.d("info gps_popup obj", "" + jsonObjectLocationSettings);
setting.setGpsTitle(jsonObjectLocationSettings.getString("title"));
setting.setGpsText(jsonObjectLocationSettings.getString("text"));
setting.setGpsConfirm(jsonObjectLocationSettings.getString("btn_confirm"));
setting.setGpsCancel(jsonObjectLocationSettings.getString("btn_cancel"));
setting.setAdsPositionSorter(jsonObjectSetting.getBoolean("ads_position_sorter"));
setting.setBannerShow(false);
setting.setAdsPosition("");
setting.setBannerAdsId("");
setting.setInterstitalShow(false);
setting.setAdsInitialTime("");
setting.setAdsDisplayTime("");
setting.setInterstitialAdsId("");
setting.setNotificationTitle("");
setting.setNotificationMessage("");
setting.setNotificationTitle("");
if (setting.getAppOpen()) {
setting.setNoLoginMessage(jsonObjectSetting.getString("notLogin_msg"));
}
setting.setFeaturedScrollEnable(jsonObjectSetting.getBoolean("featured_scroll_enabled"));
if (setting.isFeaturedScrollEnable()) {
Log.d("info setting AutoScroll", jsonObjectSetting.getJSONObject("featured_scroll").toString());
setting.setFeaturedScroolDuration(jsonObjectSetting.getJSONObject("featured_scroll").getInt("duration"));
setting.setFeaturedScroolLoop(jsonObjectSetting.getJSONObject("featured_scroll").getInt("loop"));
}
jsonObjectAppRating = jsonObjectSetting.getJSONObject("app_rating");
jsonObjectAppShare = jsonObjectSetting.getJSONObject("app_share");
gmap_has_countries = jsonObjectSetting.getBoolean("gmap_has_countries");
if (gmap_has_countries) {
gmap_countries = jsonObjectSetting.getString("gmap_countries");
}
app_show_languages = jsonObjectSetting.getBoolean("app_show_languages");
if (app_show_languages) {
languagePopupTitle = jsonObjectSetting.getString("app_text_title");
languagePopupClose = jsonObjectSetting.getString("app_text_close");
app_languages = jsonObjectSetting.getJSONArray("app_languages");
}
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 100ms
if (setting.getUserLogin().equals("0")) {
SplashScreen.this.finish();
if (setting.isLanguageChanged()) {
if (isRTL)
updateViews("ur");
else {
updateViews("en");
}
}
Intent intent = new Intent(SplashScreen.this, MainActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.right_enter, R.anim.left_out);
} else {
SplashScreen.this.finish();
if (setting.isLanguageChanged()) {
if (isRTL)
updateViews("ur");
else {
updateViews("en");
}
}
setting.isAppOpen(false);
Intent intent = new Intent(SplashScreen.this, HomeActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.right_enter, R.anim.left_out);
}
if (app_show_languages && !setting.isLanguageChanged()) {
if (setting.getLanguageRtl()) {
updateViews("ur");
} else {
updateViews("en");
}
}
}
}, 2000);
} else {
Toast.makeText(activity, response.get("message").toString(), Toast.LENGTH_SHORT).show();
}
}
}
catch (JSONException e)
{
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("info settings error", String.valueOf(t));
Log.d("info settings error", String.valueOf(t.getMessage() + t.getCause() + t.fillInStackTrace()));
}
});
}
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
private void updateViews(String languageCode) {
LocaleHelper.setLocale(this, languageCode);
}
}
This is UrlController java class which uses to call retrofit api:
UrlController.java
public class UrlController {
static OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.MINUTES)
.writeTimeout(5, TimeUnit.MINUTES)
.readTimeout(5, TimeUnit.MINUTES)
.build();
private static String Purchase_code = "************************";
private static String Custom_Security = "***********************";
private static String url = "null";
private static String Base_URL = "https://yourdomain.co.in/demo/";
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(Base_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.build();
public static <S> S createService(Class<S> serviceClass)
{
url = retrofit.baseUrl().toString();
return retrofit.create(serviceClass);
}
public static <S> S createService(
Class<S> serviceClass, String username, String password, Context context)
{
if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password)) {
String authToken = Credentials.basic(username, password);
return createService(serviceClass, authToken, context);
}
return createService(serviceClass, null, null, context);
}
public static <S> S createService(
Class<S> serviceClass, final String authToken, Context context)
{
if (!TextUtils.isEmpty(authToken)) {
AuthenticationInterceptor interceptor = new AuthenticationInterceptor(authToken, context);
if (!httpClient.interceptors().contains(interceptor))
{
httpClient.addInterceptor(interceptor);
builder.client(httpClient.build());
retrofit = builder.build();
}
}
return retrofit.create(serviceClass);
}
public static Map<String, String> AddHeaders(Context context) {
Map<String, String> map = new HashMap<>();
if (SettingsMain.isSocial(context)) {
map.put("AdForest-Login-Type", "social");
}
map.put("Purchase-Code", Purchase_code);
map.put("custom-security", Custom_Security);
map.put("Adforest-Request-From", "android");
map.put("Adforest-Lang-Locale", SettingsMain.getLanguageCode());
map.put("Content-Type", "application/json");
map.put("Cache-Control", "max-age=640000");
return map;
}
public static Map<String, String> UploadImageAddHeaders(Context context) {
Map<String, String> map = new HashMap<>();
if (SettingsMain.isSocial(context)) {
map.put("AdForest-Login-Type", "social");
}
map.put("Purchase-Code", Purchase_code);
map.put("custom-security", Custom_Security);
map.put("Adforest-Lang-Locale", SettingsMain.getLanguageCode());
map.put("Adforest-Request-From", "android");
map.put("Cache-Control", "max-age=640000");
return map;
}
}
when it executes:
myCall.enqueue(new Callback()
{
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> responseObj)
{
//some code here
} );
#Override
public void onFailure(Call<ResponseBody> call, Throwable t)
{
//some code here
}
It does not executes either the on response method or on Failure method. No error or exception in catch block. In android studio logcat debug mode it shows :
D/WindowClient: Remove from mViews:android.widget.LinearLayout{a73a5de V.E...... ......I. 0,0-580,115}, this = android.view.WindowManagerGlobal#eeef6d7
i don't understand the problem behind it...is this debug message is the cause due to which next activity not opening or it is happening due to something else??
I am badly stuck here...not finding any way to move ahead !!
I want to upload multiple images to server using multi-part, I didn't get proper code, anyone please help me to fix solve my problem.If i send as base64 format ,backend team cant able to get my image. Thats' why I go with multipart. Either Volley or Asynctask.
I tried this code from this link
https://www.simplifiedcoding.net/upload-image-to-server/
But multiple images I dont know how to do.
Main.Java
package com.getspot.getspot.imagerestapi;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main7);
findViewById(R.id.buttonUploadImage).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//if everything is ok we will open image chooser
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 100);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100 && resultCode == RESULT_OK && data != null) {
//getting the image Uri
Uri imageUri = data.getData();
try {
//getting bitmap object from uri
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
//displaying selected image to imageview
imageView.setImageBitmap(bitmap);
//calling the method uploadBitmap to upload image
uploadBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public byte[] getFileDataFromDrawable(Bitmap bitmap) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 80, byteArrayOutputStream);
Log.i("AS","--"+byteArrayOutputStream.toByteArray());
return byteArrayOutputStream.toByteArray();
}
private void uploadBitmap(final Bitmap bitmap) {
//getting the tag from the edittext
final String tags = editTextTags.getText().toString().trim();
//our custom volley request
VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, ServerUtils.Gs_Clock_Image,
new Response.Listener<NetworkResponse>() {
#Override
public void onResponse(NetworkResponse response) {
try {
JSONObject obj = new JSONObject(new String(response.data));
Log.i("AS","obj--"+obj);
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("AS","error--"+error);
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
/*
* If you want to add more parameters with the image
* you can do it here
* here we have only one parameter with the image
* which is tags
* */
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("gs_userId", "6");
return params;
}
/*
* Here we are passing image by renaming it with a unique name
* */
#Override
protected Map<String, DataPart> getByteData() {
Map<String, DataPart> params = new HashMap<>();
long imagename = System.currentTimeMillis();
Log.i("AS","imagename--"+imagename);
Log.i("AS","getFileDataFromDrawable(bitmap)--"+getFileDataFromDrawable(bitmap));
params.put("gs_task_image", new DataPart(imagename + ".png", getFileDataFromDrawable(bitmap)));
return params;
}
};
//adding the request to volley
Volley.newRequestQueue(this).add(volleyMultipartRequest);
}
}
Note:While passing the byte-array in gs_text_image,in that how can i send multiple images.I referred that above link.Please help me
I'll show you how I do it (particular case ofc, but it might give you an idea)
So, first of all you need the method interface which will look like this:
#Multipart
#POST(RestClient.UPLOAD_PICTURES_FOR_ORDER)
Call<YourTypeOfResponse> uploadPictures(#Part("images[]") RequestBody[] file, #Part MultipartBody.Part[] images);
now, you will have to prepare the files(images) that you have, for the request
private void multiparts(){
RequestBody reqFullPicFile;
MultipartBody.Part filepart;
RequestBody filename;
images = new MultipartBody.Part[files.size()];
filenameImages = new RequestBody[files.size()];
for (int file = 0; file < files.size(); file++){
reqFullPicFile = RequestBody.create(MediaType.parse("multipart/form-data"), files.get(file));
filepart = MultipartBody.Part.createFormData("full_picture", files.get(file).getName(), reqFullPicFile);
filename = RequestBody.create(MediaType.parse("text/plain"), files.get(file).getName());
images[file] = filepart;
filenameImages[file] = filename;
}
}
And, in the end, make the request with the created Multiparts (in this case images & filenameImages)
private void uploadPicturesReq(){
if (files != null) {
multiparts();
RestClient.getApi().uploadPictures(filenameImages, images)
.enqueue(new Callback<PicturesResponse>() {
#Override
public void onResponse(Call<PicturesResponse> call, Response<PicturesResponse> response) {
if (response.isSuccessful() && response.code() == 200) {
// here you can handle the response from server
}
}
#Override
public void onFailure(Call<PicturesResponse> call, Throwable t) {
Log.e(TAG, "-=onFailure=- " + t.getMessage(), t);
}
});
}
}
I'm trying to create a progress dialog that updates the amount of file updated to server and display them in progress dialog, I followed this post( https://stackoverflow.com/a/33384551 ) the code:
public class ProgressRequestBody extends RequestBody {
private File mFile;
private String mPath;
private UploadCallbacks mListener;
private static final int DEFAULT_BUFFER_SIZE = 2048;
public interface UploadCallbacks {
void onProgressUpdate(int percentage);
void onError();
void onFinish();
}
public ProgressRequestBody(final File file, final UploadCallbacks listener) {
mFile = file;
mListener = listener;
}
#Override
public MediaType contentType() {
// i want to upload only images
return MediaType.parse("image/*");
}
#Override
public long contentLength() throws IOException {
return mFile.length();
}
#Override
public void writeTo(BufferedSink sink) throws IOException {
long fileLength = mFile.length();
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
FileInputStream in = new FileInputStream(mFile);
long uploaded = 0;
try {
int read;
Handler handler = new Handler(Looper.getMainLooper());
while ((read = in.read(buffer)) != -1) {
// update progress on UI thread
handler.post(new ProgressUpdater(uploaded, fileLength));
uploaded += read;
sink.write(buffer, 0, read);
}
} finally {
in.close();
}
}
private class ProgressUpdater implements Runnable {
private long mUploaded;
private long mTotal;
public ProgressUpdater(long uploaded, long total) {
mUploaded = uploaded;
mTotal = total;
}
#Override
public void run() {
mListener.onProgressUpdate((int)(100 * mUploaded / mTotal));
}
}
}
In api interface:
#Multipart
#POST("/upload")
Call<JsonObject> uploadImage(#Part MultipartBody.Part file);
in myActiviy:
class MyActivity extends AppCompatActivity implements ProgressRequestBody.UploadCallbacks {
ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
progressBar = findViewById(R.id.progressBar);
ProgressRequestBody fileBody = new ProgressRequestBody(file, this);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("image", file.getName(), fileBody);
Call<JsonObject> request = RetrofitClient.uploadImage(filepart);
request.enqueue(new Callback<JsonObject>{...});
}
#Override
public void onProgressUpdate(int percentage) {
// set current progress
progressBar.setProgress(percentage);
}
#Override
public void onError() {
// do something on error
}
#Override
public void onFinish() {
// do something on upload finished
// for example start next uploading at queue
progressBar.setProgress(100);
}
}
The problem I face is when I try to pass the "fileBody" object to
MultipartBody.Part filePart = MultipartBody.Part.createFormData("image",
file.getName(), fileBody);
I get an error as filebody cannot be passed in, it's a wrong argument.
I took reference from this post( https://stackoverflow.com/a/33384551 ) and coded it same but im getting erros.
You missing file paramater. Try it
File file = new File(your image path);
ProgressRequestBody fileBody = new ProgressRequestBody(file, this);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("image", file.getName(), fileBody);
I am developing an Android app. In my app, I am using Retrofit to upload image and pdf files to server in multipart/form-data request. I am new to Retrofit.
I uploaded pdf file and other string data successfully. But when I upload Image file, it is giving me "No such file or directory" exception even I did the same thing as PDF file that is successfully uploaded.
This is my activity upload pdf file and image file
public class ContributeActivity extends AppCompatActivity {
public static final int SELECT_PICTURE = 2334;
public static final int SELECT_BOOK = 123;
//other properties
private File bookFile;
private File imageFile;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = (AppSingleton)getApplication();
app.initialize();
setContentView(R.layout.activity_contribute);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//do other steps
}
private void saveBtnClick()
{
contributeBook();
}
private void openImagePicker()
{
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE);
}
private void setUpFilePickerImage()
{
ivBookFile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openBookFilePicker();
}
});
}
private void openBookFilePicker()
{
Intent intent = new Intent();
intent.setType("*/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select file"), SELECT_BOOK);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
if(selectedImageUri!=null)
{
try{
bmpCoverImage = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImageUri);
imageFile = new File(selectedImageUri.getPath());
if(bmpCoverImage!=null)
{
ivCoverImage.setImageBitmap(bmpCoverImage);
}
}
catch (IOException e)
{
Toast.makeText(getBaseContext(),"An error occurred with the file selected",Toast.LENGTH_SHORT).show();
}
}
}
else if(requestCode==SELECT_BOOK)
{
Uri bookUri = data.getData();
if(bookUri!=null)
{
String filePath = bookUri.toString();//bookUri.toString()
String mime = app.getMimeType(filePath);
if(mime!=null && !mime.isEmpty() && (mime.toLowerCase()=="application/pdf" || mime.toLowerCase()=="application/txt" || mime.toLowerCase()=="application/text"))
{
bookFile = new File(bookUri.getPath());
ivBookFile.setImageResource(R.drawable.book_selected);
}
else{
Toast.makeText(getBaseContext(),"Unable to process file you have chosen.",Toast.LENGTH_SHORT).show();
}
}
}
}
}
private Boolean validateForm()
{
// do validation
return true;
}
private void contributeBook()
{
RetrofitService service = RetrofitClient.retrofit.create(RetrofitService.class);
MultipartBody.Part bodyBookFile = null;
if(bookFile!=null)
{
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), bookFile);
bodyBookFile = MultipartBody.Part.createFormData("book_file", bookFile.getName(), requestFile);
}
MultipartBody.Part bodyImageFile = null;
if(imageFile!=null)
{
RequestBody requestImageFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile);
bodyImageFile = MultipartBody.Part.createFormData("image_file",imageFile.getName(),requestImageFile);
}
RequestBody title = RequestBody.create(MediaType.parse("multipart/form-data"), tfTitle.getText().toString());
RequestBody mmTitle = RequestBody.create(MediaType.parse("multipart/form-data"), tfMmTitle.getText().toString());
RequestBody parentId = RequestBody.create(MediaType.parse("multipart/form-data"),String.valueOf(selectedParentId));
RequestBody childId = RequestBody.create(MediaType.parse("multipart/form-data"), String.valueOf(selectedChildId));
RequestBody authorName = RequestBody.create(MediaType.parse("multipart/form-data"), tfAuthorName.getText().toString());
RequestBody authorMmName = RequestBody.create(MediaType.parse("multipart/form-data"), tfAuthorMmName.getText().toString());
RequestBody authToken = RequestBody.create(MediaType.parse("multipart/form-data"),app.getAuthToken());
Call<ResponseBody> call = service.contributeBook(bodyImageFile,bodyBookFile,title,mmTitle,parentId,childId,authorName,authorMmName,authToken);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response!=null && response.isSuccessful())
{
Toast.makeText(getBaseContext(),"Book successfully contributed. Thank you.",Toast.LENGTH_SHORT).show();
}
else if(response!=null && !response.isSuccessful() && response.errorBody()!=null)
{
//server error
Toast.makeText(getBaseContext(),"Validation errors",Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getBaseContext(),"An error occurred in server",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getBaseContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
}
This is my retrofit service interface
public interface RetrofitService {
#Multipart
#POST("book/contribute")
Call<ResponseBody> contributeBook(#Part MultipartBody.Part imageFile,#Part MultipartBody.Part bookFile,#Part("title") RequestBody title
,#Part("mm_title") RequestBody mmTitle,#Part("parent_category_id") RequestBody parentId,#Part("child_category_id") RequestBody childId
,#Part("author_name") RequestBody authorName,#Part("author_mm_name") RequestBody authorMmName,#Part("auth_token") RequestBody authToken);
}
This is my retrofit client class
public class RetrofitClient {
//implementation starts - should be in different class
public static final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(LinkConfig.API_END_POINT)
.client(RetrofitClient.httpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
public static OkHttpClient httpClient()
{
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header(AppSingleton.API_KEY_FIELD, AppSingleton.API_KEY)
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
});
return httpClient.build();
}
}
With the above code, I send pdf file with other string fields but without image file field. Everything worked fine. PDF file successfully uploaded to server and data are saved in the database. But when I chose the image file and submit data to server, it gives me following error in error listener of retrofit.
I got that error before when I first upload pdf file. I have to change as in activity result after choosing file.
From
uri.toString()
To
uri.getPath()
But as you can see, I did the same thing to both PDF file and Image file in activity result. But PDF file is working well and image file is giving me error.
These are permissions set in manifest file
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
If your device Version Is more then Api Level 22, then ask for permission at runtime, I also face the same problem, try to check permission at run time.
private static final int REQUEST_EXTERNAL_STORAGE = 3;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
public void checkStoragePermissions(Activity activity,Intent intent) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
} else {
activity.startActivity(intent);
}
}