简体   繁体   中英

File path from Uri using ContentResolver

  • Goal : Select a file using Intent
  • Purpose : File Uploading

Question: How do I get file path from a 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

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 . This serves my purpose but

how to get the filePath from content provider instead of using an 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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