Я работаю над приложением для Android и мне нужно отправить запрос с файлом на сервер.
Я использую retrofit
, чтобы сделать это, и я Multipart
API-запрос.
Затем я использую Intent.createChooser
, чтобы выбрать файл.
Проблема возникает, когда я enqueue
звоню в сервисную службу. В onFailure
я получаю эту ошибку:
E / Загрузить errorrrrrr :: / document / image: 77317 (Нет такого файла или каталога)
Однако, это URI и путь к файлу, который я получаю в onActivityResult
:
URI: content://com.android.providers.media.documents/document/image%3A77317
путь: /document/image:77317
и я поставил разрешения:
<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" />
и это запрос:
@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);
Как я могу решить эту проблему?
и спасибо,
Мой код:
@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:
Кроме того, у меня возникла дополнительная проблема после редактирования кода в качестве ответа Jeel. Проблема, возникающая при захвате изображения, вызывает эту ошибку:
E / on getPath: редактировать профиль
java.lang.IllegalArgumentException: столбец '_data' не существует. Доступные столбцы: []
на android.database.AbstractCursor.getColumnIndexOrThrow (AbstractCursor.java:340)
на android.database.CursorWrapper.getColumnIndexOrThrow (CursorWrapper.java:87)
в com.example.android.renteragentapp.API_Utility.FileUtil.getPath (FileUtil.java:65)
в 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;
}
}
также я установил этого провайдера:
<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>