android新版本下打开相册取出相片新姿势

来源:互联网 发布:如何在淘宝上找客服 编辑:程序博客网 时间:2024/05/17 23:41
上一篇博客讲到android6.0下拍到的相片要经过FileProvider封装uri才能存到相册,同时android4.4以上版本从相册取出相片的uri也会被自动封装起来,这使得我们不能像以前一样直接通过uri得到相片的地址,需要现对uri进行复杂的解析,当然,逻辑还是很清楚的,可以当工具类存起来,下面上代码:
        Intent intent=new Intent(Intent.ACTION_GET_CONTENT);        intent.setType("image/*");        startActivityForResult(intent,RESULT_IMAGE);
首先是打开相册,这没什么好说的,调用系统程序,打开image类型的文件,然后看看回掉函数:
        Uri uri=data.getData();        String imagePath=null;        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            imagePath=handleUriToPath(uri);        }        else imagePath=getImagePath(uri,null);        Intent intent=new Intent(MainActivity.this,Puzzle.class);        intent.putExtra("mPicPath",imagePath);        startActivity(intent);

当android版本大于4.4会调用handleUriToPath(uri)函数把封装过的uri重新解析成我们能使用的uri。

@RequiresApi(api = Build.VERSION_CODES.KITKAT)    private String handleUriToPath(Uri uri) {        if (DocumentsContract.isDocumentUri(this,uri)){            String docId=DocumentsContract.getDocumentId(uri);            if ("com.android.providers.media.documents".equals(uri.getAuthority())){                String id=docId.split(":")[1];                String selection=MediaStore.Images.Media._ID+"="+id;//where _ID=id                return getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);            }            else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())){                Uri contentUri= ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));                return getImagePath(contentUri,null);            }        }        else if ("content".equalsIgnoreCase(uri.getScheme()))            return getImagePath(uri,null);        else if ("file".equalsIgnoreCase(uri.getScheme()))            return uri.getPath();        return null;    }
思路还是很清晰的,uri分为头部协议,中间的authority和路径和尾部的id,先判断uri是不是document类型,是的话又分media类型和download类型,media类型的先解析出document id,在通过字符串分割取出我们想要的id,docId大致是“image:id",MediaStore.Images.Meida.EXTERNAL_CONTENT_URL是存储图片的uri,这个就是我们能直接使用的uri,只不过没有具体到哪张图片,所以我们通过加上id确定到具体的图片,getImagePath(uri,selection)的作用类似于query,selection是where条件语句,稍后贴出代码。download类型通过withAppendedId(Uri contentUri,Long id)这个函数组装成一个新的uri,里面的结构很简单,同样是用一个我们已经知道的可以直接使用的Uri加上我们选择的图片的uri组合成一个完整的uri。

下面还有两句,分别判断头部协议是content还是file,content的话就直接使用写好的getImagePath函数,fie更简单,uri.getPath()就出来路径了,最后贴身getImagePath(Uri uri)代码,也是我们在4.4以前最常用的一段代码

       String path=null;       Cursor cursor=getContentResolver().query(uri,null,selection,null,null);        if (cursor!=null){            if (cursor.moveToFirst()){                path=cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));            }        }        cursor.close();        return path;

原创粉丝点击