我无法将从相机拍摄的照片发送到服务器。我一步一步地跟踪了谷歌关于拍摄照片的文档(https://developer.android.com/training/camera/photobasics),但仍然无法完成这项工作。从设备库上传文件似乎工作正常。此外,如果我录制视频,上传将是成功的。
这是我的活动代码:
wrapper.java.additional.4=-XX:PermSize=1024M
文件提供者:
private static int REQUEST_IMAGE_CAPTURE = 2;
private String mCurrentPhotoPath;
private Uri photoUri;
private List<File> filesArray;
private List<Uri> filesUrisArray;
private List<String> mimeTypesArray;
// Camera Intent
public void takePhoto() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
photoUri = null;
try {
photoFile = createImageFile();
photoUri = FileProvider.getUriForFile(this, "com.company.name.appname.provider", photoFile);
} catch (Exception ex) {
ex.printStackTrace();
}
// Continue only if the File was successfully created
if (photoUri != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 2:
if (resultCode == RESULT_OK) {
try {
galleryAddPic();
filesUrisArray.set(selectedMedia, photoUri);
mimeTypesArray.set(selectedMedia, getContentResolver().getType(photoUri));
} catch (Exception ex) {
ex.printStackTrace();
}
}
break;
}
}
/**
* Add the photo to gallery
*/
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
/**
* Method to create image file name (usado cuando sacas fotos con la cámara)
*/
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "PNG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".png", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
我的Android清单中的文件提供程序配置:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
问题在于,当我尝试准备要发送到服务器的文件时,它会抛出此异常:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.company.name.appname.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
照片的Uri如下所示:content://com.company.name.appname.provider/external_files/Android/data/com.company.name.appname/files/Pictures/PNG_20180516_105223_8084097384330493776.png
这是我的应用程序在调用FileUtils.getFile方法时崩溃的地方:
Caused by: 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.company.name.appname.comun.utils.FileUtils.getDataColumn(FileUtils.java:231)
at com.company.name.appname.comun.utils.FileUtils.getPath(FileUtils.java:329)
at com.company.name.appname.comun.utils.FileUtils.getFile(FileUtils.java:349)
FileUtils类(由方法getDataColumn引起的异常):
@NonNull
private MultipartBody.Part prepareFilePart(String partName, Uri fileUri) {
File file = FileUtils.getFile(this, fileUri);
RequestBody requestFile =
RequestBody.create(
MediaType.parse(getContentResolver().getType(fileUri)),
file
);
return MultipartBody.Part.createFormData(partName, file.getName(), requestFile);
}
答案 0 :(得分:1)
摆脱那种错误的getPath()
方法。 Uri
不必具有文件系统路径,更不用说可以派生的路径了。
更重要的是,您不需要这种方法。 mCurrentPhotoPath
是您创建的文件系统路径。使用它。
您做需要的是在配置更改中保留mCurrentPhotoPath
(或派生信息),例如将其置于已保存的实例状态Bundle
中。有关如何将ACTION_IMAGE_CAPTURE
与EXTRA_OUTPUT
和FileProvider
一起使用的说明,请参阅this sample project,包括处理配置更改。