I am working on android app and I need to post request with file to the server.
I am using retrofit
to do that and I do Multipart
api request.
Then I use Intent.createChooser
to pick the file.
The problem come in when I do enqueue
to the service call. In the onFailure
I get this error:
E/Upload errorrrrrr:: /document/image:77317 (No such file or directory)
However, This is the uri and file path which I get in the onActivityResult
:
uri: content://com.android.providers.media.documents/document/image%3A77317
path: /document/image:77317
and I put the permissions:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera2.full" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature
android:name="android.hardware.camera.any"
android:required="true" />
and this is the request:
@Multipart
@POST("upload_document")
Call<UploadDocuments> uploadDocuments(
@Header("Authorization") String authorization,
@Part MultipartBody.Part document_name,
@Part("document_type") RequestBody document_type,
@Part("fk_id") RequestBody fk_id,
@Part("type") RequestBody type,
@Part("certificate_name") RequestBody certificate_name,
@Part("certificate_description") RequestBody certificate_description,
@Part("notes") RequestBody notes);
How I can solve this problem? and Thanks,
My Code:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_passport);
button = (Button) findViewById(R.id.btnUpload);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("*/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select File"), PICK_PHOTO_FOR_AVATAR );
}
});
}
@Override
protected void onActivityResult(int requestCode, final int resultCode, Intent data) {
if (requestCode == PICK_PHOTO_FOR_AVATAR && resultCode == Activity.RESULT_OK) {
if (data == null) {
//Display an error
return;
}
else {
Uri uri = data.getData();
path = data.getData().getPath();
if(uri != null)
uploadFile(uri);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void uploadFile(Uri fileUri) {
// use the FileUtils to get the actual file by uri
File file = FileUtils.getFile( fileUri.getPath());
// create RequestBody instance from file
final RequestBody requestFile =
RequestBody.create(
MediaType.parse("*/*"),
file
);
// MultipartBody.Part is used to send also the actual file name
final MultipartBody.Part body =
MultipartBody.Part.createFormData("document_name", file.getName(), requestFile);
// add another part within the multipart request
String document_type1 = "CV";
String fk_id1 ="2";
String type1 = "property_documents";
String certificate_name1 = "anyname";
String certificate_description1 = "anyDesc";
String notes1 = "anyNotes";
RequestBody document_type =
RequestBody.create(
okhttp3.MultipartBody.FORM, document_type1);
RequestBody fk_id =
RequestBody.create(
okhttp3.MultipartBody.FORM, fk_id1);
RequestBody type =
RequestBody.create(
okhttp3.MultipartBody.FORM, type1);
RequestBody certificate_name =
RequestBody.create(
okhttp3.MultipartBody.FORM, certificate_name1);
RequestBody certificate_description =
RequestBody.create(
okhttp3.MultipartBody.FORM, certificate_description1);
RequestBody notes =
RequestBody.create(
okhttp3.MultipartBody.FORM, notes1);
// finally, execute the request
Call<UploadDocuments> call = service.uploadDocuments(
authorization,body,document_type,
fk_id,type,certificate_name,
certificate_description,notes);
call.enqueue(new Callback<UploadDocuments>() {
@Override
public void onResponse(Call<UploadDocuments> call,Response<UploadDocuments> response) {
Log.v("Upload", "successssssssssss");
if(response.isSuccessful()) {
String status = response.body().getMessage();
if (status.equals("success")) {
String name = response.body().getData().getCertificateName();
Toast.makeText(getApplicationContext(),"done " + name,Toast.LENGTH_LONG).show();
}
}
}
@Override
public void onFailure(Call<UploadDocuments> call, Throwable t) {
Log.e("Upload errorrrrrr:", t.getMessage());
}
});
}
Edit:
Also I have additional problem after editing my code as Jeel answer, The problem when I take image capture I get this error:
E/on getPath: edit profile java.lang.IllegalArgumentException: column '_data' does not exist. Available columns: [] at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:340) at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:87) at com.example.android.renteragentapp.API_Utility.FileUtil.getPath(FileUtil.java:65) at com.example.android.renteragentapp.Activity.ScanPassportActivity.uploadFile(ScanPassportActivity.java:195)
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(hasStoragePermission(101)){
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)) {
photoURI = FileProvider.getUriForFile(ScanPassportActivity.this,
"com.example.provider",
photoFile);
//FAApplication.setPhotoUri(photoURI);
} else {
photoURI = Uri.fromFile(photoFile);
}
takePicture.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)
{
takePicture.putExtra("android.intent.extras.LENS_FACING_FRONT", 1);
}
else {
takePicture.putExtra("android.intent.extras.CAMERA_FACING", 1);
}
startActivityForResult(takePicture, 101);
}
}
}
});
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File file = File.createTempFile(
imageFileName, //prefix
".jpg", //suffix
storageDir //directory
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = file.getAbsolutePath();
return file;
}
private boolean hasStoragePermission(int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
return false;
} else if( checkSelfPermission(Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, requestCode);
return false;
}
else {
return true;
}
} else {
return true;
}
}
also I set this provider:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.provider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"
tools:replace="android:resource" />
</provider>