Android Nougat下FileProvider存储相机图片至指定目录异常求助
Hey Andrea, let's sort out this FileProvider issue you're hitting on Nougat devices! The core problem here boils down to misunderstanding what each FileProvider path tag actually points to.
Why <external-files-path> Isn't Working
First, let's clarify the key difference between the two path tags you're testing:
<external-files-path>maps to your app's private external storage directory—this is the path returned bygetExternalFilesDir(null)(usually something like/storage/emulated/0/Android/data/com.insulinpower.android/files). This directory is tied exclusively to your app, and it's not the public storage location you're trying to use (/storage/emulated/0/InsulinPower/amSignTool/Data), so FileProvider can't find your file here.<external-path>maps to the root of public external storage (exactly whatEnvironment.getExternalStorageDirectory()returns:/storage/emulated/0). This is the correct tag for your target directory, which is why it works when you use it.
Correct FileProvider Configuration
Since your image needs to be stored in a public external storage subdirectory, update your file_paths.xml to use <external-path> with the correct relative path:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Maps to /storage/emulated/0, with the subpath pointing to your target directory --> <external-path name="my_data" path="InsulinPower/amSignTool/Data/" /> </paths>
⚠️ Note: Don't start the path value with a leading slash—<external-path> already references the root of public storage, so we just add the relative subdirectory path.
Additional Critical Checks
Ensure Directory Exists: Before creating your picture file, make sure the target directory exists. Add this logic in your
amPictureFile()method:File targetDir = new File(Environment.getExternalStorageDirectory(), "InsulinPower/amSignTool/Data"); if (!targetDir.exists()) { targetDir.mkdirs(); // Creates all missing parent directories }This prevents
IOExceptionwhen trying to create the image file.Runtime Permissions: For Android 6.0 (API 23) and above, you need to request the
WRITE_EXTERNAL_STORAGEruntime permission before writing to public external storage. Make sure your app handles this permission request flow—without it, your file creation will fail silently or throw an exception.
Keep Your Existing Version Logic
Your current code for handling KitKat vs. newer versions is correct:
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { this.imageToUploadUri = Uri.fromFile(pictureFile); } else { this.imageToUploadUri = FileProvider.getUriForFile( this, "com.insulinpower.android.fileprovider", pictureFile ); }
With the corrected file_paths.xml, this code will work as expected on Nougat and newer devices.
内容的提问来源于stack exchange,提问作者Andrea Montanari

