Android: Getting A File URI From A Content URI?


Answer :

Just use getContentResolver().openInputStream(uri) to get an InputStream from a URI.

http://developer.android.com/reference/android/content/ContentResolver.html#openInputStream(android.net.Uri)


This is an old answer with deprecated and hacky way of overcoming some specific content resolver pain points. Take it with some huge grains of salt and use the proper openInputStream API if at all possible.

You can use the Content Resolver to get a file:// path from the content:// URI:

String filePath = null; Uri _uri = data.getData(); Log.d("","URI = "+ _uri);                                        if (_uri != null && "content".equals(_uri.getScheme())) {     Cursor cursor = this.getContentResolver().query(_uri, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);     cursor.moveToFirst();        filePath = cursor.getString(0);     cursor.close(); } else {     filePath = _uri.getPath(); } Log.d("","Chosen path = "+ filePath); 

If you have a content Uri with content://com.externalstorage... you can use this method to get absolute path of a folder or file on Android 19 or above.

public static String getPath(final Context context, final Uri uri) {     final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;      // DocumentProvider     if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {         System.out.println("getPath() uri: " + uri.toString());         System.out.println("getPath() uri authority: " + uri.getAuthority());         System.out.println("getPath() uri path: " + uri.getPath());          // ExternalStorageProvider         if ("com.android.externalstorage.documents".equals(uri.getAuthority())) {             final String docId = DocumentsContract.getDocumentId(uri);             final String[] split = docId.split(":");             final String type = split[0];             System.out.println("getPath() docId: " + docId + ", split: " + split.length + ", type: " + type);              // This is for checking Main Memory             if ("primary".equalsIgnoreCase(type)) {                 if (split.length > 1) {                     return Environment.getExternalStorageDirectory() + "/" + split[1] + "/";                 } else {                     return Environment.getExternalStorageDirectory() + "/";                 }                 // This is for checking SD Card             } else {                 return "storage" + "/" + docId.replace(":", "/");             }          }     }     return null; } 

You can check each part of Uri using println. Returned values for my SD card and device main memory are listed below. You can access and delete if file is on memory, but I wasn't able to delete file from SD card using this method, only read or opened image using this absolute path. If you find a solution to delete using this method, please share.

SD CARD

getPath() uri: content://com.android.externalstorage.documents/tree/612E-B7BF%3A/document/612E-B7BF%3A getPath() uri authority: com.android.externalstorage.documents getPath() uri path: /tree/612E-B7BF:/document/612E-B7BF: getPath() docId: 612E-B7BF:, split: 1, type: 612E-B7BF 

MAIN MEMORY

getPath() uri: content://com.android.externalstorage.documents/tree/primary%3A/document/primary%3A getPath() uri authority: com.android.externalstorage.documents getPath() uri path: /tree/primary:/document/primary: getPath() docId: primary:, split: 1, type: primary 

If you wish to get Uri with file:/// after getting path use

DocumentFile documentFile = DocumentFile.fromFile(new File(path)); documentFile.getUri() // will return a Uri with file Uri 

Comments

Popular posts from this blog

Are Regular VACUUM ANALYZE Still Recommended Under 9.1?

Can Feynman Diagrams Be Used To Represent Any Perturbation Theory?