首页 文章

如何从URI获取完整文件路径

提问于
浏览
62

我想从URI获取完整的文件路径 . URI不是图像,但它是一个音乐文件,但如果我像MediaStore解决方案一样,如果应用程序用户选择例如Astro作为浏览器而不是音乐播放器,它将无法工作 . 我该如何解决这个问题?

10 回答

  • 77

    使用:

    String path = yourAndroidURI.uri.getPath() // "/mnt/sdcard/FileName.mp3"
    File file = new File(new URI(path));
    

    要么

    String path = yourAndroidURI.uri.toString() // "file:///mnt/sdcard/FileName.mp3"
    File file = new File(new URI(path));
    
  • 49

    PathUtil方法只能在下面的oreo中工作,如果它是oreo而不是它可能会崩溃,因为在oreo中我们不会得到id而是data.getData()中的整个路径所以你需要做的就是创建一个文件来自uri并从getPath()获取其路径并拆分它 . 下面是工作代码: -

    Uri uri = data.getData(); 
    File file = new File(uri.getPath());//create path from uri
    final String[] split = file.getPath().split(":");//split the path.
    filePath = split[1];//assign it to a string(your choice).
    

    上面的代码将在oreo中运行,如果它低于oreo,则PathUtil将起作用 . 谢谢!

    String filePath=PathUtil.getPath(context,yourURI);
    

    PathUtil.java

    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 java.net.URISyntaxException;
    
    /**
     * Created by Aki on 1/7/2017.
     */
    
    public class PathUtil {
        /*
         * Gets the file path of the given Uri.
         */
        @SuppressLint("NewApi")
        public static String getPath(Context context, Uri uri) throws URISyntaxException {
            final boolean needToCheckUri = Build.VERSION.SDK_INT >= 19;
            String selection = null;
            String[] selectionArgs = null;
            // Uri is different in versions after KITKAT (Android 4.4), we need to
            // deal with different Uris.
            if (needToCheckUri && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
                if (isExternalStorageDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                } else if (isDownloadsDocument(uri)) {
                    final String id = DocumentsContract.getDocumentId(uri);
                    uri = ContentUris.withAppendedId(
                            Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                } else if (isMediaDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    if ("image".equals(type)) {
                        uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(type)) {
                        uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(type)) {
                        uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }
                    selection = "_id=?";
                    selectionArgs = new String[]{ split[1] };
                }
            }
            if ("content".equalsIgnoreCase(uri.getScheme())) {
                String[] projection = { MediaStore.Images.Media.DATA };
                Cursor cursor = null;
                try {
                    cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
                    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    if (cursor.moveToFirst()) {
                        return cursor.getString(column_index);
                    }
                } catch (Exception e) {
                }
            } else if ("file".equalsIgnoreCase(uri.getScheme())) {
                return uri.getPath();
            }
            return null;
        }
    
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is ExternalStorageProvider.
         */
        public 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.
         */
        public 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.
         */
        public static boolean isMediaDocument(Uri uri) {
            return "com.android.providers.media.documents".equals(uri.getAuthority());
        }
    }
    
  • 5

    试试这个 .

    public String getRealPathFromURI(Uri contentUri) 
    {
         String[] proj = { MediaStore.Audio.Media.DATA };
         Cursor cursor = managedQuery(contentUri, proj, null, null, null);
         int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
         cursor.moveToFirst();
         return cursor.getString(column_index);
    }
    
  • -19

    You can use get File path from diffrent SDk versions

    使用RealPathUtils

    public class RealPathUtils {
    
    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API19(Context context, Uri uri){
        String filePath = "";
        String wholeID = DocumentsContract.getDocumentId(uri);
    
        // Split at colon, use second item in the array
        String id = wholeID.split(":")[1];
    
        String[] column = { MediaStore.Images.Media.DATA };
    
        // where id is equal to
        String sel = MediaStore.Images.Media._ID + "=?";
    
        Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                column, sel, new String[]{ id }, null);
    
        int columnIndex = cursor.getColumnIndex(column[0]);
    
        if (cursor.moveToFirst()) {
            filePath = cursor.getString(columnIndex);
        }
        cursor.close();
        return filePath;
    }
    
    
    @SuppressLint("NewApi")
    public static String getRealPathFromURI_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);
        }
        return result;
    }
    
    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){
        String[] proj = { MediaStore.Images.Media.DATA };
        Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
        int column_index
                = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
    }
    

    现在从URI获取文件路径

    String path = null;
                    if (Build.VERSION.SDK_INT < 11)
                        path = RealPathUtils.getRealPathFromURI_BelowAPI11(MainActivity.this, uri);
    
                        // SDK >= 11 && SDK < 19
                    else if (Build.VERSION.SDK_INT < 19)
                        path = RealPathUtils.getRealPathFromURI_API11to18(MainActivity.this, uri);
    
                        // SDK > 19 (Android 4.4)
                    else
                        path = RealPathUtils.getRealPathFromURI_API19(MainActivity.this, uri);
                    Log.d(TAG, "File Path: " + path);
                    // Get the file instance
                     File file = new File(path);
    
  • 4
    package com.utils;
    
    import android.annotation.SuppressLint;
    import android.content.ContentResolver;
    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 android.support.annotation.RequiresApi;
    import android.text.TextUtils;
    import android.util.Log;
    
    import org.apache.commons.io.IOUtils;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    public class FileUtils {
    
        /* Get uri related content real local file path. */
        public static String getPath(Context ctx, Uri uri) {
            String ret;
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    // Android OS above sdk version 19.
                    ret = getUriRealPathAboveKitkat(ctx, uri);
                } else {
                    // Android OS below sdk version 19
                    ret = getRealPath(ctx.getContentResolver(), uri, null);
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.d("DREG", "FilePath Catch: " + e);
                ret = getFilePathFromURI(ctx, uri);
            }
            return ret;
        }
    
        private static String getFilePathFromURI(Context context, Uri contentUri) {
            //copy file and send new file path
            String fileName = getFileName(contentUri);
            if (!TextUtils.isEmpty(fileName)) {
                String TEMP_DIR_PATH = Environment.getExternalStorageDirectory().getPath();
                File copyFile = new File(TEMP_DIR_PATH + File.separator + fileName);
                Log.d("DREG", "FilePath copyFile: " + copyFile);
                copy(context, contentUri, copyFile);
                return copyFile.getAbsolutePath();
            }
            return null;
        }
    
        public static String getFileName(Uri uri) {
            if (uri == null) return null;
            String fileName = null;
            String path = uri.getPath();
            int cut = path.lastIndexOf('/');
            if (cut != -1) {
                fileName = path.substring(cut + 1);
            }
            return fileName;
        }
    
        public static void copy(Context context, Uri srcUri, File dstFile) {
            try {
                InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
                if (inputStream == null) return;
                OutputStream outputStream = new FileOutputStream(dstFile);
                IOUtils.copy(inputStream, outputStream); // org.apache.commons.io
                inputStream.close();
                outputStream.close();
            } catch (Exception e) { // IOException
                e.printStackTrace();
            }
        }
    
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        private static String getUriRealPathAboveKitkat(Context ctx, Uri uri) {
            String ret = "";
    
            if (ctx != null && uri != null) {
    
                if (isContentUri(uri)) {
                    if (isGooglePhotoDoc(uri.getAuthority())) {
                        ret = uri.getLastPathSegment();
                    } else {
                        ret = getRealPath(ctx.getContentResolver(), uri, null);
                    }
                } else if (isFileUri(uri)) {
                    ret = uri.getPath();
                } else if (isDocumentUri(ctx, uri)) {
    
                    // Get uri related document id.
                    String documentId = DocumentsContract.getDocumentId(uri);
    
                    // Get uri authority.
                    String uriAuthority = uri.getAuthority();
    
                    if (isMediaDoc(uriAuthority)) {
                        String idArr[] = documentId.split(":");
                        if (idArr.length == 2) {
                            // First item is document type.
                            String docType = idArr[0];
    
                            // Second item is document real id.
                            String realDocId = idArr[1];
    
                            // Get content uri by document type.
                            Uri mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                            if ("image".equals(docType)) {
                                mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                            } else if ("video".equals(docType)) {
                                mediaContentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                            } else if ("audio".equals(docType)) {
                                mediaContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                            }
    
                            // Get where clause with real document id.
                            String whereClause = MediaStore.Images.Media._ID + " = " + realDocId;
    
                            ret = getRealPath(ctx.getContentResolver(), mediaContentUri, whereClause);
                        }
    
                    } else if (isDownloadDoc(uriAuthority)) {
                        // Build download uri.
                        Uri downloadUri = Uri.parse("content://downloads/public_downloads");
    
                        // Append download document id at uri end.
                        Uri downloadUriAppendId = ContentUris.withAppendedId(downloadUri, Long.valueOf(documentId));
    
                        ret = getRealPath(ctx.getContentResolver(), downloadUriAppendId, null);
    
                    } else if (isExternalStoreDoc(uriAuthority)) {
                        String idArr[] = documentId.split(":");
                        if (idArr.length == 2) {
                            String type = idArr[0];
                            String realDocId = idArr[1];
    
                            if ("primary".equalsIgnoreCase(type)) {
                                ret = Environment.getExternalStorageDirectory() + "/" + realDocId;
                            }
                        }
                    }
                }
            }
    
            return ret;
        }
    
        /* Check whether this uri represent a document or not. */
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        private static boolean isDocumentUri(Context ctx, Uri uri) {
            boolean ret = false;
            if (ctx != null && uri != null) {
                ret = DocumentsContract.isDocumentUri(ctx, uri);
            }
            return ret;
        }
    
        /* Check whether this uri is a content uri or not.
         *  content uri like content://media/external/images/media/1302716
         *  */
        private static boolean isContentUri(Uri uri) {
            boolean ret = false;
            if (uri != null) {
                String uriSchema = uri.getScheme();
                if ("content".equalsIgnoreCase(uriSchema)) {
                    ret = true;
                }
            }
            return ret;
        }
    
        /* Check whether this uri is a file uri or not.
         *  file uri like file:///storage/41B7-12F1/DCIM/Camera/IMG_20180211_095139.jpg
         * */
        private static boolean isFileUri(Uri uri) {
            boolean ret = false;
            if (uri != null) {
                String uriSchema = uri.getScheme();
                if ("file".equalsIgnoreCase(uriSchema)) {
                    ret = true;
                }
            }
            return ret;
        }
    
        /* Check whether this document is provided by ExternalStorageProvider. */
        private static boolean isExternalStoreDoc(String uriAuthority) {
            boolean ret = false;
    
            if ("com.android.externalstorage.documents".equals(uriAuthority)) {
                ret = true;
            }
    
            return ret;
        }
    
        /* Check whether this document is provided by DownloadsProvider. */
        private static boolean isDownloadDoc(String uriAuthority) {
            boolean ret = false;
    
            if ("com.android.providers.downloads.documents".equals(uriAuthority)) {
                ret = true;
            }
    
            return ret;
        }
    
        /* Check whether this document is provided by MediaProvider. */
        private static boolean isMediaDoc(String uriAuthority) {
            boolean ret = false;
    
            if ("com.android.providers.media.documents".equals(uriAuthority)) {
                ret = true;
            }
    
            return ret;
        }
    
        /* Check whether this document is provided by google photos. */
        private static boolean isGooglePhotoDoc(String uriAuthority) {
            boolean ret = false;
    
            if ("com.google.android.apps.photos.content".equals(uriAuthority)) {
                ret = true;
            }
    
            return ret;
        }
    
        /* Return uri represented document file real local path.*/
        @SuppressLint("Recycle")
        private static String getRealPath(ContentResolver contentResolver, Uri uri, String whereClause) {
            String ret = "";
    
            // Query the uri with condition.
            Cursor cursor = contentResolver.query(uri, null, whereClause, null, null);
    
            if (cursor != null) {
                boolean moveToFirst = cursor.moveToFirst();
                if (moveToFirst) {
    
                    // Get columns name by uri type.
                    String columnName = MediaStore.Images.Media.DATA;
    
                    if (uri == MediaStore.Images.Media.EXTERNAL_CONTENT_URI) {
                        columnName = MediaStore.Images.Media.DATA;
                    } else if (uri == MediaStore.Audio.Media.EXTERNAL_CONTENT_URI) {
                        columnName = MediaStore.Audio.Media.DATA;
                    } else if (uri == MediaStore.Video.Media.EXTERNAL_CONTENT_URI) {
                        columnName = MediaStore.Video.Media.DATA;
                    }
    
                    // Get column index.
                    int columnIndex = cursor.getColumnIndex(columnName);
    
                    // Get column value which is the uri related file local path.
                    ret = cursor.getString(columnIndex);
                }
            }
    
            return ret;
        }
    
    }
    

    现在从您的主类中调用 FileUtils.getPath(context, uri); .

  • 14

    我知道这已经得到了解答 . 但是我在评论中发现了一些问题 . 我发现了一个非常可靠的解决方案,从here分叉

    to use it File file=FileUtils.getFile(uri);

    public class FileUtils {
    
    //replace this with your authority
    public static final String AUTHORITY = "com.ianhanniballake.localstorage.documents";
    
    
    private FileUtils() {
    } //private constructor to enforce Singleton pattern
    
    /**
     * TAG for log messages.
     */
    static final String TAG = "FileUtils";
    private static final boolean DEBUG = false; // Set to true to enable logging
    
    
    /**
     * @return Whether the URI is a local one.
     */
    public static boolean isLocal(String url) {
        if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) {
            return true;
        }
        return false;
    }
    
    
    public static boolean isLocalStorageDocument(Uri uri) {
        return AUTHORITY.equals(uri.getAuthority());
    }
    
    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     * @author paulburke
     */
    public 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.
     * @author paulburke
     */
    public 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.
     * @author paulburke
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }
    
    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    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. 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.
     * @author paulburke
     */
    public static 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()) {
                if (DEBUG)
                    DatabaseUtils.dumpCursor(cursor);
    
                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }
    
    /**
     * 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.<br>
     * <br>
     * Callers should check whether the path is local before assuming it
     * represents a local file.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     * @author paulburke
     * @see #isLocal(String)
     * @see #getFile(Context, Uri)
     */
    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)) {
            // LocalStorageProvider
            if (isLocalStorageDocument(uri)) {
                // The path is the id
                return DocumentsContract.getDocumentId(uri);
            }
            // ExternalStorageProvider
            else 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];
                }
    
                // 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 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;
    }
    
    /**
     * Convert Uri into File, if possible.
     *
     * @return file A local file that the Uri was pointing to, or null if the
     * Uri is unsupported or pointed to a remote resource.
     * @author paulburke
     * @see #getPath(Context, Uri)
     */
    public static File getFile(Context context, Uri uri) {
        if (uri != null) {
            String path = getPath(context, uri);
            if (path != null && isLocal(path)) {
                return new File(path);
            }
        }
        return null;
      }
    
    
    }
    
  • 20

    收到文件路径时的代码段代码 .

    Uri fileUri = data.getData();
     FilePathHelper filePathHelper = new FilePathHelper();
     String path = "";
     if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
           if (filePathHelper.getPathnew(fileUri, this) != null) {
                  path = filePathHelper.getPathnew(fileUri, this).toLowerCase();
           } else {
                  path = filePathHelper.getFilePathFromURI(fileUri, this).toLowerCase();
           }
     } else {
           path = filePathHelper.getPath(fileUri, this).toLowerCase();
     }
    

    Bellow是一个可以通过创建新对象来访问的类 . 你还需要在grade1中添加一个依赖项 implementation 'org.apache.directory.studio:org.apache.commons.io:2.4'

    public class FilePathHelper {
    
        public FilePathHelper(){
    
        }
    
        public String getMimeType(String url) {
            String type = null;
            String extension = MimeTypeMap.getFileExtensionFromUrl(url.replace(" ", ""));
            if (extension != null) {
                type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
            }
            return type;
        }
    
        public String getFilePathFromURI(Uri contentUri, Context context) {
            //copy file and send new file path
            String fileName = getFileName(contentUri);
            if (!TextUtils.isEmpty(fileName)) {
                File copyFile = new File(context.getExternalCacheDir() + File.separator + fileName);
                copy(context, contentUri, copyFile);
                return copyFile.getAbsolutePath();
            }
            return null;
        }
    
        public void copy(Context context, Uri srcUri, File dstFile) {
            try {
                InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
                if (inputStream == null) return;
                OutputStream outputStream = new FileOutputStream(dstFile);
                IOUtils.copy(inputStream, outputStream);
                inputStream.close();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public String getPath(Uri uri, Context context) {
            String filePath = null;
            final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
            if (isKitKat) {
                filePath = generateFromKitkat(uri, context);
            }
    
            if (filePath != null) {
                return filePath;
            }
    
            Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DATA}, null, null, null);
    
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
                    filePath = cursor.getString(columnIndex);
                }
                cursor.close();
            }
            return filePath == null ? uri.getPath() : filePath;
        }
    
        @TargetApi(19)
        private String generateFromKitkat(Uri uri, Context context) {
            String filePath = null;
            if (DocumentsContract.isDocumentUri(context, uri)) {
                String wholeID = DocumentsContract.getDocumentId(uri);
    
                String id = wholeID.split(":")[1];
    
                String[] column = {MediaStore.Video.Media.DATA};
                String sel = MediaStore.Video.Media._ID + "=?";
    
                Cursor cursor = context.getContentResolver().
                        query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                                column, sel, new String[]{id}, null);
    
    
                int columnIndex = cursor.getColumnIndex(column[0]);
    
                if (cursor.moveToFirst()) {
                    filePath = cursor.getString(columnIndex);
                }
    
                cursor.close();
            }
            return filePath;
        }
    
        public String getFileName(Uri uri) {
            if (uri == null) return null;
            String fileName = null;
            String path = uri.getPath();
            int cut = path.lastIndexOf('/');
            if (cut != -1) {
                fileName = path.substring(cut + 1);
            }
            return fileName;
        }
    
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        public String getPathnew(Uri uri, Context context) {
            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];
                    }
                    // 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 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 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 index = cursor.getColumnIndexOrThrow(column);
                    return cursor.getString(index);
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("Something with exception - " + e.toString());
            } finally {
                if (cursor != null)
                    cursor.close();
            }
            return null;
        }
    
        public 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.
         */
        public 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.
         */
        public boolean isMediaDocument(Uri uri) {
            return "com.android.providers.media.documents".equals(uri.getAuthority());
        }
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is Google Photos.
         */
        public boolean isGooglePhotosUri(Uri uri) {
            return "com.google.android.apps.photos.content".equals(uri.getAuthority());
        }
    }
    
  • 0

    我很难在Xamarin上解决这个问题 . 从上面的建议我想出了这个解决方案 .

    private string getRealPathFromURI(Android.Net.Uri contentUri)
    {
        string filename = "";
        string thepath = "";
        Android.Net.Uri filePathUri;
        ICursor cursor = this.ContentResolver.Query(contentUri, null, null, null, null);
    
        if (cursor.MoveToFirst())
        {
            int column_index = cursor.GetColumnIndex(MediaStore.Images.Media.InterfaceConsts.Data);//Instead of "MediaStore.Images.Media.DATA" can be used "_data"
            filePathUri = Android.Net.Uri.Parse(cursor.GetString(column_index));
            filename = filePathUri.LastPathSegment;
            thepath = filePathUri.Path;
        }
    
        return thepath;
    }
    
  • 1
    **Get path from URI Use below class for android all version. 
    access any type of File**.
    
    package com.satya.filemangerdemo.common;
    
    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 android.provider.OpenableColumns;
    import android.text.TextUtils;
    import android.util.Log;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.util.List;
    
    public class FileUtils {
        private static Uri contentUri = null;
    
        /**
         * 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.<br>
         * <br>
         * Callers should check whether the path is local before assuming it
         * represents a local file.
         *
         * @param context The context.
         * @param uri     The Uri to query.
         */
        @SuppressLint("NewApi")
        public static String getPath(final Context context, final Uri uri) {
            // check here to KITKAT or new version
            final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
            String selection = null;
            String[] selectionArgs = null;
            // 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];
    
                    String fullPath = getPathFromExtSD(split);
                    if (fullPath != "") {
                        return fullPath;
                    } else {
                        return null;
                    }
                }
    
                // DownloadsProvider
                else if (isDownloadsDocument(uri)) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        final String id;
                        Cursor cursor = null;
                        try {
                            cursor = context.getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DISPLAY_NAME}, null, null, null);
                            if (cursor != null && cursor.moveToFirst()) {
                                String fileName = cursor.getString(0);
                                String path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName;
                                if (!TextUtils.isEmpty(path)) {
                                    return path;
                                }
                            }
                        } finally {
                            if (cursor != null)
                                cursor.close();
                        }
                        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"
                            };
                            for (String contentUriPrefix : contentUriPrefixesToTry) {
                                try {
                                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
    
                             /*   final Uri contentUri = ContentUris.withAppendedId(
                                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));*/
    
                                    return getDataColumn(context, contentUri, null, null);
                                } catch (NumberFormatException e) {
                                    //In Android 8 and Android P the id is not a number
                                    return uri.getPath().replaceFirst("^/document/raw:", "").replaceFirst("^raw:", "");
                                }
                            }
    
    
                        }
    
                    } else {
                        final String id = DocumentsContract.getDocumentId(uri);
                        final boolean isOreo = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
                        if (id.startsWith("raw:")) {
                            return id.replaceFirst("raw:", "");
                        }
                        try {
                            contentUri = ContentUris.withAppendedId(
                                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
    
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                        }
                        if (contentUri != null) {
                            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;
                    }
                      selection = "_id=?";
                     selectionArgs = new String[]{split[1]};
    
    
                    return getDataColumn(context, contentUri, selection,
                            selectionArgs);
                } else if (isGoogleDriveUri(uri)) {
                    return getDriveFilePath(uri, context);
                }
            }
    
    
            // MediaStore (and general)
            else if ("content".equalsIgnoreCase(uri.getScheme())) {
    
                if (isGooglePhotosUri(uri)) {
                    return uri.getLastPathSegment();
                }
    
                if (isGoogleDriveUri(uri)) {
                    return getDriveFilePath(uri, context);
                }
                 if( Build.VERSION.SDK_INT == Build.VERSION_CODES.N)
                 {
                    // return getFilePathFromURI(context,uri);
                     return getMediaFilePathForN(uri, context);
                    // return getRealPathFromURI(context,uri);
                 }else
                 {
    
                     return getDataColumn(context, uri, null, null);
                 }
    
    
            }
            // File
            else if ("file".equalsIgnoreCase(uri.getScheme())) {
                return uri.getPath();
            }
    
            return null;
        }
    
        /**
         * Check if a file exists on device
         *
         * @param filePath The absolute file path
         */
        private static boolean fileExists(String filePath) {
            File file = new File(filePath);
    
            return file.exists();
        }
    
    
        /**
         * Get full file path from external storage
         *
         * @param pathData The storage type and the relative path
         */
        private static String getPathFromExtSD(String[] pathData) {
            final String type = pathData[0];
            final String relativePath = "/" + pathData[1];
            String fullPath = "";
    
            // on my Sony devices (4.4.4 & 5.1.1), `type` is a dynamic string
            // something like "71F8-2C0A", some kind of unique id per storage
            // don't know any API that can get the root path of that storage based on its id.
            //
            // so no "primary" type, but let the check here for other devices
            if ("primary".equalsIgnoreCase(type)) {
                fullPath = Environment.getExternalStorageDirectory() + relativePath;
                if (fileExists(fullPath)) {
                    return fullPath;
                }
            }
    
            // Environment.isExternalStorageRemovable() is `true` for external and internal storage
            // so we cannot relay on it.
            //
            // instead, for each possible path, check if file exists
            // we'll start with secondary storage as this could be our (physically) removable sd card
            fullPath = System.getenv("SECONDARY_STORAGE") + relativePath;
            if (fileExists(fullPath)) {
                return fullPath;
            }
    
            fullPath = System.getenv("EXTERNAL_STORAGE") + relativePath;
            if (fileExists(fullPath)) {
                return fullPath;
            }
    
            return fullPath;
        }
    
        private static String getDriveFilePath(Uri uri, Context context) {
            Uri returnUri = uri;
            Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null);
            /*
             * Get the column indexes of the data in the Cursor,
             *     * move to the first row in the Cursor, get the data,
             *     * and display it.
             * */
            int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
            int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
            returnCursor.moveToFirst();
            String name = (returnCursor.getString(nameIndex));
            String size = (Long.toString(returnCursor.getLong(sizeIndex)));
            File file = new File(context.getCacheDir(), name);
            try {
                InputStream inputStream = context.getContentResolver().openInputStream(uri);
                FileOutputStream outputStream = new FileOutputStream(file);
                int read = 0;
                int maxBufferSize = 1 * 1024 * 1024;
                int bytesAvailable = inputStream.available();
    
                //int bufferSize = 1024;
                int bufferSize = Math.min(bytesAvailable, maxBufferSize);
    
                final byte[] buffers = new byte[bufferSize];
                while ((read = inputStream.read(buffers)) != -1) {
                    outputStream.write(buffers, 0, read);
                }
                Log.e("File Size", "Size " + file.length());
                inputStream.close();
                outputStream.close();
                Log.e("File Path", "Path " + file.getPath());
                Log.e("File Size", "Size " + file.length());
            } catch (Exception e) {
                Log.e("Exception", e.getMessage());
            }
            return file.getPath();
        }
    
        private static String getMediaFilePathForN(Uri uri, Context context) {
            Uri returnUri = uri;
            Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null);
            /*
             * Get the column indexes of the data in the Cursor,
             *     * move to the first row in the Cursor, get the data,
             *     * and display it.
             * */
            int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
            int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
            returnCursor.moveToFirst();
            String name = (returnCursor.getString(nameIndex));
            String size = (Long.toString(returnCursor.getLong(sizeIndex)));
            File file = new File(context.getFilesDir(), name);
            try {
                InputStream inputStream = context.getContentResolver().openInputStream(uri);
                FileOutputStream outputStream = new FileOutputStream(file);
                int read = 0;
                int maxBufferSize = 1 * 1024 * 1024;
                int bytesAvailable = inputStream.available();
    
                //int bufferSize = 1024;
                int bufferSize = Math.min(bytesAvailable, maxBufferSize);
    
                final byte[] buffers = new byte[bufferSize];
                while ((read = inputStream.read(buffers)) != -1) {
                    outputStream.write(buffers, 0, read);
                }
                Log.e("File Size", "Size " + file.length());
                inputStream.close();
                outputStream.close();
                Log.e("File Path", "Path " + file.getPath());
                Log.e("File Size", "Size " + file.length());
            } catch (Exception e) {
                Log.e("Exception", e.getMessage());
            }
            return file.getPath();
        }
    
    
        private static 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 index = cursor.getColumnIndexOrThrow(column);
                    return cursor.getString(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());
        }
    
        /**
         * @param uri - The Uri to check.
         * @return - Whether the Uri authority is Google Photos.
         */
        private static boolean isGooglePhotosUri(Uri uri) {
            return "com.google.android.apps.photos.content".equals(uri.getAuthority());
        }
    
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is Google Drive.
         */
        private static boolean isGoogleDriveUri(Uri uri) {
            return "com.google.android.apps.docs.storage".equals(uri.getAuthority()) || "com.google.android.apps.docs.storage.legacy".equals(uri.getAuthority());
        }
    
    
    }
    
  • 0
    String uri_path = "file:///mnt/sdcard/FileName.mp3";
    File f = new removeUriFromPath(uri_path));
    public static String removeUriFromPath(String uri)
    {
      return  uri.substring(7, uri.length());
    }
    

相关问题