Android - Android7.0相机拍照的异常处理

转载请注明出处:https://blog.csdn.net/mythmayor/article/details/76058746

1.对于权限的问题,大家都知道,Android6.0引入了动态权限控制(Runtime Permissions),Android7.0引入了私有目录被限制访问。在使用Android7.0的设备进行拍照的时候发现Crash掉了,于是找了一些官方的解决方案,现记录如下。

2.解决步骤:

(1)在manifest清单文件中注册provider
<!--android7.0拍照 需要注册FileProvider-->
<provider
     android:name="android.support.v4.content.FileProvider"
     android:authorities="包名.fileprovider"
     android:grantUriPermissions="true"
     android:exported="false">
     <meta-data
           android:name="android.support.FILE_PROVIDER_PATHS"
           android:resource="@xml/file_paths" />
</provider>
<root-path/> 代表设备的根目录new File("/");
<files-path/> 代表context.getFilesDir()
<cache-path/> 代表context.getCacheDir()
<external-path/> 代表Environment.getExternalStorageDirectory()
<external-files-path>代表context.getExternalFilesDirs()
<external-cache-path>代表getExternalCacheDirs()

也就是在application内加了一个provider,其中,name是固定的,android:authorities是你的应用包名+“.fileprovider”,其实这里不一定要写fileprovider,可以随便写,只是要与后面FileProvider.getUriForFile()这个方法中的第二个参数authority对应起来即可。android:grantUriPermissions固定true,表示uri访问授权,android:exported固定的false,android:resource表示我们app要共享文件的路径的资源文件.

(2)指定共享目录。在res目录下创建xml目录,并在xml目录下创建文件file_paths

file_paths文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--指定共享目录-->
    <paths>
        <external-path
            name="camera_photos"
            path="" />
    </paths>
</resources>

为了指定共享的目录我们需要在资源(res)目录下创建一个xml目录,然后创建一个名为“file_paths”(名字可以随便起,只要和在manifest注册的provider所引用的resource保持一致即可)的资源文件。
上述代码中 path=”” ,是有特殊意义的,它代码根目录,也就是说你可以向其它的应用共享根目录及其子目录下任何一个文件了,如果你将path设为 path=”pictures” ,那么它代表着根目录下的pictures目录(eg:/storage/emulated/0/pictures),如果你向其它应用分享pictures目录范围之外的文件是不行的。

(3)在java代码中使用FileProvider
 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

if (Build.VERSION.SDK_INT >= 24) {
     intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
     //24以上使用FileProvider
      intent.putExtra(MediaStore.EXTRA_OUTPUT, 
      FileProvider.getUriForFile(getContext(), "包名.fileprovider", file));
}else{
     //24以下
     intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
}
(4)下面再针对相机拍照和图片裁剪给出相应代码
(一)相机拍照

①Android7.0之前

File file=new File(Environment.getExternalStorageDirectory(), "/temp/"+System.currentTimeMillis() + ".jpg");
if (!file.getParentFile().exists())file.getParentFile().mkdirs();
Uri imageUri = Uri.fromFile(file);
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照片保存到指定URI
startActivityForResult(intent,1006);

②Android7.0

File file=new File(Environment.getExternalStorageDirectory(), "/temp/"+System.currentTimeMillis() + ".jpg");
if (!file.getParentFile().exists())file.getParentFile().mkdirs();
Uri imageUri = FileProvider.getUriForFile(context, "包名.fileprovider", file);//通过FileProvider创建一个content类型的Uri
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照片保存到指定URI
startActivityForResult(intent,1006);
(二)图片裁剪

①Android7.0之前

File file=new File(Environment.getExternalStorageDirectory(), "/temp/"+System.currentTimeMillis() + ".jpg");
if (!file.getParentFile().exists())file.getParentFile().mkdirs();
Uri outputUri = Uri.fromFile(file);
Uri imageUri=Uri.fromFile(new File("/storage/emulated/0/temp/1474960080319.jpg"));
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(imageUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true); // no face detection
startActivityForResult(intent,1008);

②Android7.0

File file=new File(Environment.getExternalStorageDirectory(), "/temp/"+System.currentTimeMillis() + ".jpg");
if (!file.getParentFile().exists())file.getParentFile().mkdirs();
Uri outputUri = FileProvider.getUriForFile(context, "包名.fileprovider",file);
Uri imageUri=FileProvider.getUriForFile(context, "包名.fileprovider", new File("/storage/emulated/0/temp/1474960080319.jpg");//通过FileProvider创建一个content类型的Uri
Intent intent = new Intent("com.android.camera.action.CROP");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(imageUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true); // no face detection
startActivityForResult(intent,1008);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值