960/E: Wrapped com.stardust.pio.UncheckedIOException: java.io.FileNotFoundException: /storage/emulated/0/temp_moutai.js: open failed: EPERM (Operation not permitted) (6a0f1b2617efb8b210de215f.js#35)
Wrapped com.stardust.pio.UncheckedIOException: java.io.FileNotFoundException: /storage/emulated/0/temp_moutai.js: open failed: EPERM (Operation not permitted)
at main (6a0f1b2617efb8b210de215f.js:35:0)
at 6a0f1b2617efb8b210de215f.js:46:0
回答
这个错误是由于 Android 10 及以上版本引入了分区存储(Scoped Storage)机制,系统严格限制应用直接访问 /storage/emulated/0/(内部存储根目录)。EPERM (Operation not permitted) 表示操作系统层面拦截了该文件操作,并非文件不存在。
你可以通过以下方式解决:
1. 更换为应用专属存储路径(推荐)
将文件读写路径修改为 Hamibot 的应用专属外部存储目录,该目录不受分区存储限制,且无需额外权限。
// 文档地址 https://docs.hamibot.com/
var appDir = context.getExternalFilesDir(null).getAbsolutePath();
var targetDir = files.join(appDir, "temp");
if (!files.exists(targetDir)) {
files.createWithDirs(targetDir);
}
var filePath = files.join(targetDir, "temp_moutai.js");
// 示例:写入文件
files.write(filePath, "脚本内容");
// 示例:读取文件
var content = files.read(filePath);
2. 检查 Hamibot 存储权限
进入手机系统设置 -> 应用管理 -> Hamibot -> 权限,确保 存储 权限已开启。对于 Android 11/12/13 设备,部分厂商系统可能还需要在 特殊权限设置 中开启 所有文件访问权限。但使用方案1的路径可完全规避此要求。
3. 使用脚本相对路径
如果 temp_moutai.js 是你脚本工程内的附属文件,建议直接将其放在脚本同级目录,使用相对路径引用:
// 文档地址 https://docs.hamibot.com/
var filePath = files.path("./temp_moutai.js");
if (files.exists(filePath)) {
var content = files.read(filePath);
}
最佳实践建议:
- 避免硬编码
/storage/emulated/0/或files.getSdcardPath()作为根路径进行读写,Android 10+ 环境下极易触发EPERM或EACCES。 - 文件操作前务必使用
files.exists()校验路径,使用files.createWithDirs()确保父目录存在。 - 若需跨应用共享文件,请使用
app.viewFile()或系统分享 Intent,而非直接暴露根目录路径。
调整路径后重新运行脚本即可解决该报错。如第35行涉及其他特定文件操作逻辑,可提供该行代码以便进一步定位。