【问题标题】:How to get file path of image from URI in Android Lollipop?如何从 Android Lollipop 中的 URI 获取图像的文件路径?
【发布时间】:2015-04-15 09:49:19
【问题描述】:

我想为 Android Lollipop 创建一个图像选择器。我使用Intent.ACTION_GET_CONTENT 选择我的图片,但我无法从对话框选择器返回的 URI 中获取所选图片的路径。

我尝试了这些线程的代码:

retrieve absolute path when select image from gallery kitkat android

https://chintankhetiya.wordpress.com/2013/12/14/picture-selection-from-camera-gallery/

但它们都返回 null。谁能帮帮我?

【问题讨论】:

标签: android uri filepath


【解决方案1】:

试试

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class RealPathUtil {
    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API19(Context context, Uri uri) {
        Log.variable("uri", uri.getPath());
        String filePath = "";
        if (DocumentsContract.isDocumentUri(context, uri)) {
            String wholeID = DocumentsContract.getDocumentId(uri);
            Log.variable("wholeID", wholeID);
// Split at colon, use second item in the array
            String[] splits = wholeID.split(":");
            if (splits.length == 2) {
                String id = splits[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();
            }
        } else {
            filePath = uri.getPath();
        }
        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);
    }

并使用:

private String uriToFilename(Uri uri) {
    String path = null;

    if (Build.VERSION.SDK_INT < 11) {
        path = RealPathUtil.getRealPathFromURI_BelowAPI11(mContext, uri);
    } else if (Build.VERSION.SDK_INT < 19) {
        path = RealPathUtil.getRealPathFromURI_API11to18(mContext, uri);
    } else {
        path = RealPathUtil.getRealPathFromURI_API19(mContext, uri);
    }

    return path;
}

在必须的情况下为我工作(not works 用于下载应用程序)

【讨论】:

    【解决方案2】:

    试试这个小功能:

    public static String getRealPathFromUri(Uri uri) {
        String result = "";
        String documentID;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            String[] pathParts = uri.getPath().split("/");
            documentID = pathParts[pathParts.length - 1];
        } else {
            String pathSegments[] = uri.getLastPathSegment().split(":");
            documentID = pathSegments[pathSegments.length - 1];
        }
        String mediaPath = MediaStore.Images.Media.DATA;
        Cursor imageCursor = getContentResolver().query(uri, new String[]{mediaPath}, MediaStore.Images.Media._ID + "=" + documentID, null, null);
        if (imageCursor.moveToFirst()) {
            result = imageCursor.getString(imageCursor.getColumnIndex(mediaPath));
        }
        return result;
    }
    

    【讨论】:

    • 这对我帮助很大,我一直在寻找适用于 Lollipop 的代码,您的回答对我来说是完美的,谢谢!
    • 在 Nougat 上,传入一个图像内容 Uri,返回 null。
    【解决方案3】:

    这对我有用。

    我创建了一个 Util 类RealPathUtil(与@Artem 答案中的类有一些细微差别):

    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.content.CursorLoader;
    import android.database.Cursor;
    import android.net.Uri;
    import android.provider.DocumentsContract;
    import android.provider.MediaStore;
    
    public class RealPathUtil {
    
        @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);
    
            assert cursor != 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){
            Cursor cursor = null;
    
            try {
                String[] proj = { MediaStore.Images.Media.DATA };
                cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
                assert cursor != null;
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                return cursor.getString(column_index);
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }
        }
    
    }
    

    然后,在我的应用代码中,我使用了:

    private String getPathFromUri(Uri uri) {
        if (Build.VERSION.SDK_INT < 11)
            return RealPathUtil.getRealPathFromURI_BelowAPI11(getContext(), uri);
        else if (Build.VERSION.SDK_INT < 19)
            return RealPathUtil.getRealPathFromURI_API11to18(getContext(), uri);
        else
            return RealPathUtil.getRealPathFromURI_API19(getContext(), uri);
    }
    

    【讨论】:

      【解决方案4】:

      确保您在 Android 清单中授予权限!

      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-01
        • 1970-01-01
        • 2019-08-17
        • 2020-03-26
        • 2017-08-27
        相关资源
        最近更新 更多