Android手机读取相册图片,根据URI获取图片路径

这几天做了一个APP,需要读取本地相册图片获取图片的路径然后再进行进一步的处理。这个需要先获取图片的URI,然后根据URI获取图片路径,根据图片路径获取图片。图片URI有两种格式,一种是file开头,一种是content开头。网上查了资料,基本都是按Android的系统去进行区分的,什么Android4.4前,Android4.4后。但是本人经过测试,发现按Android系统进行区分是无效的。

先说图片URI格式,我测试后发现有这两种:

file:///storage/emulated/0/DCIM/Camera/IMG_20170613_132837.jpg和

content://media/external/images/media/1028。要获取的图片路径是:

/storage/emulated/0/DCIM/Camera/IMG_20170613_132837.jpg

本人使用的测试机华为Android4.4.4,6.0,7.0,魅蓝 Android5.1,魅族MX4 Android4.4.2,图片的URI都是content开头。使用红米Android6.0.1,中兴Android6.0,图片URI都是file开头。

基于此,发现根据Android版本去判断图片URI类型是不靠谱的。

现在我的做法:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case SELECT_PHOTO_CODE://从相册获取图片
                    try{
                        final Uri imageUri = data.getData();
                        Log.e("imageUri:",imageUri+"");
                        String selectPhoto = getRealPathFromUri(this,imageUri);
                        Log.e("selectPhoto:",selectPhoto);
                        setImageCompressBitmap(selectPhoto);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    break;
                default:
                    break;
            }
        }
    }

/**
     * 根据图片的Uri获取图片的绝对路径。@uri 图片的uri
     * @return 如果Uri对应的图片存在,那么返回该图片的绝对路径,否则返回null
     */
    public static String getRealPathFromUri(Context context, Uri uri) {
        if(context == null || uri == null) {
            return null;
        }
        if("file".equalsIgnoreCase(uri.getScheme())) {
            return getRealPathFromUri_Byfile(context,uri);
        } else if("content".equalsIgnoreCase(uri.getScheme())) {
            return getRealPathFromUri_Api11To18(context,uri);
        }
//        int sdkVersion = Build.VERSION.SDK_INT;
//        if (sdkVersion < 11) {
//            // SDK < Api11
//            return getRealPathFromUri_BelowApi11(context, uri);
//        }
////        if (sdkVersion < 19) {
////             SDK > 11 && SDK < 19
////            return getRealPathFromUri_Api11To18(context, uri);
//            return getRealPathFromUri_ByXiaomi(context, uri);
////        }
//        // SDK > 19
        return getRealPathFromUri_AboveApi19(context, uri);//没用到
    }

    //针对图片URI格式为Uri:: file:///storage/emulated/0/DCIM/Camera/IMG_20170613_132837.jpg
    private static String getRealPathFromUri_Byfile(Context context,Uri uri){
        String uri2Str = uri.toString();
        String filePath = uri2Str.substring(uri2Str.indexOf(":") + 3);
        return filePath;
    }

    /**
     * 适配api19以上,根据uri获取图片的绝对路径
     */
    @SuppressLint("NewApi")
    private static String getRealPathFromUri_AboveApi19(Context context, Uri uri) {
        String filePath = null;
        String wholeID = null;

        wholeID = DocumentsContract.getDocumentId(uri);

        // 使用':'分割
        String id = wholeID.split(":")[1];

        String[] projection = { MediaStore.Images.Media.DATA };
        String selection = MediaStore.Images.Media._ID + "=?";
        String[] selectionArgs = { id };

        Cursor cursor = context.getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection,
                selection, selectionArgs, null);
        int columnIndex = cursor.getColumnIndex(projection[0]);

        if (cursor.moveToFirst()) {
            filePath = cursor.getString(columnIndex);
        }
        cursor.close();
        return filePath;
    }

    /**
     * //适配api11-api18,根据uri获取图片的绝对路径。
     * 针对图片URI格式为Uri:: content://media/external/images/media/1028
     */
    private static String getRealPathFromUri_Api11To18(Context context, Uri uri) {
        String filePath = null;
        String[] projection = { MediaStore.Images.Media.DATA };

        CursorLoader loader = new CursorLoader(context, uri, projection, null,
                null, null);
        Cursor cursor = loader.loadInBackground();

        if (cursor != null) {
            cursor.moveToFirst();
            filePath = cursor.getString(cursor.getColumnIndex(projection[0]));
            cursor.close();
        }
        return filePath;
    }

    /**
     * 适配api11以下(不包括api11),根据uri获取图片的绝对路径
     */
    private static String getRealPathFromUri_BelowApi11(Context context, Uri uri) {
        String filePath = null;
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = context.getContentResolver().query(uri, projection,
                null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
            filePath = cursor.getString(cursor.getColumnIndex(projection[0]));
            cursor.close();
        }
        return filePath;
    }

uri.getScheme()获取的是图片uri开头的file或content。

经过测试,上面的测试机型全部获得图片路径。


相关博客:Android 4.4 kitkat以上及以下根据uri获取路径的方法

Android | Display Selected Image and Its Real Path













 
  
 
 

你可能感兴趣的:(Android)