Android7.0调用系统相册、拍照裁剪及压缩

Android7.0调用系统相册、拍照裁剪及压缩并有效解决兼容性的问题(我用的是MI Note3  7.1.1系统进行测试的)


通过工具类封装 可以在页面中直接拿来就用 非常得方便

Activity代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button button;
    private FrameLayout container;
    private ImageView imageView;
    public static final String TAG = "MainActivity";


    private SystemPictureSelector pictureSelector;
    private String savedPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + String.valueOf(System.currentTimeMillis()) + ".png";
    private int index = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();

    }

    private void initView() {

        button = findViewById(R.id.btn_select);
        //container = findViewById(R.id.image_container);
        imageView = findViewById(R.id.image_selected);
        imageView.setOnClickListener(this);
        button.setOnClickListener(this);
        loadGlideImage();
    }

    private void loadGlideImage() {

        SystemPictureSelector.Builder builder = new SystemPictureSelector.Builder(this);
        builder.isCropped(true)
                .setCropSize(3, 2)
                .setOutputPath(savedPath)
                .setOnSelectListener(new SystemPictureSelector.OnSystemPictureSelectListener() {
                    @Override
                    public void onSelectedSuccess(File file) {

                        Uri uri = Uri.fromFile(file);
                        Log.e(TAG, "onSelectedSuccess: " + uri.toString());

                        Glide.clear(imageView);
                        Glide.with(MainActivity.this)
                                .load(file)
                                .diskCacheStrategy(DiskCacheStrategy.NONE)
                                .into(new SimpleTarget() {
                                    @Override
                                    public void onResourceReady(GlideDrawable resource, GlideAnimation glideAnimation) {
                                        imageView.setImageDrawable(resource);
                                    }
                                });
                        //uploadPhoto();
                    }

                    @Override
                    public void onSelectedMessage(String msg) {

                        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
                    }
                });
        pictureSelector = builder.create();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        pictureSelector.bindingActivityForResult(requestCode, resultCode, data);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.image_selected:

                showSelectDialog();
                break;

            case R.id.btn_select:

                showSelectDialog();
                break;
        }
    }


    private void showSelectDialog() {
        final BottomSheetDialog dialog = new BottomSheetDialog(this);
        View selectView = LayoutInflater.from(this).inflate(R.layout.dialog_layout, null);
        TextView bt_camera = selectView.findViewById(R.id.btn_by_camera);
        TextView bt_gallery = selectView.findViewById(R.id.btn_by_gallery);
        TextView bt_cancel = selectView.findViewById(R.id.btn_cancel);
        dialog.setContentView(selectView);
        /**
         * 解决bsd显示不全的情况
         */
        View parent = (View) selectView.getParent();
        BottomSheetBehavior behavior = BottomSheetBehavior.from(parent);
        selectView.measure(0, 0);
        behavior.setPeekHeight(selectView.getMeasuredHeight());

        bt_camera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog.dismiss();

                index = 1;
                verifyPeimissions();
                Log.d("bt_camera", 1111 + "");
            }
        });

        bt_gallery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog.dismiss();
                index = 2;
                verifyPeimissions();
                Log.d("bt_gallery", 2222 + "");
            }
        });

        bt_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (dialog.isShowing()) {
                    dialog.dismiss();
                }
            }
        });
        dialog.show();
    }

    private void verifyPeimissions() {
        String[] permission = new String[]{
                Manifest.permission.WRITE_EXTERNAL_STORAGE
                , Manifest.permission.READ_EXTERNAL_STORAGE
                , Manifest.permission.CAMERA
        };
        EasyPermissions.of(MainActivity.this)
                .reqCode(123)
                .perms(permission)
                .callBack(new com.moos.selector.permission.my.PermissionInfo() {
                    @Override
                    public void onGranted(List perms) {
                        if (index == 1) {
                            Log.d("bt_camera", 3333 + "");
                            pictureSelector.getSystemPhotoByCamera();
                        } else if (index == 2) {
                            Log.d("bt_gallery", 4444 + "");
                            pictureSelector.getSystemPhotoByGallery();
                        }
                    }

                    @Override
                    public void onDenied(List perms) {
                        ToastUtil.showToast(MainActivity.this, "您拒绝了权限,该功能不可用\n可在应用设置里授权拍照哦");

                    }
                });
    }
}

调用相机图库的工具类:

public class SystemPictureSelector {

    public static final int TAKE_PHOTO = 101;
    public static final int LOCAL_GALLERY = 102;
    public static final String TAG = "SystemPictureSelector";
    public static final int REQUEST_TAKE_PHOTO = 2018;
    public static final int REQUEST_GALLERY_PHOTO = 2019;
    public static final int REQUEST_CROP_PICTURE = 2020;
    private Activity mContext;
    private int mBehavior = 1;
    private int mAspectX = 1;
    private int mAspectY = 1;
    private int mOutputX = 200;
    private int mOutputY = 200;
    private String mSavedPath;
    private boolean mWeatherCrop = true;
    private OnSystemPictureSelectListener mListener;

    private File mTargetPhoto;
    private File mOutputFile;

    public SystemPictureSelector(Builder builder) {

        this.mContext = builder.context;
        this.mAspectX = builder.aspectX;
        this.mAspectY = builder.aspectY;
        this.mOutputX = builder.outputX;
        this.mOutputY = builder.outputY;
        this.mWeatherCrop = builder.weatherCrop;
        this.mSavedPath = builder.savedPath;
        this.mListener = builder.listener;
    }

    Uri imgUri = null;

    /**
     * get picture by taking photo
     */
    public void getSystemPhotoByCamera() {
        mSavedPath = getSavedPath();
        mBehavior = TAKE_PHOTO;
        File imgFile = new File(mSavedPath);
        if (!imgFile.getParentFile().exists()) {
            imgFile.getParentFile().mkdirs();
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // 适配Android7.0通过contentResolver获取uri
            ContentValues contentValues = new ContentValues(1);
            contentValues.put(MediaStore.Images.Media.DATA, imgFile.getAbsolutePath());
            imgUri = mContext.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);

        } else {
            // 7.0以下通过文件获取uri
            imgUri = Uri.fromFile(imgFile);
        }

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);
        mContext.startActivityForResult(intent, REQUEST_TAKE_PHOTO);
    }

    /**
     * get picture by local gallery
     */
    public void getSystemPhotoByGallery() {

        mBehavior = LOCAL_GALLERY;
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        mContext.startActivityForResult(intent, REQUEST_GALLERY_PHOTO);

    }

    /**
     * 采取系统自带方式裁剪图片
     *
     * @param targetPhoto 需要裁剪的目标图片
     * @param outputFile  我们指定的输出文件
     */
    private void cropPictureBySystemWay(File targetPhoto, File outputFile) {

        Intent intent = new Intent("com.android.camera.action.CROP");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // android7.0设置输出文件的uri
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            intent.setDataAndType(getUriByFileForN(mContext, targetPhoto), "image/*");
            //intent.setDataAndType(file2Uri(mContext,targetPhoto),"image/*");
        } else {
            intent.setDataAndType(Uri.fromFile(targetPhoto), "image/*");
        }

        //设置图片裁剪区域宽高比
        intent.putExtra("aspectX", mAspectX);
        intent.putExtra("aspectY", mAspectY);
        intent.putExtra("crop", "true");

        //设置图片裁剪后输出质量(一般来说,值越大,越清晰,但需要根据情况而定)
        //intent.putExtra("outputX", mOutputX);
        //intent.putExtra("outputY", mOutputY);
        intent.putExtra("scale", true);//支持缩放
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outputFile));
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);//取消人脸识别
        mContext.startActivityForResult(intent, REQUEST_CROP_PICTURE);
    }

    /**
     * 根据文件转换成对应的Uri
     *
     * @param ctx
     * @param file
     * @return
     */
    public static Uri file2Uri(Context ctx, File file) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return FileProvider.getUriForFile(ctx, BuildConfig.APPLICATION_ID + ".fileprovider", file);
        } else {
            return Uri.fromFile(file);
        }
    }

    /**
     * Android7.0根据文件获取uri
     */
    private Uri getUriByFileForN(Context context, File imageFile) {
        String filePath = imageFile.getAbsolutePath();
        Cursor cursor = context.getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                new String[]{MediaStore.Images.Media._ID},
                MediaStore.Images.Media.DATA + "=? ",
                new String[]{filePath}, null);

        if (cursor != null && cursor.moveToFirst()) {
            int id = cursor.getInt(cursor
                    .getColumnIndex(MediaStore.MediaColumns._ID));
            Uri baseUri = Uri.parse("content://media/external/images/media");
            return Uri.withAppendedPath(baseUri, "" + id);
        } else {
            if (imageFile.exists()) {
                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.DATA, filePath);
                return context.getContentResolver().insert(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            } else {
                return null;
            }
        }
    }

    private String getSavedPathByTime() {
        return getExternalStoragePath() + File.separator + String.valueOf(System.currentTimeMillis()) + ".png";
    }

    private String getPhotoPathByUri(Intent data) {
        Uri sourceUri = data.getData();
        String[] projection = {MediaStore.Images.Media.DATA};
        Cursor cursor = mContext.managedQuery(sourceUri, projection, null, null, null);
        int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String imgPath = cursor.getString(columnIndex);
        return imgPath;
    }

    /**
     * 获取SD下的对应的应用路径
     */
    private String getExternalStoragePath() {
        StringBuilder sb = new StringBuilder();
        sb.append(Environment.getExternalStorageDirectory().getAbsolutePath());
        sb.append(File.separator);
        String ROOT_DIR = "Android/data/" + mContext.getPackageName();
        sb.append(ROOT_DIR);
        sb.append(File.separator);
        return sb.toString();
    }

    /**
     * by moos on 2018/05/12
     * desc:绑定所在activity的onActivityForResult方法,处理回调数据
     *
     * @param requestCode 请求码
     * @param resultCode  结果码
     * @param data        返回结果
     */
    public void bindingActivityForResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case REQUEST_TAKE_PHOTO:
                    // 系统拍照
                    mTargetPhoto = new File(mSavedPath);
                    if (mWeatherCrop) {
                        // 去裁剪
                        mOutputFile = new File(getSavedPathByTime());
                        cropPictureBySystemWay(mTargetPhoto, mOutputFile);
                    } else {
                        // 不裁剪
                        if (mListener != null) {
                            mListener.onSelectedSuccess(mTargetPhoto);
                            mListener.onSelectedMessage("拍照成功~");
                        }
                    }
                    break;

                case REQUEST_GALLERY_PHOTO:
                    // 本地图库
                    if (data != null) {
                        mTargetPhoto = new File(getPhotoPathByUri(data));
                        if (mWeatherCrop) {
                            // 去裁剪
                            mOutputFile = new File(getSavedPathByTime());
                            cropPictureBySystemWay(mTargetPhoto, mOutputFile);
                        } else {
                            // 不裁剪
                            if (mListener != null) {
                                mListener.onSelectedSuccess(mTargetPhoto);
                                mListener.onSelectedMessage("从本地选取图片成功~");
                            }
                        }
                    } else {
                        mListener.onSelectedMessage("从本地图库获取到的数据为空!");
                    }

                    break;

                case REQUEST_CROP_PICTURE:
                    // 系统裁剪
                    if (data != null) {
                        Log.d("----------data != ", "null");
                        if (mBehavior == TAKE_PHOTO && mTargetPhoto != null) {


                        }
                        LuBanYaSuo(mOutputFile);
                    } else {
                        Log.d("---------data = ", "null");
                        mListener.onSelectedMessage("系统裁剪失败,无法获取裁剪数据");
                    }
                    break;
            }
        }
    }

    private void LuBanYaSuo(File file) {
        Luban.with(mContext)
                .load(file.getAbsolutePath())                   // 传人要压缩的图片列表
                .ignoreBy(100)                                  // 忽略不压缩图片的大小
                .setTargetDir(getYaSuoPath())             // 设置压缩后文件存储位置
                .setCompressListener(new OnCompressListener() { //设置回调
                    @Override
                    public void onStart() {
                        // TODO 压缩开始前调用,可以在方法内启动 loading UI
                    }

                    @Override
                    public void onSuccess(File file) {
                        // TODO 压缩成功后调用,返回压缩后的图片文件
                        if (mListener != null) {
                            mListener.onSelectedSuccess(file);
                            mListener.onSelectedMessage("裁剪成功~");
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        // TODO 当压缩过程出现问题时调用
                    }
                }).launch();
    }

    private String getYaSuoPath() {
        String path = Environment.getExternalStorageDirectory() + "/Luban/image/";
        File file = new File(path);
        if (file.mkdirs()) {
            return path;
        }
        return path;
    }

    private String getSavedPath() {
        return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + String.valueOf(System.currentTimeMillis()) + ".png";
    }

    public static class Builder {

        private Activity context;
        private OnSystemPictureSelectListener listener;
        private int aspectX = 1;
        private int aspectY = 1;
        private int outputX = 200;
        private int outputY = 200;
        private String savedPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + String.valueOf(System.currentTimeMillis()) + ".png";
        private boolean weatherCrop = true;

        public Builder(Activity context) {
            this.context = context;
        }

        public Builder isCropped(boolean weatherCrop) {
            this.weatherCrop = weatherCrop;
            return this;
        }


        /**
         * 为图片设置裁剪的区域比例
         *
         * @param aspectX width aspect
         * @param aspectY height aspect
         * @return
         */
        public Builder setCropSize(int aspectX, int aspectY) {
            this.aspectX = aspectX;
            this.aspectY = aspectY;
            return this;
        }

        /**
         * 为裁剪后的图片设置输出质量
         *
         * @param outputX output width quality
         * @param outputY output height quality
         * @return
         */
        public Builder setOutputSize(int outputX, int outputY) {
            this.outputX = outputX;
            this.outputY = outputY;
            return this;
        }

        /**
         * 为图片设置存储路径
         *
         * @param path saved path you wanted
         * @return
         */
        public Builder setOutputPath(String path) {
            this.savedPath = path;
            return this;
        }

        public Builder setOnSelectListener(OnSystemPictureSelectListener listener) {
            this.listener = listener;
            return this;
        }

        public SystemPictureSelector create() {
            return new SystemPictureSelector(this);
        }
    }

    interface OnSystemPictureSelectListener {
        void onSelectedSuccess(File file);

        void onSelectedMessage(String message);
    }
}
附上我的demo地址 点击打开链接


你可能感兴趣的:(Android7.0调用系统相册、拍照裁剪及压缩)