原生代码访问Android应用数据文件夹文件遇SELinux权限拒绝问题
解决Android原生代码访问应用数据文件夹被SELinux限制的问题
核心问题分析
你遇到的权限拒绝并非普通文件权限问题,而是Android 10+分区存储策略结合SELinux强制访问控制导致的——即使你申请了外部存储权限,直接硬编码路径访问Android/data下的自有目录也会被拦截,尤其是目录遍历操作更容易触发限制。
具体解决方案
不要硬编码路径,通过Java层传递合法路径
放弃直接写死/storage/emulated/0/Android/data/appname/files/...,改用Java系统API获取应用专属外部目录路径,再传递给原生层:// Java层获取Documents目录路径 File docDir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS); String modelFilePath = new File(docDir, "model.bin").getAbsolutePath(); // 通过JNI传递给C++代码这种方式获取的路径是系统认可的,SELinux会允许应用访问。
移除不必要的目录遍历操作
报错指向directory_iterator,说明你的代码在尝试遍历目录(比如当前目录.),而SELinux限制了这种遍历行为。直接访问具体文件路径即可,无需提前遍历目录。简化后的C++代码:#include <cstring> #include <fstream> #include <android/log.h> #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "NativeFile", __VA_ARGS__) void loadModel(const char* modelPath) { std::ifstream f(modelPath, std::ios::binary); if (!f.is_open()) { LOGE("Open file failed: %s", strerror(errno)); return; } // 后续文件操作 }适配Android存储策略
- Android 10(API 29)及以上:默认启用分区存储,应用无需申请
READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE权限即可访问自有Android/data目录,但必须通过系统API获取路径。 - Android 11+:强制分区存储,即使申请旧权限也无法直接硬编码访问其他应用目录,自有目录也必须通过合法路径访问。
- Android 10(API 29)及以上:默认启用分区存储,应用无需申请
检查Manifest配置
确保未错误启用旧存储模式(Android 11+会忽略该配置,但避免混淆):<application android:requestLegacyExternalStorage="false"> <!-- 其他配置 --> </application>
内容的提问来源于stack exchange,提问作者Ronith
相关产品推荐
相关产品推荐

