安卓基础--实现从系统相机,相册获取图片

安卓调用系统的相机相册采用的是隐式意图开启的方式,跟电话,短信一样,在调用系统这些功能的时候要注意两点:
1.权限。安卓手机因为型号太多,各种定制系统五花八门,所以权限处理也成了开发者的一大难题。
2.图片压缩。由于上传至服务器一般要求省流量,快速,所以一般不会上传清晰的原图,这就需要对原图进行压缩然后在上传。
这里权限处理我用的是andPermission,毕竟大神处理的还是还是很完善的,而且用法也很简单。
权限处理代码实现如下:

    public void getPermission(int requestCode) {
        if (Build.VERSION.SDK_INT >= 19) {
            AndPermission.with(this)
                    .requestCode(requestCode)//权限处理的请求码
                    .permission(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)//要申请的权限
                    .callback(permissionListener)//申请结果的回调
                    .rationale(rationaleListener)//用户拒绝后的处理
                    .start();
        }
    }
 public PermissionListener permissionListener = new PermissionListener() {
        @Override
        public void onSucceed(int requestCode, @NonNull List<String> grantPermissions) {
            //取得权限之后,乙方某些机型在失败的情况下依然返回true,最好在这里在检查一下是否拿到权限
//,如果拿到权限就可以开启相机或者相册了,在这里我没有处理
           switch (requestCode) {
                case REQUEST_PERMISSION_CAMERA:
//开启相机
                   openCamera(code);
                    break;
                case REQUEST_PERMISSION_PICTURES:
//开启相册
                   openPictures(code);
                    break;

            }

        }


    @Override
    public void onFailed(int requestCode, @NonNull List<String> deniedPermissions) {
        //重新请求权限
        if (AndPermission.hasAlwaysDeniedPermission(RegisterTwoActivity.this, deniedPermissions)) {
            // 第二种:用自定义的提示语。
            AndPermission.defaultSettingDialog(RegisterTwoActivity.this, requestCode)
                    .setTitle("权限申请失败")
                    .setMessage("您拒绝了我们必要的相机权限,应用将不能正常使用,请在设置中授权!")
                    .setPositiveButton("去设置")
                    .show();
        }

    }
};
 public RationaleListener rationaleListener = new RationaleListener() {
        @Override
        public void showRequestPermissionRationale(int requestCode, final Rationale rationale) {
            AlertDialog.newBuilder(mContext)
                    .setTitle("友好提醒")
                    .setMessage("你已拒绝必要权限,不能愉快的玩耍了")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.cancel();
                            rationale.resume();
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.cancel();
                            rationale.cancel();
                        }
                    }).show();


        }
    };

/**
* 开启相机
*
* @param code
*/

        public void openCamera(int code) {
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                uri = FileProvider.getUriForFile(registerTwoActivity, "com.longxing.driver.fileprovider", new File(SpFlag.getPicturePath(code)));//7.0 的手机不允许app获取app以外的存储路径,所以在这里用了contentProvide,把路径存放在app里面
                intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
            } else {
                uri = Uri.fromFile(new File(SpFlag.getPicturePath(code)));
                // 指定存储路径,这样就可以保存原图了
                intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
            }
            startActivityForResult(intent, code);

        }

/**
 * 开启相册
 *
 * @param code
 */
public void openPictures(int code) {
    Intent intent = new Intent();
    intent.setType("image/*");// 从所有图片中进行选择

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

        //intent.setAction(Intent.ACTION_OPEN_DOCUMENT);//以文件形式打开相册
        imageUri = FileProvider.getUriForFile(registerTwoActivity, "com.longxing.driver.fileprovider", new File(SpFlag.getPicturePath(code)));

    } else {
        //intent.setAction(Intent.ACTION_GET_CONTENT);//以文件形式打开相册
        imageUri = Uri.fromFile(new File(SpFlag.getPicturePath(code)));
    }
    registerTwoActivity.setImageUri(imageUri);
    intent.setAction(Intent.ACTION_PICK);//以图库形式打开相册,个人觉得这个方式比较人性化
    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    startActivityForResult(intent, code);
}

对相机相册返回的数据进行处理,压缩

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {

        case 1:
            try {
                saveImage(3, PhotoBean.path);
            } catch (Exception e) {
                e.printStackTrace();
                showToast("拍照失败,请重试!");
            }
            break;
        case 2:
            checkImage(data, resultCode, 1);
            break;
    }
}

压缩相机返回的图片,以及图片展示

private void saveImage(int code, String path) throws Exception {
    if (path == null || path.length() <= 0) {
        showToast("图片格式错误,请重新拍照或选择照片!");
        return;
    }
    Log.i("saveImage" + code, "" + new File(path).length());
    Bitmap photoBitmap = BitmapUtils.bitmapScale(path, 400, 600);//压缩
    String photoBitmapSmall = FileUtils.saveBitmap2(photoBitmap, path);
    if (photoBitmapSmall != null && photoBitmapSmall.length() > 0) {
        hashMap.put(code + "", photoBitmapSmall);
    }
    Log.i("hashMap", hashMap.size() + "444" + photoBitmapSmall);
    GlideImageUtils.Display(mContext, photoBitmapSmall, itvIdCardFront);
    }
}

压缩相册返回的图片,以及图片展示

private void checkImage(Intent data, int resultCode, int number) {
    if (data == null) {
        showToast("图片格式错误,请重新拍照或选择照片!");
        return;
    }
    if (resultCode == Activity.RESULT_OK) {
        try {
            Bitmap bitmap = null;
            if (null != data && null != data.getData()) {
                bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData());
            } else {
                bitmap = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(imageUri));
            }
            if (bitmap != null) {
                //把bitmap转成文件写入本地
                String path = FileUtils.saveBitmap2(bitmap, PhotoBean.path);
                saveImage(number, PhotoBean.path);
            } else {
                showToast("图片格式错误,请重新选择!");
            }

        } catch (Exception e) {
            e.printStackTrace();
            showToast("图片格式错误,请重新选择!");
        }
    }
}

压缩BitMap

public static Bitmap bitmapScale(String is, double width, double height) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true; // 设置了此属性一定要记得将值设置为false
    Bitmap bitmap = BitmapFactory.decodeFile(is);
    // 防止OOM发生
    options.inJustDecodeBounds = false;
    int mWidth = bitmap.getWidth();
    int mHeight = bitmap.getHeight();
    Matrix matrix = new Matrix();
    float scaleWidth = 1;
    float scaleHeight = 1;
    if (mWidth <= mHeight) {
        scaleWidth = (float) (width / mWidth);
        scaleHeight = (float) (height / mHeight);
    } else {
        scaleWidth = (float) (height / mWidth);
        scaleHeight = (float) (width / mHeight);
    }
    //        matrix.postRotate(90); /* 翻转90度 */
    // 按照固定大小对图片进行缩放
    matrix.postScale(scaleWidth, scaleHeight);
    Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, mWidth, mHeight, matrix, true);
    // 用完了记得回收
    bitmap.recycle();
    return newBitmap;
}

保存BitMap文件在本地

public static String saveBitmap2(Bitmap bm, String picName) {
    try {
        File file = new File(picName);
        FileOutputStream out = new FileOutputStream(file);
        bm.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();

    } catch (IOException e) {
        e.printStackTrace();
    }
    return picName;
}

猜你喜欢

转载自blog.csdn.net/fishandbean/article/details/77962296