android - 获取操作 GET_CONTENT 的文件路径

标签 android file uri

我知道我问的问题已经被问了很多次了,但我已经尝试了他们的很多答案。

我开发了以下用于获取 pdf 文件的代码,并且完美设置了 PROVIDER。

Intent intent = new Intent();
intent.setType("application/pdf");
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, PICKFILE_REQUEST_CODE);

但是一旦我将获取onActivityResult上的数据,然后尝试获取文件路径。

所以在某些情况下,我得到了正确的文件路径。但在三星设备中,我得到的 URI 为 content://file-content/number。因此,由于这种类型的 URI,方法无法将该 URI 转换为文件路径。

这是我将 URI 转换为 localPath 的方法

private static String getRealPath(ContentResolver contentResolver, Uri uri, String whereClause) {
        String localPath = "";

        // Query the URI with the condition.
        Cursor cursor = contentResolver.query(uri, null, whereClause, null, null);

        if (cursor != null) {
            boolean moveToFirst = cursor.moveToFirst();
            if (moveToFirst) {

                // Get column name by URI type.
                String columnName = MediaStore.Images.Media.DATA;

                if (uri == MediaStore.Images.Media.EXTERNAL_CONTENT_URI) {
                    columnName = MediaStore.Images.Media.DATA;
                } else if (uri == MediaStore.Audio.Media.EXTERNAL_CONTENT_URI) {
                    columnName = MediaStore.Audio.Media.DATA;
                } else if (uri == MediaStore.Video.Media.EXTERNAL_CONTENT_URI) {
                    columnName = MediaStore.Video.Media.DATA;
                }

                // Get column index.
                int columnIndex = cursor.getColumnIndex(columnName);

                // Get column value which is the uri related file local path.
                localPath = cursor.getString(columnIndex);
            }
        }

        return localPath;
    }

所以我对这个问题有两个问题:

  1. 我想获取 URI 的列名称,但当用户从云端硬盘的文件中选择文件时无法获取哪种类型的 URI。

    即:在我的方法中,我无法比较 uri == MediaStore.Image.Media.EXTERNAL_CONTENT_URI。

  2. 如何将 content://file-content/number uri 转换为文件路径。

提前致谢。

最佳答案

I want to get column name for uri but Not getting which type of URI when user select file from Drive's file.

使用此代码检查 URI 的方案:

if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
    // Content scheme        
} else if (uri.getScheme().equals(ContentResolver.SCHEME_FILE)){
   // File scheme    
} else {
   // Other
}

How can convert content://file-content/number uri to file path.

创建临时文件:

@Nullable
private File createTempUploadFile(String fileName) {
    File storageDir = new File(getActivity().getExternalFilesDir(null), "Upload");
    if (storageDir.exists()) {
        File[] files = storageDir.listFiles();
        for (File file : files) {
            file.delete();
        }
    } else {
        if (!storageDir.mkdirs()) {
            return null;
        }
    }

    File file = new File(storageDir.getPath() + File.separator + fileName);
    mCurrentFilePath = "file:" + file.getAbsolutePath();
    return file;
}

编写一个 util 方法以从输入流复制到文件

public static boolean copyFileFromInputStream(InputStream inputStream, File dest) {
    OutputStream outputStream = null;
    try {
        outputStream = new FileOutputStream(dest);
        final byte[] buffer = new byte[64 * 1024]; // 64KB
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
        return true;
    } catch (IOException e) {
        Timber.e(e);
        return false;
    } finally {
        try {
            if (inputStream != null) {
                inputStream.close();
            }

            if (outputStream != null) {
                outputStream.close();
            }
        } catch (IOException e) {
            // Do nothing.
        }
    }
}

将 URI 中的内容复制到 onActivityResult 中的临时文件

try {
    File dest = createTempUploadFile(fileName);
    if (dest != null) {
        InputStream inputStream =
                getActivity().getContentResolver().openInputStream(uri);
        Utils.copyFileFromInputStream(inputStream, dest);
    }
} catch (Exception e) {
    // TODO
}

现在从临时文件中获取文件路径。

更新:如果您想从 URI 获取文件名,请在 onActivityResult 中使用此代码。

Cursor cursor = null;
try {
    cursor = getActivity().getContentResolver().query(uri,
            null,
            null,
            null,
            null);

    if (cursor != null && cursor.moveToFirst()) {
        int displayNameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
        String fileName = cursor.getString(displayNameIndex);
    }  
} finally {
    if (cursor != null) {
        cursor.close();
    }
}

关于android - 获取操作 GET_CONTENT 的文件路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52290192/

相关文章:

android - 具有以下 fragment 边缘 View 的应用栏

android - 忽略 Alpha 并覆盖目标的 Porter Duff 模式

android - 使用 android 媒体播放器进行渐进式视频下载

c - 从文件读入数组并使用数组中的数字执行操作

java - 使用 java 8 Stream 将字符串映射

android - 使用存储访问框架请求访问文件夹时,Intent.FLAG_GRANT_PREFIX_URI_PERMISSION 有什么用?

ansible - 如何检查ansible playbook中的状态代码

java - Android Studio 的构建、清理问题

c - 我是否错误地使用了 fscanf?

Java 文件 URI 错误?