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

上一篇博客讲到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;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值