项目中有需求是要从图库中选择图片并显示的。这个需求,网上一搜一大把,我也不想炒剩饭了。只是将自己碰到的一些问题,讲出来,供大家参考,规避类似问题。

最开始,我调用系统图库,没考虑过版本问题,直到找了台小米机测试,才发现问题所在。按理说,我应该感谢小米的,别急,后面就知道我为啥吐槽它了。

我调用系统图库的是ACTION_PICK,回调方法onactivityresult里代码如下:

if (requestCode==Conts.LOAD_PICTURE) {
if (resultCode==getActivity().RESULT_OK&&data!=null) {

Uri selectedImage = data.getData();  
String[] filePathColumn = { MediaStore.Images.Media.DATA };  
Cursor cursor = getContext().getContentResolver().query(selectedImage,  
filePathColumn, null, null, null);  
cursor.moveToFirst();  
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);  
String picturePath = cursor.getString(columnIndex);  
cursor.close();

}

选择了图片之后,小米机会崩掉(别的机子,啥版本都没问题),或者返回上一层界面,或者重启app。看异常信息。指示cursor.moveToFirst(),空指针异常。也就是说,cursor为空。是uri的问题,4.4之前,返回的是包含图片绝对路劲的,4.4之后,返回的不再是绝对路劲了,而是一个图片的编码。但是,Android肯定不会这么坑,对吧,他绝对会兼容之前的版本。如果用的是ACTION_PICK,还是可以用这个方法的,但是他只能选择系统图库里的图片,例如“最近”,“图片”,“文件夹”什么的,就看不到了。不过至少给了个方法,是吧。华为,三星,魅族,oppo,都试过了,没有问题。而小米呢,又开始发扬其作屎风格了,不论版本高低,这样都不行,都会出现我上面提到的问题。得到的只是一个图片编码。你需要去转换为绝对路径,才能方便使用。得到绝对路径的方法,有大神封装好了,封装成了一个pictureHelper工具类,最后我会把这个类的代码贴上。

总结一下,就是,除了小米,你用ACTION_PICK,都能得到一个图片的绝对路径。如果是小米,用ACTION_PICK,就需要去转化了。但是,小米用ACTION_GET_CONTENT或者ACTION_OPEN_DOCUMENT,低版本,也能得到绝对路径。反正我是醉了。最后我统一的处理方法就是,用ACTION_GET_CONTENT,然后分版本处理,低版本还是旧的方法,高版本,用pictureHelper工具类处理得到绝对路径。

贴代码,调用图库Intent intent= new Intent(Intent.ACTION_GET_CONTENT);// ACTION_OPEN_DOCUMENT
               // intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); //4.4推荐用此方式,4.4以下的API需要再兼容
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                intent.setType("image/*");
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
                        startActivityForResult(intent, Conts.LOAD_PICTURE_KITKAK);//4.4版本
                } else {
                        startActivityForResult(intent, Conts.LOAD_PICTURE);//4.4以下版本,先不处理
                }

在onactivityresult里的处理://上面的是低版本的,下面一种是高版本

if (requestCode==Conts.LOAD_PICTURE) {
if (resultCode==getActivity().RESULT_OK&&data!=null) {

Uri selectedImage = data.getData();  
String[] filePathColumn = { MediaStore.Images.Media.DATA };

Cursor cursor = getContext().getContentResolver().query(selectedImage,  
filePathColumn, null, null, null);  
cursor.moveToFirst();  
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);  
String picturePath = cursor.getString(columnIndex);  
cursor.close();  
}
}

//4.4以上版本

if (requestCode==Conts.LOAD_PICTURE_KITKAK) {
if (resultCode==getActivity().RESULT_OK&&data!=null) {
Uri selectedImage = data.getData();
                String picturePath = PictureHelper.getPath(getContext(), selectedImage); 
             
}
}

还有个我遇到的问题也顺带提一句,如果,你在onactivityresult里有很多操作,比较耗时的话,也会崩掉,响应事件过长导致的。我的处理方法是,这些处理用工作线程完成,处理完毕,handler发消息给主线程去完成UI操作。这个大家估计问题不大,只是有时会忽视。

好了,进入正题,吐槽开始。小米,从他整出MIUI,就没消停过,擅自更改UI样式等等,就不提了,Android的很多设计原则,他丫就是不准守,他的原则只有一个,就是舔的用户开心,完全不管开发者的感受。反正用户骂的不会是系统,只会骂开发者,这个app做的真烂。之前还有个drawable里放图片资源也遇到过,别人的这么放的都好使,他的就不行,闪退,还是去查了好久资料,按照他的规则来,才解决图片资源加载的问题。总之,Android碎片化如此严峻的今天,我们又要多一种适配出来,那就是该屎的小米。你在开发中,必须考虑你的app在小米机上,会不会正常运行。我要是能做主,我的app就尼玛不兼容小米。爱咋咋地。可惜......

最后把那个PictureHelper工具类附上。

public class PictureHelper {

// get the absolute path from the uri
    @SuppressLint("NewApi")
    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)) {
                    // 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 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;
    }

public static boolean isExternalStorageDocument(Uri uri) {
            return "com.android.externalstorage.documents".equals(uri
                            .getAuthority());
    }

public static boolean isDownloadsDocument(Uri uri) {
            return "com.android.providers.downloads.documents".equals(uri
                            .getAuthority());
    }

public static boolean isMediaDocument(Uri uri) {
            return "com.android.providers.media.documents".equals(uri
                            .getAuthority());
    }

private static boolean isGooglePhotosUri(Uri uri) {
            return "com.google.android.apps.photos.content".equals(uri
                            .getAuthority());
    }

}

关于从图库选择图片的问题,Android4.4前后的改动,顺便吐槽小米MIUI相关推荐

  1. 安卓兼容7.0图库选择图片生成二维码

    上一篇文章生成二维码没有完善,这次来完善一下图库选择图片生成二维码,代码和上次的差不多,安卓6.0后打开相机和图册必须判断是否已经获得权限,只有用户设置获取权限才能访问,要不是访问不了的,代码比较多, ...

  2. Android开发:调用系统图库选择图片

    方法: //调用系统图库选择图片 public Intent selectPicture() {Intent intent = new Intent(Intent.ACTION_PICK,androi ...

  3. Android开发之调用相机拍照与本地图库选择图片

    引用链接 Android开发之调用相机拍照与本地图库选择图片 Android调用相机实现拍照功能 部分截图 引言 小项目有一个访问相册的需求,在网上查找得到两位大神博客指点,但博客发布时间过旧,难免因 ...

  4. Android调用手机图库选择图片并调用手机的图片裁剪工具

    /*** 获得图库图片回调标识*/public static final int GET_PIC_FROM_GALLERY = 0X100;/*** 调用手机工具编辑图片标识*/public stat ...

  5. android 4.4从图库选择图片,安卓6.0,从系统图库选择照片,裁剪,并显示的问题。...

    问题是:当我点击选择按钮时,确实跳到图库.但是选择完照片,却没有跳转到裁剪界面?这是为什么?代码逻辑有问题吗? 全局变量:private Uri chooseUri; //对按钮监听,跳转到图库,并选 ...

  6. Android 如何从系统图库中选择图片

     这几天我都在做Android的App,同时学习它的API,我将分享一些我学到的东西,比如: 如何从系统图库中选择图片. 首先,让我们来看看如何将手机系统图库集成到你的App中,然后再从图库中选择 ...

  7. Android10(华为Mate30)获取图片路径失败,拍照或从相册选择图片后无法显示

    在使用华为Mate30是从图库选择图片,本地无法显示,其他手机没问题,发现是兼容Android10的问题,Android10下本app的私有文件是不需要权限的,访问其他应用权限需要权限 android ...

  8. Flutter 相册选择图片和相机拍照

    Flutter 获取相册中的图片和用相机拍照   在原生开发中,拍照及从图库选择图片是非常常见的需求,而且原生的图片选择第三方库也有很多并且很完善了.Flutter 也给我们提供了好用的图片选择插件, ...

  9. Android 从 Android 本地图库选择多个图片

    原文地址 本文说明如何从 Android 本地图库选择多个图片.作者考虑很多解决方案. 演示从 Android 本地图库选择多个图片,有两个方法可以实现从图库中选择多个图片: 用 Intent 获取多 ...

最新文章

  1. PyTorch实现,GitHub 4000星:这是微软开源的计算机视觉库
  2. Python--logging....实例应用
  3. 编程python用什么软件比较好-新手入门Python编程的8个实用建议
  4. 山东大学为中外学生“学伴”项目不当选项致歉
  5. Redis事务中的watch机制-从实例入手学习
  6. 2017西安交大ACM小学期 神器插座 KMP匹配
  7. linux indent命令: 调整C原始代码文件的格式
  8. python安装多个版本_Mac安装多个python版本
  9. 红黑树 键值_Java集合框架:红黑树概念、插入及旋转操作详细解读就问你会不会...
  10. 利用Session实现一次性验证码(多学一招)
  11. char* str = abc ;跟char str[] = abc;的区别
  12. 0 基础 Java 自学之路(2021年最新版)
  13. 单相全桥逆变器带负载电流前馈的双闭环控制系统设计及仿真
  14. 计算机控制系统——导论
  15. BeanUtils.copyProperties 和 fastjson 性能对比
  16. latex 如何输入 双斜杠 单斜杠
  17. IDEA修改默认的新建项目路径
  18. EM算法-数学原理及其证明
  19. 解线性方程组——高斯消元の板子
  20. modeller建模

热门文章

  1. docker启动时出现open() “/usr/local/openresty/nginx/conf/nginx.conf“ failed (13: Permission deni
  2. python 66:re正则表达式7(全- tcy)
  3. 秒拍5大月榜出炉:首发MCN机构榜,魔力TV15.6亿播放量夺冠!
  4. Vue.js+uniapp青少年大学生心理健康科普系统 java php python微信小程序
  5. [实战Google深度学习框架]Tensorflow(7)自然语言处理
  6. 人工智能的特点及人工智能应用
  7. Python和Java相比有什么优势?
  8. 在Java中操作Redis(详细完整版)
  9. Tyk GateWay - Universal Data Graph (数据组装)
  10. 如何向国外专业期刊投稿