Android 调用拍照、相册、裁剪兼容8.0以上的二种方式

这段代码展示了在Android应用中如何调用相机和相册选择图片,然后进行系统裁剪处理。针对华为和小米设备的兼容性问题进行了特殊处理,包括设置裁剪比例和处理圆形裁剪框。

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

第一种

	private String mPhotoPath;
    private File mPhotoFile;
    private Uri imageUri;

    /**
     * 调用手机相机
     */
    private void openCamera() {
        mPhotoPath = App.getInstance().getAppCacheDir() + UUID.randomUUID().toString() + ".jpg";
        mPhotoFile = new File(mPhotoPath);
        Intent intentCamera = new Intent();
        getFileUri(mPhotoFile);
        intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        startActivityForResult(intentCamera, PHOTO_REQUEST_CAMERA);
    }

    /**
     * 调用手机相册
     */
    private void openAlbum() {
        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, PHOTO_REQUEST_GALLERY);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //调用相册,返回结果
        if (requestCode == PHOTO_REQUEST_GALLERY && resultCode == Activity.RESULT_OK) {
            Cursor cursor = getContentResolver().query(data.getData(), new String[]{MediaStore.Images.Media.DATA}, null, null, null);
            //游标移到第一位,即从第一位开始读取
            if (cursor != null) {
                cursor.moveToFirst();
                mPhotoPath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
                cursor.close();
                //调用系统裁剪
                mPhotoFile = new File(mPhotoPath);
                getFileUri(mPhotoFile);
                startPhoneZoom(imageUri);
            }
        }

        //调用相机,返回结果
        if (requestCode == PHOTO_REQUEST_CAMERA && resultCode == Activity.RESULT_OK) {
            startPhoneZoom(imageUri);
        }
        //调用系统裁剪,返回结果
        if (requestCode == PHOTO_REQUEST_CROP_PHOTO && resultCode == Activity.RESULT_OK) {
            //设置裁剪返回的位图
            Bundle bundle = data.getExtras();
            if (bundle != null) {
                Bitmap bitmap = bundle.getParcelable("data");
                feedbackImg.setImageBitmap(bitmap);
                Logger.d(TAG, "--------------bitmap------------" + bitmap);
                mFilePath = ImageUtils.saveBitmap(this, bitmap, App.getInstance().getImageCacheDir());
                delImg.setVisibility(View.VISIBLE);
            }
        }
    }

    private Uri getFileUri(File mAvatarFile) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            imageUri = FileProvider.getUriForFile(this, "com.cds.iot.fileprovider", mAvatarFile);
        } else {
            imageUri = Uri.fromFile(mAvatarFile);
        }
        return imageUri;
    }

    /**
     * 调用系统裁剪的方法
     */
    private void startPhoneZoom(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        intent.setDataAndType(uri, "image/*");
        //是否可裁剪
        intent.putExtra("corp", "true");
        //是否压缩
        intent.putExtra("scale", true);
        //裁剪器高宽比
        if (android.os.Build.MODEL.contains("HUAWEI")
                || Build.MANUFACTURER.equals("HUAWEI")) {//华为机特殊处理,防止裁剪框为圆形
            intent.putExtra("aspectX", 9998);
            intent.putExtra("aspectY", 9999);
        } else {
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 1);
        }
        //设置裁剪框高宽
        intent.putExtra("outputX", 300);
        intent.putExtra("outputY", 300);
        //返回数据
        intent.putExtra("return-data", true);
//        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        startActivityForResult(intent, PHOTO_REQUEST_CROP_PHOTO);
    }
    
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(!TextUtils.isEmpty(mFilePath)){
            File file = new File(mFilePath);
            file.delete();//删除临时文件
        }
    }

2.第二种(强烈推荐,兼容华为圆形裁剪、小米裁剪崩溃等兼容性问题)

private String mPhotoPath;
private File mPhotoFile;
private File mAvatarFile;
private Uri imageUri;

/**
 * 调用手机相机
 */
private void openCamera() {
    mPhotoPath = App.getInstance().getAppCacheDir() + UUID.randomUUID().toString() + ".jpg";
    mPhotoFile = new File(mPhotoPath);
    Intent intentCamera = new Intent();
    getFileUri(mPhotoFile);
    intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
    intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    startActivityForResult(intentCamera, PHOTO_REQUEST_CAMERA);
}

/**
 * 调用手机相册
 */
private void openAlbum() {
    Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(intent, PHOTO_REQUEST_GALLERY);
}


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Logger.i(TAG, "onActivityResult requestCode:" + requestCode + ",resultCode:" + resultCode);
    if (requestCode == CHANGE_PHONE && resultCode == RESULT_OK) {
        mPresenter.getUserInfo(userId);
    }
    if (requestCode == PHOTO_REQUEST_GALLERY && resultCode == RESULT_OK) {
        //调用相册
        Cursor cursor = getContentResolver().query(data.getData(), new String[]{MediaStore.Images.Media.DATA}, null, null, null);
        //游标移到第一位,即从第一位开始读取
        if (cursor != null) {
            cursor.moveToFirst();
            mPhotoPath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            cursor.close();
            //调用系统裁剪
            mPhotoFile = new File(mPhotoPath);
            getFileUri(mPhotoFile);
            startPhoneZoom(imageUri);
        }
    }

    if (requestCode == PHOTO_REQUEST_CAMERA && resultCode == RESULT_OK) {
        //相机返回结果,调用系统裁剪
        startPhoneZoom(imageUri);
    }
    if (requestCode == PHOTO_REQUEST_CROP_PHOTO && resultCode == RESULT_OK) {
        Picasso.with(this)
                .load(mAvatarFile)
                .transform(new PicassoCircleTransform())
                .into(headImg);

        mUserInfo.setHead_img(mAvatarFile.getAbsolutePath());
        mPresenter.updateUserInfo(mUserInfo);
    }
}

private Uri getFileUri(File mAvatarFile) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        imageUri = FileProvider.getUriForFile(this, "com.cds.iot.fileprovider", mAvatarFile);
    } else {
        imageUri = Uri.fromFile(mAvatarFile);
    }
    return imageUri;
}

/**
 * 调用系统裁剪的方法
 */
private void startPhoneZoom(Uri uri) {
    mAvatarFile = new File(App.getInstance().getAppCacheDir(), UUID.randomUUID().toString() + ".jpg");//这个是创建一个截取后的图片路径和名称。
    try {
        if (mAvatarFile.exists()) {
            mAvatarFile.delete();
        }
        mAvatarFile.createNewFile();
    } catch (IOException e) {
        e.printStackTrace();
    }
    imageUri = Uri.fromFile(mAvatarFile);

    Intent intent = new Intent("com.android.camera.action.CROP");
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    }
    intent.setDataAndType(uri, "image/*");
    //是否可裁剪
    intent.putExtra("corp", "true");
    //是否压缩
    intent.putExtra("scale", true);
    //裁剪器高宽比
    if (android.os.Build.MODEL.contains("HUAWEI")
                || Build.MANUFACTURER.equals("HUAWEI")) {//华为机特殊处理,防止裁剪框为圆形
            intent.putExtra("aspectX", 9998);
            intent.putExtra("aspectY", 9999);
        } else {
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 1);
        }
    //设置裁剪框高宽
    intent.putExtra("outputX", 300);
    intent.putExtra("outputY", 300);

    intent.putExtra("return-data", false);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
    intent.putExtra("noFaceDetection", true); // no face detection
    startActivityForResult(intent, PHOTO_REQUEST_CROP_PHOTO);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (mAvatarFile != null) {
        mAvatarFile.delete();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值