android7.0拍照照片裁剪

大多项目都会用到上传图片的功能,实现这一的功能有2种方式:

  1. 自己实现图片的获取和裁剪
  2. 调用系统其他程序实现功能

在这次项目中,我用到了第二种,即:
用Intent.ACTION_PICK获取图片
用MediaStore.ACTION_IMAGE_CAPTURE拍照
用com.android.camera.action.CROP裁剪

这种方式在targetSdkVersion>=24,运行的目标api>=24的时候,系统默认采用新的规则
中文官网是这么描述的:

对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode
API 政策禁止在您的应用外部公开 file://
URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException
异常。
要在应用间共享文件,您应发送一项 content://
URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider
类。如需了解有关权限和共享文件的详细信息,请参阅共享文件。

对于这种规则,有以下2种方案解决
1.保守者,不打算遵守规则

    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.setVmPolicy(builder.build());

这将使程序按照之前的规则执行(在api25测试可用)

2.做个遵守规则的好司机
2.1.在AndroidManifest.xml的application标签中申明FileProvider

    
        
    

name是固定的
exported也是固定的
grantUriPermissions我觉得也是固定的
authorities一般是这样写的

2.2.创建共享目录文件说明文件xml/provider_paths.xml



    
    

这里external-path是其中一种标签,还有其他的,根据自己需求使用
path是路径,用“.”代表整个目录

2.3.将传递的file:// URI替换为content:// URI

FileProvider.getUriForFile(context,
                authorities,
                imageFile);

v4兼容包提供的工具类

2.4.增加Uri权限

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

2.5.前面几个步骤,已经可以执行获取图片,拍照,并且调用到裁剪,但是呢,裁剪点击完成,文件无法输出到目标文件,这里得用代码让com.android.camera.action.CROP也获取Uri权限

    Context context = provider.getContext();
    List resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        context.grantUriPermission(packageName, uri , Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }

3.最后在实际使用中,用户可能装了多个相册类型的app,然后发现有些app返回的uri是共享文件,但是直接操作这个uri会报没有权限,我这里测试了谷歌相册,返回的uri为content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F485/ORIGINAL/NONE/613973819,我不管用把这个uri发到哪里处理,都提示没有权限,包括谷歌相册,我也不晓得要怎么获取这个uri的权限。最后我的解决方案为把这样的uri先转成实际路径,再转成共享文件。

你可能感兴趣的:(android7.0拍照照片裁剪)