content: package com.vitanov.multiimagepicker;
  
  import android.annotation.SuppressLint;
  import android.content.ContentUris;
  import android.content.Context;
  import android.database.Cursor;
  import android.net.Uri;
  import android.os.Build;
  import android.os.Environment;
  import android.provider.DocumentsContract;
  import android.provider.MediaStore;
  
  import androidx.loader.content.CursorLoader;
  
  import java.util.Objects;
  
  // https://gist.github.com/tatocaster/32aad15f6e0c50311626
  
  public class FileDirectory {
  
      /**
       * 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.
       *
       * @param context The context.
       * @param uri The Uri to query.
       * @author paulburke
       */
      public static String getPath(final Context context, final Uri uri){
          String _path;
          // SDK < API11
          if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
              _path = getPath_BelowAPI11(context, uri);
          }
          // SDK >= 11 && SDK < 19
          else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
              _path = getPath_API11to18(context, uri);
          }
          // SDK > 19 (Android 4.4) and up
          else {
              _path = getPath_API19(context, uri);
          }
          return _path;
      }
  
      @SuppressLint("NewApi")
      public static String getPath_API19(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)) {
                      if(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){
                          return Environment.getExternalStorageDirectory() + "/" + split[1];
                      }
                      return Objects.requireNonNull(context.getExternalFilesDir(null)).getAbsolutePath() + "/" + split[1];
  
                  }
  
                  // TODO handle non-primary volumes
              }
              // DownloadsProvider
              else if (isDownloadsDocument(uri)) {
  
                  final String id = DocumentsContract.getDocumentId(uri);
                  final Uri contentUri = ContentUris.withAppendedId(
                          Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
  
                  return getDataColumn(context, contentUri, null, 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 getDataColumn(context, uri, null, null);
          }
          // File
          else if ("file".equalsIgnoreCase(uri.getScheme())) {
              return uri.getPath();
          }
  
          return null;
      }
  
      @SuppressLint("NewApi")
      public static String getPath_API11to18(Context context, Uri contentUri) {
          String[] proj = {MediaStore.Images.Media.DATA};
          String result = null;
  
          CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null);
          Cursor cursor = cursorLoader.loadInBackground();
  
          if (cursor != null) {
              int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
              cursor.moveToFirst();
              result = cursor.getString(column_index);
              cursor.close();
          }
          return result;
      }
  
      public static String getPath_BelowAPI11(final Context context, final Uri contentUri) {
          String[] proj = {MediaStore.Images.Media.DATA};
          Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
          int column_index = 0;
          String result = "";
          if (cursor != null) {
              column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
              cursor.moveToFirst();
              result = cursor.getString(column_index);
              cursor.close();
              return result;
          }
          return result;
      }
  
      /**
       * Get the value of the data column for this Uri. This is useful for
       * MediaStore Uris, and other file-based ContentProviders.
       *
       * @param context The context.
       * @param uri The Uri to query.
       * @param selection (Optional) Filter used in the query.
       * @param selectionArgs (Optional) Selection arguments used in the query.
       * @return The value of the _data column, which is typically a file path.
       */
      private static String getDataColumn(Context context, Uri uri, String selection,
                                          String[] selectionArgs) {
  
          final String column = "_data";
          Cursor cursor = null;
          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 static 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 static 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 static boolean isMediaDocument(Uri uri) {
          return "com.android.providers.media.documents".equals(uri.getAuthority());
      }
  }