无法将照片从相机上传到服务器。 IllegalArgumentException:column' _data'不存在

时间:2018-05-16 11:05:29

标签: java android retrofit2

我无法将从相机拍摄的照片发送到服务器。我一步一步地跟踪了谷歌关于拍摄照片的文档(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);
}   

1 个答案:

答案 0 :(得分:1)

摆脱那种错误的getPath()方法。 Uri不必具有文件系统路径,更不用说可以派生的路径了。

更重要的是,您不需要这种方法。 mCurrentPhotoPath是您创建的文件系统路径。使用它。

需要的是在配置更改中保留mCurrentPhotoPath(或派生信息),例如将其置于已保存的实例状态Bundle中。有关如何将ACTION_IMAGE_CAPTUREEXTRA_OUTPUTFileProvider一起使用的说明,请参阅this sample project,包括处理配置更改。