I want to upload a video file using Retrofit 2, please help me doing this.
This is my endpoint:
upload.php:
<?php
$uploaddir = '../uploads/';
$uploadfile = $_FILES['userfile']['name'];
$response = array();
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir.$uploadfile))
{
$response["result"] = "1";
echo json_encode($response);
} else
{
$response["result"] = "-1";
echo json_encode($response);
}
?>
I tried to follow a sample (combining it with file selection from the gallery) on the web, but it doesn't even compile (I have marked the erroneous line by a comment):
MainActivity:
public class MainActivity extends Activity
{
private static int RESULT_LOAD_VIDEO = 1;
String decodableString;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn_load = (Button) findViewById(R.id.buttonLoadVideo);
btn_load.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
loadVideoFromGallery(btn_load);
}
});
}
/*
* PICK THE VIDEO AND EXTRACT ITS ADDRESS
*/
public void loadVideoFromGallery(View view)
{
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, RESULT_LOAD_VIDEO);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
try {
// When a video is picked
if (requestCode == RESULT_LOAD_VIDEO && resultCode == RESULT_OK
&& null != data)
{
// Get the video from data
Uri selectedVideo = data.getData();
String[] filePathColumn = { MediaStore.Video.Media.DATA };
Cursor cursor = getContentResolver().query(selectedVideo,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
decodableString = cursor.getString(columnIndex);
Log.i("mok",decodableString);
cursor.close();
upload(decodableString);
} else
{
Toast.makeText(this, "You haven't picked any video",
Toast.LENGTH_LONG).show();
}
} catch (Exception e)
{
e.printStackTrace();
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
.show();
}
}
/*
* UPLOAD THE SELECTED VIDEO TO THE SRVER
*/
public void upload(String decodableString)
{
final String BASE_URL = "http://192.168.1.7/";
Retrofit retrofit = new Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
UploadApiService service = retrofit.create(UploadApiService.class);
MediaType MEDIA_TYPE = MediaType.parse("video/mp4");
File file = new File("/storage/emulated/0/Pictures/MyApp/test.png");
RequestBody requestBody = RequestBody.create(MEDIA_TYPE, file);
Call<com.squareup.okhttp.ResponseBody> call = service.uploadVideo("desc", requestBody);
call.enqueue(new Callback<ResponseBody>(){ //error even before compile***
#Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit)
{
// TODO Auto-generated method stub
if (response.isSuccess())
{
Log.i("mok","S");
ResponseBody rb = response.body();
Log.i("mok",rb.getUsername());
}
else
{
Log.i("mok","F");
com.squareup.okhttp.ResponseBody rb = response.errorBody();
}
}
#Override
public void onFailure(Throwable t)
{
t.printStackTrace();
Log.i("mok",t.getCause()+"");
Log.i("mok","T");
finish();
}
});
}
}
UploadApiService:
public interface UploadApiService
{
#Multipart
#POST("api/upload.php")
Call<ResponseBody> uploadVideo(#Part("description") String description, #Part("video") RequestBody video);
}
I guess I have to use a kind of Stream to keep track of the progress but unfortunately I don't know more.
Make sure you imports are the correct. For example, Callback should be retrofit.Callback;, not import com.squareup.okhttp.Callback;. Based on your comment, it sounds like the real problem was a type conflict with a locally defined ResponseBody.
Related
I want to use onActivityResult method in Adapter but after searching on Stack Overflow I found I have to make interface for onActivityResult but I donot know how to make this and handle onActivityResult Methode to work as per my need.
Here is my Adapter Class.
public class PosterAdapter extends RecyclerView.Adapter<PosterAdapter.PosterViewHolder> {
private static final String TAG = "resPoster";
private ArrayList<Poster> posterArrayList;
private Context context;
public PosterAdapter(ArrayList<Poster> posterArrayList, Context context) {
this.posterArrayList = posterArrayList;
this.context = context;
}
#NonNull
#Override
public PosterViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.sending_image_layout, viewGroup, false);
return new PosterViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull PosterViewHolder posterViewHolder, int i) {
posterViewHolder.imageViewDownload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
posterViewHolder.relativeLayoutImage.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(posterViewHolder.relativeLayoutImage.getDrawingCache());
posterViewHolder.relativeLayoutImage.setDrawingCacheEnabled(false);
FileOutputStream outStream = null;
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/providers");
dir.mkdirs();
String fileName = String.format("%d.jpg", System.currentTimeMillis());
Log.d(TAG,"filename: " + fileName);
File outFile = new File(dir, fileName);
Log.d(TAG,"outFile: " + outFile);
try {
outStream = new FileOutputStream(outFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
posterViewHolder.imageViewEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent();
i.setType("image/*");
i.setAction(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
// startActivityForResult(i, 0);
((Activity) context).startActivityForResult(Intent.createChooser(i, "CHOOSING INTENT"), 0);
}
});
}
#Override
public int getItemCount() {
return posterArrayList.size();
}
public class PosterViewHolder extends RecyclerView.ViewHolder {
RelativeLayout relativeLayoutImage;
ImageView imageViewBg, imageViewEdit, imageViewDownload, imageViewShare;
CircleImageView imageViewProfie;
public PosterViewHolder(#NonNull View posterView) {
super(posterView);
relativeLayoutImage = posterView.findViewById(R.id.image_relative);
imageViewBg = posterView.findViewById(R.id.image_bg);
imageViewProfie = posterView.findViewById(R.id.image_profile_moving);
imageViewEdit = posterView.findViewById(R.id.edit_image);
imageViewDownload = posterView.findViewById(R.id.download_image);
imageViewShare = posterView.findViewById(R.id.share_image);
}
}
}
and I want to use this class
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == 0) {
final Uri selectedUri = data.getData();
if (selectedUri != null) {
startCrop(selectedUri);
} else {
Toast.makeText(context, "Cannot retrieve selected Image", Toast.LENGTH_SHORT).show();
}
} else if (requestCode == UCrop.REQUEST_CROP) {
handleCropResult(data);
}
}
if (resultCode == UCrop.RESULT_ERROR) {
handleCropError(data);
}
}
Please Help me handle this method in interface.
Thank you.
**UPDATE: **
Here is my activity code to understand more my question.
RequestQueue requestQueue;
private ArrayList<Poster> posterArrayList = new ArrayList<>();
private RecyclerView recyclerView;
private PosterAdapter posterAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sending_image);
requestQueue = Volley.newRequestQueue(this);
recyclerView = findViewById(R.id.recycler_poster);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
getAllPoster();
}
private void getAllPoster() {
HashMap<String, String> params = new HashMap<String, String>();
params.put("poster_id", "1");
Log.d(TAG + "pp", String.valueOf(params));
String Url = Constants.Base_URL + "poster/";
JsonObjectRequest request = new JsonObjectRequest(Url, new JSONObject(params),
response -> {
Log.d("responsePending", String.valueOf(response));
try {
String statusResponseObject = response.getString("status");
String msgObject = response.getString("msg");
if (statusResponseObject.equals("200")){
JSONArray jsonArray = response.getJSONArray("response");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject pendingFragResponse = jsonArray.getJSONObject(i);
String posterObject = pendingFragResponse.getString("poster");
String positionObject = pendingFragResponse.getString("position");
String sizeObject = pendingFragResponse.getString("size");
String txt_positionObject = pendingFragResponse.getString("txt_position");
String titleObject = pendingFragResponse.getString("title");
String descriptionObject = pendingFragResponse.getString("description");
//
posterArrayList.add(new Poster(posterObject, positionObject,
sizeObject, txt_positionObject,
titleObject, descriptionObject));
posterAdapter = new PosterAdapter( posterArrayList, SendingImageActivity.this);
recyclerView.setAdapter(posterAdapter);
// wp10ProgressBar.hideProgressBar();
// wp10ProgressBar.setVisibility(View.GONE);
}
posterAdapter.notifyDataSetChanged();
// wp10ProgressBar.hideProgressBar();
}else {
// wp10ProgressBar.hideProgressBar();
// wp10ProgressBar.setVisibility(View.GONE);
Toast.makeText(SendingImageActivity.this, msgObject, Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(this, "Server didn't response, Try after some time", Toast.LENGTH_LONG).show();
}
}, error -> {
error.printStackTrace();
Log.d(TAG + "error", String.valueOf(error.getMessage()));
Toast.makeText(this, "Server didn't response, Try after some time", Toast.LENGTH_LONG).show();
});
requestQueue.add(request);
}
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(this, "Server didn't response, Try after some time", Toast.LENGTH_LONG).show();
}
}, error -> {
error.printStackTrace();
Log.d(TAG + "error", String.valueOf(error.getMessage()));
Toast.makeText(this, "Server didn't response, Try after some time", Toast.LENGTH_LONG).show();
});
requestQueue.add(request);
}
}
Rather than using Interface pattern just create public method inside your adapter and call that method when your onActivityResult hits in Activity.
(This answer is just a workaround for your scenario. Ideally you should not pass your activity Context to your adapter, rather than use Interface pattern and receive callback inside your activity whenever any action took place (like clicking on edit button) inside your activity and pass relevant data while trigger callback from your adapter.)
You can refer AllNoteActivity and NoteAdapter for reference here
So what you need to do is put the current method onActivityResult() from PosterAdapter to the activity. Then make the methods startCrop(), handleCropResult() and handleCropError() public (I assume are in PosterAdapter).
In the onActivityResult() change the call of startCrop() to posterAdapter.startCrop(). Same for the other methods. And that should do it.
Create a method in adapter
In your adapter class
public void waterverYouWantMethod(){
}
And call that method from Activity when onActivityResult mehtod called.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
// call that method here
adapter.wateverYouWantMethod();
}
}
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 having trouble using the upload method in some files (with a UTF-8 character). When I select these files, I will encounter the following error:
FATAL EXCEPTION: Thread-34
Process: com.articlerdotir.articler, PID: 27672
java.lang.NullPointerException: Attempt to invoke interface method 'int java.lang.CharSequence.length()' on a null object reference
at java.util.regex.Matcher.reset(Matcher.java:995)
at java.util.regex.Matcher.(Matcher.java:174)
at java.util.regex.Pattern.matcher(Pattern.java:1006)
at okhttp3.MediaType.parse(MediaType.java:52)
at com.articlerdotir.articler.activity.UploaderActictivity.UploadFile(UploaderActictivity.java:186)
at com.articlerdotir.articler.activity.UploaderActictivity$2$1.run(UploaderActictivity.java:154)
at java.lang.Thread.run(Thread.java:762)
When I select these files and upload them, I will encounter the following.
For example, when the file name is: DellaAli.doc or 0123.doc does not come up with a problem, but when the file name is دلهعلی.doc or ۰۱۲۳.doc this code does not work properly. How to fix this problem? Thanks
this is my code for uploader activity:
public class UploaderActictivity extends AppCompatActivity {
private Button button_browse,button_upload;
JustifiedTextView js,messageText;
ImageView imNotify;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_uploader);
js=findViewById(R.id.textDes);
messageText =findViewById(R.id.messageText);
imNotify =findViewById(R.id.notify);
button_browse = (Button) findViewById(R.id.browse);
button_upload =(Button) findViewById(R.id.upload);
js.setText( getResources().getString(des) + "\n" +
getResources().getString(des1)+ "\n" +
getResources().getString(des2)+ "\n" +
getResources().getString(des3));
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},100);
return;
}
}
browse_btn();
upload_btn();
}
private void browse_btn() {
button_browse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new MaterialFilePicker()
.withActivity(UploaderActictivity.this)
.withRequestCode(10)
.start();
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == 100 && (grantResults[0] == PackageManager.PERMISSION_GRANTED)){
browse_btn();
}else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},100);
}
}
}
ProgressDialog progress;
#Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
if(requestCode == 10 && resultCode == RESULT_OK){
String filePath = data.getStringExtra(FilePickerActivity.RESULT_FILE_PATH);
messageText.setText(filePath);
}
}
private void upload_btn() {
button_upload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
progress = new ProgressDialog(UploaderActictivity.this);
progress.setTitle("Uploading");
progress.setMessage("Please wait...");
progress.setCancelable(false);
progress.show();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
File f = new File(messageText.getText().toString());
if(f.isFile()) {
UploadFile(f);
}else {
messageText.setText(getResources().getString(uploadFile));
}
}
});
t.start();
}
});
}
private String getMimeType(String path) {
String extension = MimeTypeMap.getFileExtensionFromUrl(path);
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
public void UploadFile(final File f){
String content_type = getMimeType(f.getPath());
String file_path = f.getAbsolutePath();
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(UploaderActictivity.this);
final int UserID = prefs.getInt("UserID", 0);
OkHttpClient client = new OkHttpClient();
RequestBody file_body = RequestBody.create(MediaType.parse(content_type), f);
RequestBody request_body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("type", content_type)
.addFormDataPart("uploaded_file",
UserID + "_" + file_path.substring(file_path.lastIndexOf("/") + 1), file_body)
.build();
Request request = new Request.Builder()
.url(AppConfig.upLoadServerUri + "/upload")
.post(request_body)
.build();
try {
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new IOException("Error : " + response);
}
progress.dismiss();
runOnUiThread(new Runnable() {
#Override
public void run() {
messageText.setText(getResources().getString(DescriptionForUpload));
}
});
} catch (IOException e) {
progress.dismiss();
e.printStackTrace();
runOnUiThread(new Runnable() {
#Override
public void run() {
messageText.setText(getResources().getString(uploadAgain));
}
});
}
}
#Override
protected void onDestroy()
{
super.onDestroy();
if (progress!=null && progress.isShowing()){
progress.dismiss();
}
}
}
the problem that your getMimeType return null
just change the getMimeType function width this
private fun getMimeType(path: String): String? {
val extension = MimeTypeMap.getFileExtensionFromUrl(path)
return if(extension.isNullOrEmpty()){
val i = path.lastIndexOf('.')
if (i > 0) {
path.substring(i + 1)
}else{
MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
}
}else{
MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
}
}
this code is in kotlin
I m trying to upload Multipart Multiple Image Upload in Retrofit,but it shows response failure error like that [/storage/emulated/0/Whatsapp/Media/WhatsApp Images/abc.jpg,/storage/emulated/0/Whatsapp/Media/WhatsApp Images/abcd.jpg] open failed; ENOENT (No such file or directory)
I followed this tutorial...https://futurestud.io/tutorials/retrofit-2-how-to-upload-a-dynamic-amount-of-files-to-server
I used this Library for Image Picker...https://github.com/myinnos/AwesomeImagePicker
Activity.java :
private void ImageChooser(){
Intent intent = new Intent(this, AlbumSelectActivity.class);
intent.putExtra(ConstantsCustomGallery.INTENT_EXTRA_LIMIT,5); // set limit for image selection
startActivityForResult(intent, ConstantsCustomGallery.REQUEST_CODE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ConstantsCustomGallery.REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) {
ArrayList<images> images = data.getParcelableArrayListExtra(ConstantsCustomGallery.INTENT_EXTRA_IMAGES);
ArrayList<String> imagelist = new ArrayList<>();
for (int i = 0; i < images.size(); i++) {
Uri uri = Uri.fromFile(new File(images.get(i).path));
String filePath = getRealPathFromURIPath(uri, WorkerAddPhotosActivity.this);
imagelist.add(filePath);
}
LoadWorkerInquiry(images)
}
}
private String getRealPathFromURIPath(Uri contentURI, Activity activity) {
Cursor cursor = activity.getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) {
return contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
}
public void LoadWorkerInquiry(ArrayList<String> image) {
ApiConfig getResponse = AppConfig.getRetrofit().create(ApiConfig.class);
List<MultipartBody.Part> parts = new ArrayList<>();
for (int index = 0; index < image.size(); index++) {
File file = new File(image.toString());
RequestBody surveyBody = RequestBody.create(MediaType.parse("image/*"), file);
parts.add(MultipartBody.Part.createFormData("image", file.getName(), surveyBody));
}
Call<WorkerImageUpload> call = getResponse.uploadImages(parts);
call.enqueue(new Callback<WorkerImageUpload>() {
#Override
public void onResponse(Call<WorkerImageUpload> call, retrofit2.Response<WorkerImageUpload> response) {
WorkerImageUpload serverResponse = response.body();
if (response.isSuccessful()) {
} else {
}
}
#Override
public void onFailure(Call<WorkerImageUpload> call, Throwable t) {
if (t instanceof IOException) {
Error("Timeout",t.getMessage());
}
else if (t instanceof IllegalStateException) {
Error("ConversionError",t.getMessage());
} else {
Error("Error",t.getMessage());
}
}
});
}
Api Interface :
#Multipart
#POST("api/***")
Call<WorkerImageUpload> uploadImages(#Part List<MultipartBody.Part> Image);
I assume you are trying to access WhatsApp internal storage which is forbidden without specifically granted access.
Try to access files in your app storage. This documentation will be useful: https://developer.android.com/guide/topics/data/data-storage.html
How to send the request string param using Retrofit. I have submitted the code below. Here how to add the string param and send to server.
AppConfig:
public class AppConfig {
public static String BASE_URL = "http://104.239.173.64/peoplecaddie-api";
public static Retrofit getRetrofit() {
return new Retrofit.Builder()
.baseUrl(AppConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
ApiConfig:
public interface ApiConfig {
#Multipart
#POST("/general/Candidate/fileUpload")
Call<ServerResponse> upload(
#Header("Authorization") String authorization,
#PartMap Map<String, RequestBody> map
);
}
ServerResponse:
public class ServerResponse {
// variable name should be same as in the json response from php
#SerializedName("success")
boolean success;
#SerializedName("message")
String message;
public String getMessage() {
return message;
}
public boolean getSuccess() {
return success;
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
Button btnUpload, btnPickImage, btnPickVideo;
String mediaPath;
ImageView imgView;
String[] mediaColumns = {MediaStore.Video.Media._ID};
ProgressDialog progressDialog;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Uploading...");
btnUpload = (Button) findViewById(R.id.upload);
btnPickImage = (Button) findViewById(R.id.pick_img);
btnPickVideo = (Button) findViewById(R.id.pick_vdo);
imgView = (ImageView) findViewById(R.id.preview);
btnUpload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
uploadFile();
}
});
btnPickImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, 0);
}
});
// Video must be low in Memory or need to be compressed before uploading...
btnPickVideo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, 1);
}
});
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client2 = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
// When an Image is picked
if (requestCode == 0 && resultCode == RESULT_OK && null != data) {
// Get the Image from data
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
assert cursor != null;
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
mediaPath = cursor.getString(columnIndex);
// Set the Image in ImageView for Previewing the Media
imgView.setImageBitmap(BitmapFactory.decodeFile(mediaPath));
cursor.close();
} // When an Video is picked
else if (requestCode == 1 && resultCode == RESULT_OK && null != data) {
// Get the Video from data
Uri selectedVideo = data.getData();
String[] filePathColumn = {MediaStore.Video.Media.DATA};
Cursor cursor = getContentResolver().query(selectedVideo, filePathColumn, null, null, null);
assert cursor != null;
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
mediaPath = cursor.getString(columnIndex);
// Set the Video Thumb in ImageView Previewing the Media
imgView.setImageBitmap(getThumbnailPathForLocalFile(MainActivity.this, selectedVideo));
cursor.close();
} else {
Toast.makeText(this, "You haven't picked Image/Video", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG).show();
}
}
// Providing Thumbnail For Selected Image
public Bitmap getThumbnailPathForLocalFile(Activity context, Uri fileUri) {
long fileId = getFileId(context, fileUri);
return MediaStore.Video.Thumbnails.getThumbnail(context.getContentResolver(),
fileId, MediaStore.Video.Thumbnails.MICRO_KIND, null);
}
// Getting Selected File ID
public long getFileId(Activity context, Uri fileUri) {
Cursor cursor = context.managedQuery(fileUri, mediaColumns, null, null, null);
if (cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
return cursor.getInt(columnIndex);
}
return 0;
}
// Uploading Image/Video
private void uploadFile() {
progressDialog.show();
// Map is used to multipart the file using okhttp3.RequestBody
Map<String, RequestBody> map = new HashMap<>();
File file = new File(mediaPath);
RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file);
map.put("fileContent0\"; filename=\"" + file.getName() + "\"", requestBody);
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()) {
Log.e("Response", serverResponse.getMessage());
Toast.makeText(getApplicationContext(), serverResponse.getMessage(), Toast.LENGTH_SHORT).show();
} else {
Log.e("Response", serverResponse.getMessage());
Toast.makeText(getApplicationContext(), serverResponse.getMessage(), Toast.LENGTH_SHORT).show();
}
} else {
Log.v("Response", serverResponse.toString());
}
progressDialog.dismiss();
}
#Override
public void onFailure(Call<ServerResponse> call, Throwable t) {
Log.e("Throwable", t.toString());
}
});
}
#Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client2.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app URL is correct.
Uri.parse("android-app://com.delaroystudios.androidupload/http/host/path")
);
AppIndex.AppIndexApi.start(client2, viewAction);
}
#Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app URL is correct.
Uri.parse("android-app://com.delaroystudios.androidupload/http/host/path")
);
AppIndex.AppIndexApi.end(client2, viewAction);
client2.disconnect();
}
}
In the above example code just passed the token and File with the help of request Body.
How to send request string param with above code.
that is How to send Below login_params details as a request param using retrofit. when i tried i got
/Throwable: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $ . this exception.
HashMap<String, String> login_params = new HashMap<String, String>();
login_params.put("fileCount", "1");
login_params.put("id","1743");
login_params.put("fileType", "SAMPLE");
login_params.put("platform", "Android");
login_params.put("externalID", "portpolio");
You can use #PartMap annotation to pass parameters along with File request. PartMap is a Map of "Key" and RequestBody. So first, you have to create RequestBody object of the parameter that you want to pass and then create Map object of it and pass it as argument.
For example your method in api interface would be,
#Multipart
#POST("upload")
Call<ResponseBody> uploadFileWithPartMap(
#PartMap() Map<String, RequestBody> partMap,
#Part MultipartBody.Part file);
and request would be,
MultipartBody.Part body = prepareFilePart("photo", fileUri);
// create a map of data to pass along
RequestBody token= RequestBody.create(
MediaType.parse(MULTIPART_FORM_DATA), "token_string");
HashMap<String, RequestBody> map = new HashMap<>();
map.put("token", token);
-----------------
private MultipartBody.Part prepareFilePart(String partName, Uri fileUri) {
// https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java
// use the FileUtils to get the actual file by uri
File file = FileUtils.getFile(this, fileUri);
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(MediaType.parse(MULTIPART_FORM_DATA), file);
// MultipartBody.Part is used to send also the actual file name
return MultipartBody.Part.createFormData(partName, file.getName(), requestFile);
}
and finally the calling method would be,
// finally, execute the request
Call<ResponseBody> call = service.uploadFileWithPartMap(map, body);
call.enqueue(...);
I hope this will help you and for detailed reference please check this link https://futurestud.io/tutorials/retrofit-2-passing-multiple-parts-along-a-file-with-partmap