在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文件
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以下和以上的设配