如何从FileProvider URI获取真实路径?

时间:2017-07-19 09:42:24

标签: java android uri

我有这个代码用于解码content:// URI:

Cursor cursor = null;
try {
    cursor = context.getContentResolver().query(contentUri,
                     new String[] { MediaStore.Files.FileColumns.DATA },
                     null, null, null);

    int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA);
    cursor.moveToFirst();

    return cursor.getString(columnIndex);

} finally {
    if (cursor != null) {cursor.close()};
}

但它不适用于FileProvider URI(例如下载文件的Chrome Dev URI:content://com.chrome.dev.FileProvider/downloads/)。有没有办法获得真正的道路?

4 个答案:

答案 0 :(得分:2)

您可以尝试使用此解决方案从文件提供程序URI获取实际路径。

首先,您需要定义文件提供程序路径文件,如下所示。

  

provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="/storage/emulated/0" path="."/>
</paths>

AndroidMenifest.xml 中声明文件提供程序,如下所示。

  

AndroidMenifest.xml

<application>
    .
    .
    .
    <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
    </provider>
 </application>

现在在活动方面。

  

MyActivity.java

private Uri picUri;

    private void takePhotoFromCamera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (Utils.isNougat()) {
            picUri = FileProvider.getUriForFile(this, getPackageName(), imageHelper
                    .createImageFile());
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        }else {
            picUri = Uri.fromFile(imageHelper.createImageFile());
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, picUri);
        startActivityForResult(intent, Const.ServiceCode.TAKE_PHOTO);
    }


    /**
     * This method is used for handel result after captured image from camera .
    */
    private void onCaptureImageResult() {
        if(Utils.isNougat()){
            documentImage = imageHelper.getRealPathFromURI(picUri.getPath());
        }else {
            documentImage = imageHelper.getRealPathFromURI(picUri);
        }
    }

按照我的方法获取真实路径。

public String getRealPathFromURI(Uri contentURI) {
        String result;
        Cursor cursor = context.getContentResolver().query(contentURI, null,
                null, null, null);

        if (cursor == null) { // Source is Dropbox or other similar local file
            // path
            result = contentURI.getPath();
        } else {
            cursor.moveToFirst();
            try {
                int idx = cursor
                        .getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                result = cursor.getString(idx);
            } catch (Exception e) {
                AppLog.handleException(ImageHelper.class.getName(), e);
                Toast.makeText(context, context.getResources().getString(
                        R.string.error_get_image), Toast.LENGTH_SHORT).show();

                result = "";
            }
            cursor.close();
        }
        return result;
    }

希望你解决问题。

答案 1 :(得分:0)

试试这个:

@TargetApi(19)
 private static String generatePath(Uri uri,Context context){
    String filePath = null;
    if(DocumentsContract.isDocumentUri(context, uri)){
        String wholeID = DocumentsContract.getDocumentId(uri);

        String id = wholeID.split(":")[1];

        String[] column = { MediaStore.Video.Media.DATA };
        String sel = MediaStore.Video.Media._ID + "=?";

        Cursor cursor = context.getContentResolver().
                query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                        column, sel, new String[]{ id }, null);



        int columnIndex = cursor.getColumnIndex(column[0]);

        if (cursor.moveToFirst()) {
            filePath = cursor.getString(columnIndex);
        }

        cursor.close();
    }
    return filePath;
}

答案 2 :(得分:0)

我正在使用它来获取所选文件的完整路径。 Meybe它会帮助你

    final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("application/zip");
    intent.addCategory(Intent.CATEGORY_OPENABLE);

    if (intent.resolveActivity(getPackageManager()) != null) {
        // file browser has been found on the device
        startActivityForResult(Intent.createChooser(intent, "Select File Browser"), SELECT_FILE_REQUEST_CODE);





@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == SELECT_FILE_REQUEST_CODE) {

                final Uri uri = data.getData();

                if (uri.getScheme().equals("file")) {
                    // the direct path to the file has been returned
                    final String path = uri.getPath();
                    final File file = new File(path);
                    mFilePath = path;

                    updateFileInfo(file.getName(), file.length(), mFileType);
                } else if (uri.getScheme().equals("content")) {
                    // an Uri has been returned
                    mFileStreamUri = uri;

                    final Bundle extras = data.getExtras();
                    if (extras != null && extras.containsKey(Intent.EXTRA_STREAM))
                        mFileStreamUri = extras.getParcelable(Intent.EXTRA_STREAM);

                    // file name and size must be obtained from Content Provider
                    final Bundle bundle = new Bundle();
                    bundle.putParcelable(EXTRA_URI, uri);
                    getLoaderManager().restartLoader(SELECT_FILE_REQ, bundle, this);
                }
            }
        }
    }

 @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        final Uri uri = args.getParcelable(EXTRA_URI);

        return new CursorLoader(this, uri, null, null, null, null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        if (data != null && data.moveToNext()) {
            /*
             * Here we have to check the column indexes by name as we have requested for all. The order may be different.
             */
            final String fileName = data.getString(data.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)/* 0 DISPLAY_NAME */);
            final int fileSize = data.getInt(data.getColumnIndex(MediaStore.MediaColumns.SIZE) /* 1 SIZE */);
            String filePath = null;
            final int dataIndex = data.getColumnIndex(MediaStore.MediaColumns.DATA);
            if (dataIndex != -1)
                filePath = data.getString(dataIndex /* 2 DATA */);
            if (!TextUtils.isEmpty(filePath))
                mFilePath = filePath;

            updateFileInfo(fileName, fileSize, mFileType);

答案 3 :(得分:0)

你可以试试这个。从URI

获取真实路径
File file = new File(getRealPathFromURI(selectedImageURI));

方法

private String getRealPathFromURI(Uri contentURI) {
    String result;
    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
    if (cursor == null) { //checking
        result = contentURI.getPath();
    } else { 
        cursor.moveToFirst(); 
        int idx = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA); 
        result = cursor.getString(idx);
        cursor.close();
    }
    return result;
}