来自Uri的文件路径使用ContentResolver

时间:2016-08-11 07:13:31

标签: android android-intent android-contentresolver

  • 目标:使用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 }

现在我有 fileName MimeType fileSize &的的inputStream 即可。这符合我的目的,但

  

如何从内容提供商处获取 filePath ,而不是使用   的InputStream?

1 个答案:

答案 0 :(得分:2)

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

在编写内容提供程序时,也没有人强迫您导出文件路径。在内部你必须处理它们,但对外面只有uris很重要。因此,作为提供者的使用者,您可以而且不应该对文件路径做出任何假设。