1
\$\begingroup\$

I am using below code to get a video file path from uri.

Need review for the following:

1.Code optimization

2.Crash(Code is working fine in the devices I tested but i need to make sure that it doesn't crashes in any case)

3.Performance

4.Overall code review

 /**
 * Get a file path from a Uri. This will get the the path for Storage Access
 * Framework Documents, as well as the _data field for the MediaStore and
 * other file-based ContentProviders.
 */
 private 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)) {
 // ExternalStorageProvider
 if (isExternalStorageDocument(uri)) {
 final String docId = DocumentsContract.getDocumentId(uri);
 final String[] split = docId.split(":");
 final String type = split[0];
 if ("primary".equalsIgnoreCase(type)) {
 return Environment.getExternalStorageDirectory() + "/" + split[1];
 } else {
 // Below logic is how External Storage provider build URI for documents
 // Based on http://stackoverflow.com/questions/28605278/android-5-sd-card-label and https://gist.github.com/prasad321/9852037
 StorageManager mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
 try {
 Class<?> storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
 Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
 Method getUuid = storageVolumeClazz.getMethod("getUuid");
 Method getState = storageVolumeClazz.getMethod("getState");
 Method getPath = storageVolumeClazz.getMethod("getPath");
 Method isPrimary = storageVolumeClazz.getMethod("isPrimary");
 Method isEmulated = storageVolumeClazz.getMethod("isEmulated");
 Object result = getVolumeList.invoke(mStorageManager);
 final int length = Array.getLength(result);
 for (int i = 0; i < length; i++) {
 Object storageVolumeElement = Array.get(result, i);
 //String uuid = (String) getUuid.invoke(storageVolumeElement);
 final boolean mounted = Environment.MEDIA_MOUNTED.equals(getState.invoke(storageVolumeElement))
 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(getState.invoke(storageVolumeElement));
 //if the media is not mounted, we need not get the volume details
 if (!mounted) continue;
 //Primary storage is already handled.
 if ((Boolean) isPrimary.invoke(storageVolumeElement) && (Boolean) isEmulated.invoke(storageVolumeElement))
 continue;
 String uuid = (String) getUuid.invoke(storageVolumeElement);
 if (uuid != null && uuid.equals(type)) {
 String res = getPath.invoke(storageVolumeElement) + "/" + split[1];
 return res;
 }
 }
 } catch (Exception ex) {
 }
 }
 }
 // DownloadsProvider
 else if (isDownloadsDocument(uri)) {
 final String id = DocumentsContract.getDocumentId(uri);
 if (!TextUtils.isEmpty(id)) {
 if (id.startsWith("raw:")) {
 return id.replaceFirst("raw:", "");
 }
 }
 String[] contentUriPrefixesToTry = new String[]{
 "content://downloads/public_downloads",
 "content://downloads/my_downloads",
 "content://downloads/all_downloads"
 };
 for (String contentUriPrefix : contentUriPrefixesToTry) {
 Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
 try {
 String path = getDataColumn(context, contentUri, null, null);
 if (path != null) {
 return path;
 }
 } catch (Exception e) {}
 }
 return null;
 }
 // MediaProvider
 else if (isMediaDocument(uri)) {
 final String docId = DocumentsContract.getDocumentId(uri);
 final String[] split = docId.split(":");
 final String type = split[0];
 Uri contentUri = null;
 if ("image".equals(type)) {
 contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
 } else if ("video".equals(type)) {
 contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
 } else if ("audio".equals(type)) {
 contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
 }
 final String selection = "_id=?";
 final String[] selectionArgs = new String[]{
 split[1]
 };
 return getDataColumn(context, contentUri, selection, selectionArgs);
 }
 }
 // MediaStore (and general)
 else if ("content".equalsIgnoreCase(uri.getScheme())) {
// // Return the remote address
 if (isGooglePhotosUri(uri))
 return uri.getLastPathSegment();
 return getDataColumn(context, uri, null, null);
 }
 // File
 else if ("file".equalsIgnoreCase(uri.getScheme())) {
 return uri.getPath();
 }
 return null;
 }
 public static boolean isGooglePhotosUri(Uri uri) {
 return "com.google.android.apps.photos.content".equals(uri.getAuthority());
 }
 /**
 * Get the value of the data column for this Uri.
 */
 private String getDataColumn(Context context, Uri uri, String selection,
 String[] selectionArgs) {
 Cursor cursor = null;
 final String column = "_data";
 final String[] projection = {
 column
 };
 try {
 cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
 null);
 if (cursor != null && cursor.moveToFirst()) {
 final int column_index = cursor.getColumnIndexOrThrow(column);
 return cursor.getString(column_index);
 }
 } finally {
 if (cursor != null)
 cursor.close();
 }
 return null;
 }
 /**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
 private boolean isExternalStorageDocument(Uri uri) {
 return "com.android.externalstorage.documents".equals(uri.getAuthority());
 }
 /**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
 private boolean isDownloadsDocument(Uri uri) {
 return "com.android.providers.downloads.documents".equals(uri.getAuthority());
 }
 /**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
 private boolean isMediaDocument(Uri uri) {
 return "com.android.providers.media.documents".equals(uri.getAuthority());
 }
asked Dec 2, 2018 at 11:45
\$\endgroup\$
3
  • \$\begingroup\$ What do you mean crash? \$\endgroup\$ Commented Dec 2, 2018 at 11:47
  • \$\begingroup\$ @πάνταῥεῖ to make sure code will not crash,,, \$\endgroup\$ Commented Dec 2, 2018 at 11:48
  • \$\begingroup\$ The getPath() function is overly large, decompose it into smaller private functions, I would do this at each if statement. \$\endgroup\$ Commented Dec 2, 2018 at 13:18

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.