【问题标题】:File path from Uri using ContentResolver使用 ContentResolver 来自 Uri 的文件路径
【发布时间】:2016-08-11 07:13:31
【问题描述】:
  • 目标:使用 Intent 选择文件
  • 用途:文件上传

问题:如何从 Uri 获取文件路径。请注意,没有 特定的文件类型。用户可以从设备上的可用文件选择器列表中选择任何文件。

到目前为止我编写的代码

{
//File Pick Intent
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        try {
            (context).startActivityForResult(
                    Intent.createChooser(intent, "Select a File to Upload"),
                    PICK_FILE);
        }
        catch (android.content.ActivityNotFoundException ex) {
            Toast.makeText(context, "Please install a File Manager.", Toast.LENGTH_SHORT).show();
        }
}

// On Activity Result
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {

        if (requestCode == PICK_FILE && resultCode == Activity.RESULT_OK) {

            Uri uri = intent.getData();

            String mimeType = getContentResolver().getType(uri);
            Cursor returnCursor = getContentResolver().query(uri,null, null, null, null);

            int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
            int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);

            System.out.println("mime: "+ mimeType);
            System.out.println("name: " + returnCursor.getString(nameIndex));
            System.out.println("size: " + returnCursor.getString(sizeIndex));

            // File Input Stream gets me file data
            InputStream inputStream = getContentResolver().openInputStream(uri);
            // Can create a file using this stream but I am looking for some better dolution that gives me file path instead

}

从 Intent 返回的典型 Uris 是

1. { dat=content://com.google.android.apps.docs.storage/document/acc=1;doc=107 flg=0x1 }
2. { dat=file:///Removable/MicroSD/docs/doccuments.rar flg=0x3 }
3. { dat=content://media/external/audio/media/1110 }
4. { dat=content://com.android.externalstorage.documents/document/primary:.profig.os flg=0x1 }

现在我有了 fileNameMimeTypefileSizeinputStream。这符合我的目的,但是

如何从内容提供者那里获取 filePath 而不是使用 输入流?

【问题讨论】:

  • 你的Uri uri = intent.getData(); 是什么?
  • 对问题进行了编辑。 @pskink
  • 所以只有file://方案的必须是物理文件,其他Uris可以是纯虚拟的:你必须使用InputStream读取它们

标签: android android-intent android-contentresolver


【解决方案1】:

您已经在使用正确的解决方案。通过获取文件路径,人们可能会尝试直接读取文件,但由于沙箱,在大多数情况下它应该会失败。例如,如果该文件位于另一个应用程序的应用程序目录中。通过使用内容提供程序,其他应用可以授予您对某些允许您读取文件的 uri 的读取权限。

在编写内容提供程序时,也没有人强迫您导出文件路径。在内部,您必须与它们打交道,但对外部而言,只有 uris 很重要。因此,作为提供者的消费者,您可以也不应该对文件路径做出任何假设。

【讨论】:

  • 所以,如果我想读取一个文件。我必须使用输入流。有没有办法直接访问文件,把我的一些应用资源保存在这里?
  • 你可以试试。正如您所看到的,您提供的一些 uri 以“内容”开头,而另一些则以“文件”开头。后者可用于创建带有“新文件(uri.getPath)”的文件。但是,是的。如果您想从另一个应用程序上传文件,请将其复制到您应用程序拥有的某个目录或直接从提供程序将文件流式传输到服务器。
  • 好的。非常感谢!我还尝试在 developer.android.com 中搜索一些指南,但找不到有关如何读取文件的任何有用信息。
猜你喜欢
  • 2014-07-31
  • 1970-01-01
  • 1970-01-01
  • 2013-12-09
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多