You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Nougat下FileProvider存储相机图片至指定目录异常求助

Fixing FileProvider "Failed to find configured root" Exception for Public External Storage

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 by getExternalFilesDir(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 what Environment.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

  1. 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 IOException when trying to create the image file.

  2. Runtime Permissions: For Android 6.0 (API 23) and above, you need to request the WRITE_EXTERNAL_STORAGE runtime 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:14:59