照片系列之android调用照片库获取图片

本文详细介绍了在Android应用中如何处理相册权限,包括WRITE_EXTERNAL_STORAGE权限的请求及回调,以及不同Android版本下相册图片的正确处理方法。同时,针对大图片在ImageView显示的问题,提供了一种有效的图片压缩解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

判断权限

在打开相册前要先获取权限,WRITE_EXTERNAL_STORAGE是个危险权限,有了这个权限会获得到对SD卡读写的能力

 if (ContextCompat.checkSelfPermission(PictureAc.this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){
                    //如果没有请求权限在这里请求
                    ActivityCompat.requestPermissions(PictureAc.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},2);
                }else {
                    openAlbum();
                }

下面是获取权限的回调

//这里接收动态获取权限时候的结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case 2:
                if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
                   openAlbum();
                }else{
                    Toast.makeText(this,"您拒绝了该权限的获取",Toast.LENGTH_SHORT).show();
                }
                break;
            default:
        }
    }

打开相册

获取权限后我们需要打开相册,在这里我们在intent中设置必要的参数就可以调到图库

    /**
     * 打开相册
     */
    private void openAlbum(){
        Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); //"android.intent.action.GET_CONTENT"
        innerIntent.setType("image/*"); //查看类型 String IMAGE_UNSPECIFIED = "image/*";
        innerIntent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(Intent.createChooser(innerIntent, null), Choose_From_Album);
    }

回调处理

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode){
            case Choose_From_Album://调用相册
                if (resultCode==RESULT_OK) {
                    Toast.makeText(PictureAc.this, "调用相册成功!", Toast.LENGTH_LONG).show();
                    if (Build.VERSION.SDK_INT>=19){
                        //4.4以上系统使用这个方法处理图片
                        handleImageOnKitKat(data);
                    }else{
                        //4.4以下系统使用这个方法处理图片
                        handleImagebeforeKitKat(data);
                    }
                }else{
                    Toast.makeText(PictureAc.this, "调用相册失败!", Toast.LENGTH_LONG).show();
                }
                break;
            default:
                break;
        }

这里为了兼容新老版本差异,因为Android系统4.4版本开始,选取的相册中的照片不再返回图片真实的Uri了,而是一个封装过的,需要进行解析才能用

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void handleImageOnKitKat(Intent data) {
        String imagePath=null;
        Uri uri=data.getData();
        if (DocumentsContract.isDocumentUri(this,uri)){
            //如果document类型的Uri,则通过document id处理
            String docId=DocumentsContract.getDocumentId(uri);
            if ("com.android.providers.media.documents".equals(uri.getAuthority())){
                String id=docId.split(":")[1];//解析出数字格式的id
                String selection=MediaStore.Images.Media._ID+"="+id;
                imagePath=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));
                imagePath=getImagePath(contentUri,null);
            }
        }else if("content".equalsIgnoreCase(uri.getScheme())){
            //如果是content类型的Uri,则使用普通方式处理
            imagePath=getImagePath(uri,null);
        }else if("file".equalsIgnoreCase(uri.getScheme())){
            //如果是file类型的Uri,直接获取图片路径即可
            imagePath=uri.getPath();
        }
        displayImage(imagePath);//根据图片路径显示图片
    }
 private void handleImagebeforeKitKat(Intent data) {
        Uri uri=data.getData();
        String imagePath=getImagePath(uri,null);
        displayImage(imagePath);
    }

根据uri获取图片路径

 private String getImagePath(Uri uri, String selection){
        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;
    }

显示图片到ImageView

private void displayImage(String imagePath) {
        if (imagePath!=null){
           // Bitmap bitmap=BitmapFactory.decodeFile(imagePath);
            Bitmap bitmap=resizePhoto(imagePath);
            showImg.setImageBitmap(bitmap);
        }else{
            Toast.makeText(PictureAc.this, "获取图片失败!", Toast.LENGTH_LONG).show();
        }
    }

ImageView不能显示过大图片问题

在调用手机相册的时候发现相册中部分图片能正常显示,而有些图片无法正常显示,这个时候压缩一下图片就好了。

private Bitmap resizePhoto(String photo_url)
    {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        //不会加载,只会获取图片的一个尺寸
        //options里面储存了图片的高度和宽度
        //读取文件
        BitmapFactory.decodeFile(photo_url ,options);
        //改变图片的大小
        double ratio = Math.max(options.outWidth *1.0d/1024f,options.outHeight *1.0d/1024);
        options.inSampleSize =(int) Math.ceil(ratio);
        //设置后会加载图片
        options.inJustDecodeBounds = false;
        //图片压缩完成
        return BitmapFactory.decodeFile(photo_url ,options);
    }
    

链接: 照片系列之android调用摄像头拍照.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值