系统相机拍照、从相册中获取图片

一.使用系统相机拍照:

    private void openCamera() {
        File outputImage = new File(getExternalCacheDir(), "output_image.jpg");//获取应用关联文件缓存目录
        try{
            if(outputImage.exists()) {
                outputImage.delete();//判断如果当前文件存在,则删除
            }
            outputImage.createNewFile();//创建新的文件
        }catch (Exception e) {
            e.printStackTrace();
        }//这段逻辑相当于每次更新缓存文件
        if(Build.VERSION.SDK_INT >= 24) {
            //检查版本7.0以上,需要使用 FileProvider,否则会报FileUriException异常
            imageUri = FileProvider.getUriForFile(this, "com.itcast.myopencamera.fileprovider", outputImage);
        }else {
            imageUri = Uri.fromFile(outputImage);//将文件转换成uri格式
        }
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");//从已存在的相机应用中请求一个图片
        intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);//保存图像的路径和文件名
        startActivityForResult(intent, 1);
    }

    private void getCameraPics(Intent data) {
        try {
            Logger.d(imageUri+"..."+path);
            Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
            imageView.setImageBitmap(bitmap);
       } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 1:
                if(resultCode == RESULT_OK) {
                    getCameraPics(data);
                }
                break;
        }
    }
先要指定相机拍照后,图片存放的位置。判断手机android版本,如果是7.0及以上系统,需要使用FileProvider来封装文件转换成Uri格式,否则系统会报FileUriException异常。如果是7.0以下的直接使用Uri.fromFile()来转换成Uri格式。调用系统相机,需要传递数据,用MediaStore.EXTRA_OUTPUT标识来保存设置的图片存放的路径和文件名。当拍照完并保存后,会回调onActivityResult()方法,使用BitmapFactory工厂将图片保存的文件直接转换成一个Bitmap对象,直接显示到ImageView控件上。


二.从相册中获取图片:

    private void openPics() {
//        //打开系统相册一:如果按下面的方式打开,图片uri地址不会被封装
//        Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
//        startActivityForResult(intent,0);

        //打开系统相册方法二
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent,0);
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void handleImageOnKitKat(Intent data) {
        String imagePath = null;
        Uri uri = data.getData();
        Logger.d(uri);//-----content://com.android.providers.media.documents/document/image%3A659
        if(DocumentsContract.isDocumentUri(this,uri)) {
            //如果是document类型的Uri,则通过document ID处理
            String docId = DocumentsContract.getDocumentId(uri);
            Logger.d(docId);//----- image:662
            if("com.android.providers.media.documents".equals(uri.getAuthority())) {
                Logger.d(uri.getAuthority());//----- com.android.providers.media.documents
                String id = docId.split(":")[1];//解析出数字格式的id
                Logger.d(id);//----662
                String selection = MediaStore.Images.Media._ID + "=" + id;
                Logger.d(selection);// -----_id=662
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
                Logger.d(imagePath+"-----media.documents");//-----/storage/emulated/0/Pictures/04 慢速快门.jpg
            }else if("com.android.providers.downloads.document".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
                imagePath = getImagePath(contentUri,null);
                Logger.d(imagePath+"-----downloads.document");
            }
        }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();//获取Android默认的Uri地址,地址格式为:/storage/emulated/0/Pictures/07 绚彩夜拍.jpg
        String imagePath = getImagePath(uri, null);
        Logger.d(imagePath);
        displayImage(imagePath);
    }

    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;
    }

    private void displayImage(String imagePath) {
        if(imagePath != null) {
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            imageView.setImageBitmap(bitmap);
        }else {
            Toast.makeText(this,"不存在图片",Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 0:
                if(resultCode == RESULT_OK) {
                    if(Build.VERSION.SDK_INT < 19) {
                        handleImageBeforeKitKat(data);//4.4版本以下处理图片的uri地址
                    }else {
                        handleImageOnKitKat(data);//4.4版本以上处理图片的uri地址
                    }
                }
                break;
        }
    }
直接从相册中获取图片有2中方式,一个方式是以“ ACTION_PICK”行为打开的相册,它在任何Android版本下,图片的Uri地址都是真实的绝对路径,不需要解析它的地址,直接调用getImagePath()方法就能获取到图片的地址。另一种方式是以“GET_CONTENT”行为打开的相册,如果以这种方式开启,需要对Android版本进行判断,因为在Android4.4版本以上,相册中的图片地址都进行过封装的,Uri地址格式为:

content://com.android.providers.media.documents/document/image%3A659
而在Android4.4版本以下,相册的图片地址没进行封装,Uri地址格式为:

/storage/emulated/0/Pictures/07 绚彩夜拍.jpg
Android4.4版本及以上图片Uri解析,需要先判断Uri是否是Document类型的,如果是获取Document的ID来处理。如果不是的话,就使用普通方式的来解析Uri地址。另外,如果Uri的Authority是media类型的,需要再一次解析,通过字符串的分割获取到数字格式的id,然后将id封装成选择条件与新构建的Uri传入到getImagePath()方法中,这样才能获取到图片的真实地址。而Android4.4版本以下,直接使用内容解析者遍历图库的数据库查找,找到将图片的真实地址直接返回。





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值