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

来源:互联网 发布:switch php case 多个 编辑:程序博客网 时间:2024/05/17 09:22

一.使用系统相机拍照:

    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版本以下,直接使用内容解析者遍历图库的数据库查找,找到将图片的真实地址直接返回。





阅读全文
0 1