美文网首页Android
Android选择相册、拍照、裁剪功能的简单封装

Android选择相册、拍照、裁剪功能的简单封装

作者: 天路_9c23 | 来源:发表于2018-07-12 15:24 被阅读0次

            在实际开发中,遇到头像修改功能,我们一般是向用户提供相册,拍照以及裁剪功能。而在这个功能开发中,我们需要考虑Android6.0权限适配以及图片压缩上传。虽然功能很普通,但是里面有很多坑要跳过。废话少说,直接进入正题。

    第一步:图片选择框的弹出

        图片选择方式对话框的展示形式根据产品UI来定,但是主要展示的是相机、相册以及取消按钮,代码如下:

    //弹出图片选择框

    public void choicePhoto(Fragment context, File file){

            this.cameraFile = file;        //这个是提前创建的用来存储相机拍照的图片

            final Dialog dialog =new Dialog(context.getActivity(), R.style.Theme_Light_Dialog);

            View view = LayoutInflater.from(context.getActivity()).inflate(R.layout.dialog_photo,null);

            Window window = dialog.getWindow();

            window.setGravity(Gravity.BOTTOM);

            window.setWindowAnimations(R.style.dialog);

            window.getDecorView().setPadding(13,0,13,10);

            WindowManager.LayoutParams layoutParams = window.getAttributes();

            layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;

            layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

            layoutParams.alpha =1.0f;

            window.setAttributes(layoutParams);

            dialog.setContentView(view);

            Button fromCamera = (Button) view.findViewById(R.id.fromcamera);//相机获取

            Button fromGallery = (Button) view.findViewById(R.id.fromgallery);//相册获取

            Button cancle = (Button) view.findViewById(R.id.cancel_getphoto);

            //拍照获取

            fromCamera.setOnClickListener(new View.OnClickListener() {

                    @Override

                      public void onClick(View v) {

                            dialog.dismiss();

                            //拍照权限适配

                            RxPermissions rxPermissions =new RxPermissions(context.getActivity());

                            rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA).subscribe(aBoolean                         -> {

                                    if (aBoolean) {

                                        fromCamera(context);

                                     }else {

                                            //未获取权限

                                            Toast.makeText(context.getActivity(),"您没有授权该权限,请在设置中打开授权", Toast.LENGTH_SHORT).show();

                                    }

                                });

                            }

                    });

                //手机相册获取

                fromGallery.setOnClickListener(new View.OnClickListener() {

                        @Override

                        public void onClick(View v) {

                                dialog.dismiss();

                                RxPermissions rxPermissions =new RxPermissions(context.getActivity());

                                rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(aBoolean -> {

                                        if (aBoolean) {

                                                fromGallery(context);

                                        }else {

                                                //未获取权限

                                                Toast.makeText(context.getActivity(),"您没有授权存储权限,请在设置中打开授权", Toast.LENGTH_SHORT).show();

                                        }

                                   });

                                }

                        });

                //取消

                cancle.setOnClickListener(new View.OnClickListener() {

                            @Override

                            public void onClick(View v) {

                                    dialog.dismiss();

                            }

                   });

        dialog.show();

     }

             其中需要注意的是Android6.0动态权限适配。如果选择相册方式,需要判断存储权限;如果选择相机方式,需要判断相机以及存储权限。我这里采用的是第三方库RxPermissions

    第二步:调用系统相册或相机

    1.调用相机

            Intent intent =new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

            //存放拍照的图片文件

            if (!cameraFile.getParentFile().exists()){

            cameraFile.getParentFile().mkdirs();

            }

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){

            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

            Uri uri = FileProvider.getUriForFile(mContext.getActivity(),"com.xx.xxxxxi.fileprovider",cameraFile);

            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

            }else{

                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile));

           }

           mContext.startActivityForResult(intent,FROM_CAMERA);

    2.调用系统相册

        Intent intent =new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

        intent.setType("image/*");

        mContext.startActivityForResult(intent,FROM_GALLERY);

    第三步:界面中处理onActivityResult返回结果

            switch (requestCode) {

                case FROM_GALLERY:

                    //裁剪图片

                    PhotoUtils.getInstance().startCropImage(data.getData());

                    break;

                case FROM_CAMERA:

                    //裁剪图片

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){

                        PhotoUtils.getInstance().startCropImage(FileProvider.getUriForFile(mContext,"com.xx.xxxx.fileprovider",cameraFile));

                   }else{

                        PhotoUtils.getInstance().startCropImage(Uri.fromFile(cameraFile));

                    }

                    break;

               case IMAGE_CROP:

                    Uri outputUri = Uri.parse("file://" +"/" + Constants.FILE_HEAD_PATH_CROP);

                    mPhotoFile =new File(Constants.FILE_HEAD_PATH_CROP);

                    //保存裁剪后的图片

                    PhotoUtils.getInstance().saveImage(mPhotoFile,outputUri);

                    showLoading();

                    mPresenter.uploadHead(PreManager.instance().getString("token"),"image",mPhotoFile);//上传图片

                    break;

    这部分中,需要注意的是选择相册,返回的是uri路径;而选择相册,我们是保存到文件中,所以需要通过保存的文件获取到uri,但也要考虑到Android6.0权限问题,需要通过FileProvider.getUriForFile(mContext,"com.xx.xxxx.fileprovider",cameraFile)的方式获取到uri

    第四步:裁剪图片

        public void startCropImage(Uri uri){

                Uri imageUri = uri;

                outputUri = Uri.parse("file://" +"/" + Constants.FILE_HEAD_PATH_CROP);//裁剪输出文件

                Intent intent =new Intent("com.android.camera.action.CROP");

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){

                        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

                }

                intent.setDataAndType(imageUri,"image/*");

                intent.putExtra("crop","true");

                //设置宽高比例

                intent.putExtra("aspectX",1);

                intent.putExtra("aspectY",1);

                intent.putExtra("outputX",300);

                intent.putExtra("outputY",300);

                intent.putExtra(MediaStore.EXTRA_OUTPUT,outputUri);

                intent.putExtra("return-data",false);

                intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());

                intent.putExtra("noFaceDetection",true);

                mContext.startActivityForResult(intent,IMAGE_CROP);

            }

    第五步:保存以及压缩上传

            //保存裁剪后的图片

            public void saveImage(File file,Uri uri) {

                    //根据路径获取到原图

                    String realFilePath = getRealFilePath(uri);

                    Bitmap bitmap = BitmapFactory.decodeFile(realFilePath);

                    /*保存图片*/

                    ByteArrayOutputStream baos =new ByteArrayOutputStream();

                    // 把压缩后的数据存放到baos中,压缩质量为50%

                    bitmap.compress(Bitmap.CompressFormat.JPEG,50, baos);

                    try {

                        FileOutputStream fos =new FileOutputStream(file);

                        fos.write(baos.toByteArray());

                        fos.flush();

                        fos.close();

                }catch (Exception e) {

                        e.printStackTrace();

                }

            }

    相关文章

      网友评论

        本文标题:Android选择相册、拍照、裁剪功能的简单封装

        本文链接:https://www.haomeiwen.com/subject/crqrpftx.html