On Android 7.0 mobile phone, call the system camera with the old method to take photos and keep throwing. FileUriExposedException is abnormal. This is because Android 7.0 forces a policy called StrictMode to be enabled, and App cannot expose URI of file: / /. If you use Intent to open an external App with such a URI (for example, open the system camera to take a picture), you will throw a FileUriExposedException exception. Official FileProvider, solution.
The specific steps are as follows:
1. Create the folder XML in the res directory, and create the file [paths.xml file. The location is as follows:
Arbitrary xml file name
The contents of the xml file are as follows:
<?xml version="1.0" encoding="utf-8"?> <resources> <!--<files-path/> //The root of the delegate: Context.getFilesDir() <external-path/> //Root directory represented: Environment.getExternalStorageDirectory() <cache-path/> //Root directory represented: getCacheDir() <root-path/> //External SD card --> <external-path name="external_files" path=""> </external-path> </resources>
2. In the Manifest.xml file, under the application tab:
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.xxx.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/image_paths" /> </provider>
xxx content is optional, preferably package name, and cannot be the same as other projects
3. Get Uri method:
private Uri getPhotoUri() { Uri imageUri = null; String sdDir = Environment.getExternalStorageDirectory().getAbsolutePath(); String fileName = "new_photo.jpg"; String path = sdDir + String.format("/%s/%s", "AAAA", fileName); File file = new File(path); file.getParentFile().mkdirs(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { try { imageUri = FileProvider.getUriForFile(this, "com.xxx.fileprovider", file); } catch (Exception e) { e.printStackTrace(); } } else { imageUri = Uri.fromFile(file); } return imageUri; }
4. System camera call method:
private void jumpToTakePhoto() { myUri = getPhotoUri();//myUri is the global Uri variable Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//Photograph cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, getPhotoUri()); cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//Add flag here startActivityForResult(cameraIntent, TAKEPHOTO_CODE); }
5. Apply for permission and take photos:
private void getPermissionAndTakePhoto(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//Android version greater than 6.0, dynamic application permission int checkCallPhonePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA); if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[] , REQUEST_CARME_STATE); } else { jumpToTakePhoto();//Permission has been applied, take photos directly } } else { jumpToTakePhoto();//Android version is less than 6.0, take photos directly } }
Permission application result processing:
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == REQUEST_CARME_STATE && grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { jumpToTakePhoto();//Permission application succeeded, take photos } }
6. After taking photos, return to the display:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Uri result=null; if (TAKEPHOTO_CODE == requestCode) { if (resultCode == RESULT_OK) { try { if(bitmap!=null){ bitmap.recycle();//Recycle and release the image resources, otherwise the OOM will be abnormal when shooting again } //When photographing returns, obtain the file from the path and turn it into Bitmap, and display it to imageView bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(getPhotoUri())); imageView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } } }
The first time I did it, it was all pictures. Some of the pictures didn't show, which was embarrassing...