简体   繁体   English

使用ContentResolver来自Uri的文件路径

[英]File path from Uri using ContentResolver

  • Goal : Select a file using Intent 目标 :使用Intent选择文件
  • Purpose : File Uploading 目的 :文件上传

Question: How do I get file path from a Uri. 问题:如何从Uri获取文件路径。 Note that there is no specific file type. 请注意,没有特定的文件类型。 User can select any file from the list of available file choosers on the device. 用户可以从设备上的可用文件选择器列表中选择任何文件。

What I've coded so far 到目前为止,我已经编码了什么

{
//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

}

Typical Uris returned from Intent are 从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 }

Now I have fileName , MimeType , fileSize & inputStream . 现在我有了fileNameMimeTypefileSizeinputStream This serves my purpose but 这符合我的目的,但是

how to get the filePath from content provider instead of using an inputStream? 如何从内容提供者获取filePath而不是使用inputStream?

You are already using the correct solution. 您已经在使用正确的解决方案。 By obtaining the file path one might try to read the file directly, but because of the sandbox it should fail in most of the cases. 通过获取文件路径,人们可能会尝试直接读取文件,但是由于沙箱的缘故,它在大多数情况下应该会失败。 For example if the file lies in the app directory of another app. 例如,如果文件位于另一个应用程序的应用程序目录中。 By using content providers other apps can grant you read permissions to certain uris which allow you to read a file. 通过使用内容提供程序,其他应用程序可以授予您某些uri的读取权限,从而允许您读取文件。

Also nobody forces you to export file paths when writing a content provider. 同样,没有人会强迫您在编写内容提供程序时导出文件路径。 Internally you have to deal with them, but to the outside only uris matter. 在内部,您必须与它们打交道,但在外部,只有麻烦事。 So as a consumer of the provider you can and should not make any assumptions about the file path. 因此,作为提供者的使用者,您可以也不应对文件路径进行任何假设。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM