学习http://blog.csdn.net/lmj623565791/article/details/72859156
Android7.0之前的拍照常规实现代码
public void takePhoto() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
String filename = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.CHINA)
.format(new Date()) + ".png";
File file = new File(Environment.getExternalStorageDirectory() + "/zz/", filename);
mCurrentPhotoPath = file.getAbsolutePath();
Uri fileUri = Uri.fromFile(file);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(takePictureIntent, REQUEST_CODE_TAKE_PHOTO);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_TAKE_PHOTO) {
image.setImageBitmap(BitmapFactory.decodeFile(mCurrentPhotoPath));
}
}
Uri.fromFile(file)//为file:///storage/emulated/0/zz/20180607-163315.png 此代码在android7.0一下的系统运行正常,但是运行在android7.0上就会崩溃 原因是android7.0禁止应用对外公开;如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障, 并出现 FileUriExposedException 异常。 google给出的解决方案是:要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。 进行此授权的最简单方式是使用 FileProvider 类。 于是代码改为:
public void takePhoto() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
String filename = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.CHINA)
.format(new Date()) + ".png";
//对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。
// 如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。
//官方解决方案:要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。
// 进行此授权的最简单方式是使用 FileProvider 类。如需了解有关权限和共享文件的详细信息,请参阅共享文件。
File file = new File(Environment.getExternalStorageDirectory() + "/zz/", filename);
mCurrentPhotoPath = file.getAbsolutePath();
Uri fileUri = null;
if (Build.VERSION.SDK_INT > 23) {
/**Android 7.0以上的方式**/
fileUri = FileProvider.getUriForFile(this, "com.cyz.android7.fileprovider", file);
} else {
fileUri = Uri.fromFile(file);
}
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(takePictureIntent, REQUEST_CODE_TAKE_PHOTO);
System.out.println(fileUri+" "+Uri.fromFile(file));
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_TAKE_PHOTO) {
image.setImageBitmap(BitmapFactory.decodeFile(mCurrentPhotoPath));
}
}
清单文件添加
添加xml文件file_paths.xml
这样得到的fileUrl为
/**
* 申请权限
*/
public void requestPower() {
//判断是否已经赋予权限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//这里可以写个对话框之类的项向用户解释为什么要申请权限,并在对话框的确认键后续再次申请权限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_REQUEST_PERMISSION);
} else {
//申请权限,字符串数组内是一个或多个要申请的权限,REQUEST_CODE_REQUEST_PERMISSION是申请权限结果的返回参数,
// 在onRequestPermissionsResult可以得知申请结果
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,}, REQUEST_CODE_REQUEST_PERMISSION);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_REQUEST_PERMISSION) {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "" + "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "" + "权限" + permissions[i] + "申请失败", Toast.LENGTH_SHORT).show();
}
}
}
}
代码 点击打开链接