Android6.0调用系统相机拍照、访问相册

在Android6.0中Google提出了动态申请权限的Api,调用相机拍照,访问SDcard等操作都需要先申请对应的权限如下:

android:name="android.permission.CAMERA" />                    //相机权限
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    //写入sd卡
android:name="android.permission.READ_EXTERNAL_STORAGE" />     //读取sd卡   

安卓6.0权限动态检查我使用一下的动态检查库

'com.tbruyelle.rxpermissions2:rxpermissions:0.9.3@aar'
public static void requestAllPermissions(final Activity mActivity) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        RxPermissions rxPermission = new RxPermissions(mActivity);
        rxPermission.requestEach(
                Manifest.permission.READ_EXTERNAL_STORAGE,//sd卡读取
                Manifest.permission.WRITE_EXTERNAL_STORAGE,//sd卡写入
                Manifest.permission.CAMERA //相机
        )
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Permission permission) throws Exception {
                        if (permission.granted) {
                            // 用户已经同意该权限

                        } else if (permission.shouldShowRequestPermissionRationale) {
                            // 用户拒绝了该权限,没有选中『不再询问』(Never ask again),那么下次再次启动时,还会提示请求权限的对话框

                        } else {
                            //引导用户去系统设置开启权限
                            Uri packageURI = Uri.parse("package:" + mActivity.getPackageName());
                            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                            mActivity.startActivity(intent);
                        }
                    }
                });
    }
}
//选择系统相册 requestCode == 0 代表是选择系统相册的回调,当等于0时取到图片数据
private void takePhoto() {
    Intent albumIntent = new Intent(Intent.ACTION_PICK, null);
    albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
    startActivityForResult(albumIntent, 0);
}
//拍照 requestCode == 1 是调用相机进行拍摄
private void takeCamera() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    String cameraFielPath = getApplication().getExternalCacheDir().getPath() + "/Camera.jpg";//图片存放在手机自带内存,地址在你的包名文件夹下
    File outputImage = new File(cameraFielPath);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
        //根据6.0的要求需要对文件传输使用新的传输方式FileProvider,没有配置FileProvider 安卓6.0会报错退出当前activity
        //通过FileProvider创建一个content类型的Uri
        Uri imageUrl = FileProvider.getUriForFile(WebActivity.this, "com.android.provider", outputImage);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUrl);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//对读取对Url进行临时授权
    }else {
        //6.0以下不做处理直接使用没问题
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outputImage));
    }
    startActivityForResult(intent, 1);
}
FileProvider的配置  找到开发目录中的AndroidManifest.xml文件打开并添加如下代码:


    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.android.provider.provider"
    android:exported="false"
    android:grantUriPermissions="true">
            android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />

然后在安卓中的res资源目录下的xml目录下创建一个file_paths.xml文件

Android6.0调用系统相机拍照、访问相册_第1张图片

file_paths.xml  文件如下

xml version="1.0" encoding="utf-8"?>

    //name根据自己来随便起,path路径是你存放图片的地址,也可以不填默认全目录
    name="camera_photos" path="" />

以上都配置完毕之后就可以接收回调了:

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

    Uri result = null;
    if (requestCode == 1) {
        if (null != data && null != data.getData()) {
            //选择相机照相后的图片
            result = Uri.fromFile(new File(cameraFielPath));
            Bitmap bitmap = BitmapFactory.decodeFile(cameraFielPath);
            compressImageToFile(bitmap, new File(cameraFielPath));//图片压缩
        }
        
    } else if (requestCode == 0) {
        if (data != null) {
            result = data.getData();
            //选择相册的图片
        }
    }
}
//图片压缩
public static void compressImageToFile(Bitmap bmp, File file) {
    // 0-100 100为不压缩
    int options = 20;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // 把压缩后的数据存放到baos中
    bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
    try {
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(baos.toByteArray());
        fos.flush();
        fos.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
这样就完成了6.0以下和以上的设配



你可能感兴趣的:(Android)