iPaulPro / aFileChooser

[DEPRECATED] Android library that provides a file explorer to let users select files on external storage.
Apache License 2.0
1.79k stars 850 forks source link

Can not get file path from FileProvider URI #85

Open NaikSoftware opened 7 years ago

NaikSoftware commented 7 years ago

Uri generated with FileProvider not contain _data column https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java#L233

iad24 commented 6 years ago

Hi @NaikSoftware . Were u able to solve this? I got stuck on this one =/

nicolabeghin commented 6 years ago

any news on this?

GersonSales commented 6 years ago

Any news? I've got the same issue.

nicolabeghin commented 6 years ago

I ended up applied a quick-n-dirty fix:

FileUtils.java

public static boolean isCloudFile(Uri uri) {
    return "content".equalsIgnoreCase(uri.getScheme());
}

then in my app

if (FileUtils.isCloudFile(uri)) {
    path = handleRemoteFile(uri);
}

where handleRemoteFile(final Uri uri) is

private String handleRemoteFile(final Uri uri) throws IOException {
    Cursor cursor = getContentResolver().query(uri, null, null, null, null);
    int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
    cursor.moveToFirst();
    String filename = cursor.getString(nameIndex);
    long filesize = cursor.getLong(sizeIndex);
    InputStream is = getContentResolver().openInputStream(uri);
    File downloadedCloudFile = new File(downloads_folder, filename);
    if (downloadedCloudFile.exists()) {
        downloadedCloudFile.delete();
    }
    FileOutputStream out = new FileOutputStream(downloadedCloudFile);
    IOUtils.copy(is, out);
    return downloadedCloudFile.getAbsolutePath();
}
GersonSales commented 6 years ago

Thanks, but doesn't work for me. I have the folowing problem:

I have to caputure an image from camera, so I'm doing this:

MediaCatchActivity.java

@OnClick(R.id.sendPhoto_button)
public void sendPhotoButton(View view) {
    Intent imageCaptureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    mMediaUri = Util.getImageUri(this);
    imageCaptureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mMediaUri);
    imageCaptureIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    if (imageCaptureIntent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(imageCaptureIntent, IMAGE_CAPTURE);
    }
}

Util.java


public static Uri getImageUri(Context context) {
    File imageFile = createImageFile(context);
    if (imageFile != null) {
        return FileProvider.getUriForFile(context, AUTHORITY, imageFile);
    }
    return null;
}

public static File createImageFile(Context context) {
    return createImageFile(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "jpg");
}

static File createMediaFile(File storageDirectory, String extension)  {
    // Create an mediaFile file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String fileName = extension.toUpperCase() + "_" + timeStamp + "_";
    File mediaFile = null;
    try {
        mediaFile = File.createTempFile(
         fileName,  /* prefix */
        "." + extension, /* suffix */
        storageDirectory /* directory */
        );
    } catch (IOException e) {
            e.printStackTrace();
    }

    // Save a file: path for use with ACTION_VIEW intents
    //mCurrentPhotoPath = mediaFile.getAbsolutePath();
    return mediaFile;
}

And this is me trying to get real path from uri

public static String getRealPathFromURI(Context context, Uri contentUri) {
    Cursor cursor = null;
     try {
        String[] proj = { MediaStore.Images.Media.DATA };
        cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

AndroidManifest.xml

...
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.capture.image"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
...
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="images" path="Android/data/com.capture.image/files/Pictures" />
</paths>

Error

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent {  }} to activity {com.com.capture.image/com.capture.image.MediaCatchActivity}: java.lang.IllegalArgumentException: column '_data' does not exist. Available columns: []
nicolabeghin commented 6 years ago

I suggest to take a look at https://github.com/ArthurHub/Android-Image-Cropper or just use it as a full handle-photo-capture library. Implementing photo capture and upload from scratch is pretty hard due to android manufacturers different implementations.