参考链接:
http://blog.youkuaiyun.com/hu5080126/article/details/53738625
http://www.jianshu.com/p/ba57444a7e69
在Android7.0以后,当app使用file:// url 共享给其他app时, 会抛出异常。
因为在android 6.0 + 权限需要 在运行时候检查, 其他app 可能没有读写文件的权限, 所以google在7.0的时候加上了这个限制。
官方推荐使用 FileProvider 解决这个问题。
1.打开相机拍照获取照片Uri,然后对图片进行压缩
2.打开相册获取选取的图片Uri,然后对图片进行压缩
打开相机和相册是不会触发任何权限问题的,如果你想获取相机或相册的图片中的Uri,即file://URI开头的Uri离开了相机或相册应用,就会触发7.0文件uri权限 FileUriExposedException
,会触发FileUriExposedException权限异常。
现在将代码贴下来:
private static final int NEED_CAMERA = 200; private static final int RESULT_PICK = 201;
/** * 从TakePhotoPopWin获取的onClickListener * 点击PopuWindow上的照相或者从相册中选取图片 功能1 */ private View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { //照相 case R.id.btn_take_photo: //检测是否有相机和读写文件权限 if (ContextCompat.checkSelfPermission(UIUtils.getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(UIUtils.getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { getActivity().requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, NEED_CAMERA); } else { //打开相机获取图片 startCamera(); } break; //从相册选择图片 case R.id.btn_pick_photo: if (ContextCompat.checkSelfPermission(UIUtils.getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { getActivity().requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, RESULT_PICK); } else { //选择图片 startPickPhoto(); } break; } } };
/** * date: 2017/7/5 10:59 * autour: HelenChen * description: 选择图片 */ private void startPickPhoto() { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(Intent.createChooser(intent, "请选择图片"), RESULT_PICK); takePhotoPopWin.hiddPop(); }
/** * 打开相机获取图片 */ private void startCamera() { File imagePath = new File(Environment.getExternalStorageDirectory(), "images"); if (!imagePath.exists()) imagePath.mkdirs(); newFile = new File(imagePath, "point_image.jpg"); //第二参数是在manifest.xml定义 provider的authorities属性 contentUri = FileProvider.getUriForFile(UIUtils.getContext(), "com.example.administrator.im_demo.fileprovider", newFile); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //兼容版本处理,因为 intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) 只在5.0以上的版本有效 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { ClipData clip = ClipData.newUri(getActivity().getContentResolver(), "A photo", contentUri); intent.setClipData(clip); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } else { List<ResolveInfo> resInfoList = getActivity().getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { String packageName = resolveInfo.activityInfo.packageName; getActivity().grantUriPermission(packageName, contentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } } intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri); startActivityForResult(intent, NEED_CAMERA); takePhotoPopWin.hiddPop(); }
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case NEED_CAMERA: // 如果权限被拒绝,grantResults 为空 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //打开相机获取图片 startCamera(); } else { Toast.makeText(UIUtils.getContext(), "需要相机和读写文件权限", Toast.LENGTH_SHORT).show(); } break; case RESULT_PICK: // 如果权限被拒绝,grantResults 为空 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //选择图片 startPickPhoto(); } else { Toast.makeText(UIUtils.getContext(), "需要读取权限", Toast.LENGTH_SHORT).show(); } break; } }
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case NEED_CAMERA: ContentResolver contentProvider = getActivity().getContentResolver(); ParcelFileDescriptor mInputPFD; try { //获取contentProvider图片 mInputPFD = contentProvider.openFileDescriptor(contentUri, "r"); FileDescriptor fileDescriptor = mInputPFD.getFileDescriptor(); iv_company_bk.setImageBitmap(BitmapFactory.decodeFileDescriptor(fileDescriptor)); } catch (FileNotFoundException e) { e.printStackTrace(); } break; //选择照片 case RESULT_PICK: try { Uri uri = data.getData(); //打开圆形裁剪图界面 String path = Utils.getRealFilePathFromUri(getActivity().getApplicationContext(), uri); Bitmap bitmaps = BitmapUtil.decodeSampledBitmap(path, 720, 1280); iv_company_bk.setImageBitmap(bitmaps); /** * 请求网络,将图片上传到服务器 */ //upLoadImg(path); }catch (Exception e){ e.printStackTrace(); } break; } }