Android API 35调用Context.openFileOutput()触发IOException权限拒绝问题
解决API35中Context.openFileOutput()抛出EACCES的问题
问题原因
Android 14(API35)对应用私有目录的文件操作新增了更严格的校验规则:
- 禁止通过
openFileOutput()传入包含路径分隔符(如/)的文件名,这类操作在API34及以下版本可能被静默兼容(比如自动截断路径),但API35会直接抛出权限拒绝异常。 - 对文件名中的非法字符(如
\,:,*,?等)校验更严格,不符合规范的文件名会触发权限错误。
解决方案
1. 修正文件操作逻辑
如果需要保存到子目录,不要直接通过openFileOutput()指定路径,而是先创建目标目录,再通过File类直接操作文件。修改后的代码示例:
void save(Context context, String fileName) { String xmlFileName = fileName.endsWith(EXT_XML) ? fileName : fileName + EXT_XML; // 基于应用私有files目录构建目标文件对象 File targetFile = new File(context.getFilesDir(), xmlFileName); // 自动创建所需的父目录(如果包含子路径) if (!targetFile.getParentFile().exists()) { targetFile.getParentFile().mkdirs(); } FileOutputStream xmlFos; try { xmlFos = new FileOutputStream(targetFile); } catch (IOException ex) { throw new RuntimeException(ex.getMessage()); } serializeXml(xmlFos); }
2. 校验文件名合法性
确保传入的fileName不包含路径分隔符或非法字符。如果业务需要支持子目录,提前对文件名做拆分处理,先创建子目录再创建文件。
3. 适配targetSdkVersion规则
如果应用targetSdkVersion升级到35,需注意:
openFileOutput()仅适用于直接在应用私有files根目录下创建文件,不能指定子路径。- 所有私有目录的文件操作,优先使用
context.getFilesDir()结合File类实现,避免依赖旧API的兼容行为。
内容的提问来源于stack exchange,提问作者David Singleton
相关产品推荐
相关产品推荐

