Android通过uri 获取文件路径

时间:2025-01-30 13:11:28
话不多说,通过uri获取文件路径遇到了很多坑,但也最终解决了,直接上代码。

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;



public class UriUtils {
    public static String getFilePathFromURI(Context context, Uri contentUri) {
        File rootDataDir = (null);
//        ().getExternalFilesDir(null).getPath();
        String fileName = getFileName(contentUri);
        if (!(fileName)) {
            File copyFile = new File(rootDataDir +  + fileName);
            copyFile(context, contentUri, copyFile);
            return ();
        }
        return null;
    }
    public static String getFileName(Uri uri) {
        if (uri == null) return null;
        String fileName = null;
        String path = ();
        int cut = ('/');
        if (cut != -1) {
            fileName = (cut + 1);
        }
        return fileName;
    }

    public static void copyFile(Context context, Uri srcUri, File dstFile) {
        try {
            InputStream inputStream = ().openInputStream(srcUri);
            if (inputStream == null) return;
            OutputStream outputStream = new FileOutputStream(dstFile);
            copyStream(inputStream, outputStream);
            ();
            ();
        } catch (Exception e) {
            ();
        }
    }

    public static int copyStream(InputStream input, OutputStream output) throws Exception, IOException {
        final int BUFFER_SIZE = 1024 * 2;
        byte[] buffer = new byte[BUFFER_SIZE];
        BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
        BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE);
        int count = 0, n = 0;
        try {
            while ((n = (buffer, 0, BUFFER_SIZE)) != -1) {
                (buffer, 0, n);
                count += n;
            }
            ();
        } finally {
            try {
                ();
            } catch (IOException e) {
            }
            try {
                ();
            } catch (IOException e) {
            }
        }
        return count;
    }


    /**
     * 通过uri  获取文件路径
     * @param context
     * @param imageUri
     * @return
     */
    public static String getFileAbsolutePath(Context context, Uri imageUri) {
        if (context == null || imageUri == null) {
            return null;
        }

        if (.SDK_INT < .VERSION_CODES.KITKAT) {
            return getRealFilePath(context, imageUri);
        }

        if (.SDK_INT >= .VERSION_CODES.KITKAT && .SDK_INT < Build.VERSION_CODES.Q && (context, imageUri)) {
            if (isExternalStorageDocument(imageUri)) {
                String docId = (imageUri);
                String[] split = (":");
                String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return () + "/" + split[1];
                }
            } else if (isDownloadsDocument(imageUri)) {
                String id = (imageUri);
                Uri contentUri = (("content://downloads/public_downloads"), (id));
                return getDataColumn(context, contentUri, null, null);
            } else if (isMediaDocument(imageUri)) {
                String docId = (imageUri);
                String[] split = (":");
                String type = split[0];
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = .EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = .EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = .EXTERNAL_CONTENT_URI;
                }
                String selection = ._ID + "=?";
                String[] selectionArgs = new String[]{split[1]};
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        } // MediaStore (and general)
        if (.SDK_INT >= Build.VERSION_CODES.Q){
            return uriToFileApiQ(context,imageUri);
        }
        else if ("content".equalsIgnoreCase(())) {
            // Return the remote address
            if (isGooglePhotosUri(imageUri)) {
                return ();
            }
            return getDataColumn(context, imageUri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(())) {
            return ();
        }
        return null;
    }

    //此方法 只能用于4.4以下的版本
    private static String getRealFilePath(final Context context, final Uri uri) {
        if (null == uri) {
            return null;
        }
        final String scheme = ();
        String data = null;
        if (scheme == null) {
            data = ();
        } else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
            data = ();
        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
            String[] projection = {};
            Cursor cursor = ().query(uri, projection, null, null, null);

//            Cursor cursor = ().query(uri, new String[]{}, null, null, null);
            if (null != cursor) {
                if (()) {
                    int index = ();
                    if (index > -1) {
                        data = (index);
                    }
                }
                ();
            }
        }
        return data;
    }


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    private static boolean isExternalStorageDocument(Uri uri) {
        return "".equals(());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    private static boolean isDownloadsDocument(Uri uri) {
        return "".equals(());
    }

    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        String column = ;
        String[] projection = {column};
        try {
            cursor = ().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && ()) {
                int index = (column);
                return (index);
            }
        } finally {
            if (cursor != null) {
                ();
            }
        }
        return null;
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    private static boolean isMediaDocument(Uri uri) {
        return "".equals(());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    private static boolean isGooglePhotosUri(Uri uri) {
        return "".equals(());
    }


    /**
     * Android 10 以上适配 另一种写法
     * @param context
     * @param uri
     * @return
     */
    private static String getFileFromContentUri(Context context, Uri uri) {
        if (uri == null) {
            return null;
        }
        String filePath;
        String[] filePathColumn = {, .DISPLAY_NAME};
        ContentResolver contentResolver = ();
        Cursor cursor = (uri, filePathColumn, null,
                null, null);
        if (cursor != null) {
            ();
            try {
                filePath = ((filePathColumn[0]));
                return filePath;
            } catch (Exception e) {
            } finally {
                ();
            }
        }
        return "";
    }

    /**
     * Android 10 以上适配
     * @param context
     * @param uri
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.Q)
    private static String uriToFileApiQ(Context context, Uri uri) {
        File file = null;
        //android10以上转换
        if (().equals(ContentResolver.SCHEME_FILE)) {
            file = new File(());
        } else if (().equals(ContentResolver.SCHEME_CONTENT)) {
            //把文件复制到沙盒目录
            ContentResolver contentResolver = ();
            Cursor cursor = (uri, null, null, null, null);
            if (()) {
                String displayName = ((OpenableColumns.DISPLAY_NAME));
                try {
                    InputStream is = (uri);
                    File cache = new File(().getAbsolutePath(), ((() + 1) * 1000) + displayName);
                    FileOutputStream fos = new FileOutputStream(cache);
                    (is, fos);
                    file = cache;
                    ();
                    ();
                } catch (IOException e) {
                    ();
                }
            }
        }
        return ();
    }

}

使用方法

path = getFileAbsolutePath(Context, uri);

感谢各位观赏,欢迎提意见