
Momentum-Firmware 的 JS 文件选择器gui/file_picker 模块与 pickFile 实战指南【免费下载链接】Momentum-Firmware Feature-rich, stable and customizable Flipper Firmware项目地址: https://gitcode.com/GitHub_Trending/mo/Momentum-Firmware导读在 Flipper 固件的 JS 脚本生态中让用户从设备存储中选择一个文件是许多脚本如解析协议文件、读取配置、选择资产的刚需。Momentum-Firmware 通过gui/file_picker模块提供pickFile()函数以极简的参数设计起始路径 扩展名过滤弹出一个原生文件浏览对话框并返回所选文件的绝对路径。读完本文你将掌握该 API 的完整签名、扩展名过滤规则、取消分支处理以及它背后从 JS 模块到dialogs系统服务的完整调用链。一、模块定位一个 Prompt 函数而非 GUI 视图js_gui__file_picker在文档中被明确描述为Allows asking the user to select a file. It is not GUI view like other JS GUI views, rather just a function that shows a prompt.这意味着它与其他 JS GUI 模块如gui/dialog、gui/submenu、gui/text_input等视图有本质区别视图模块通常需要与viewDispatcher、事件循环event_loop配合先创建视图、注册回调、切换显示再异步等待用户交互事件文件选择器则是一个同步阻塞式函数调用调用即弹出对话框用户完成选择或取消后函数直接返回结果脚本继续向下执行。这种设计让文件选择成为脚本里即用即走的一个步骤非常适合需要先选定文件再做后续处理的线性流程脚本。从源码结构看该模块注册的模块名是gui__file_picker内部 ID在 JS 侧通过require(gui/file_picker)导入。相关文件如下JS 模块实现applications/system/js_app/modules/js_gui/file_picker.cTypeScript 类型声明applications/system/js_app/packages/fz-sdk/gui/file_picker.d.ts官方示例脚本applications/system/js_app/examples/apps/Scripts/Examples/gui.js二、API 参考pickFile() 完整说明pickFile()是gui/file_picker模块导出的唯一函数对应底层 C 实现js_gui_file_picker_pick_file。函数签名// 来自 file_picker.d.tsJS SDK 0.1 引入 declare function pickFile(basePath: string, extension: string): string | undefined;参数详解参数类型必填说明basePathstring是文件浏览器启动时所在的起始目录路径extensionstring是要展示的文件扩展名过滤规则返回值string用户选中文件后返回该文件的绝对路径字符串例如/ext/subghz/Test.subundefined用户按下返回键取消选择时返回脚本中需用if (path)之类的方式做判空处理。参数校验细节源码层面C 层实现使用JsValueDeclaration声明了两个参数均为字符串类型并通过JS_VALUE_PARSE_ARGS_OR_RETURN解析见 file_picker.c。也就是说两个参数都必须提供且为字符串否则解析失败会直接返回不弹窗这是 JS SDK 0.1 起就稳定提供的 API类型声明见 file_picker.d.ts。三、extension 过滤规则的三种用法extension参数用于控制文件浏览器中可见的文件类型文档给出了三种典型写法写法含义示例场景.sub仅显示该单一扩展名的文件让用户挑选 Sub-GHz 信号文件.iso|.img用|分隔多个扩展名显示其中任意一种选择镜像文件磁盘映像*通配符显示所有文件不限制类型的通用选择官方示例 gui.js 中使用的是*从/extSD 卡根目录开始让用户自由选择任何文件let path filePicker.pickFile(/ext, *);注意extension的匹配只作用于文件不作用于目录——目录始终可见方便用户逐层导航进入子目录。这是文件浏览器对话框的通用行为DialogsFileBrowserOptions中的extension仅用于过滤可被选中的文件。四、完整实战示例选择文件后展示结果结合官方示例脚本 gui.js一个完整的文件选择流程如下// 1. 导入所需模块 let gui require(gui); let filePicker require(gui/file_picker); let dialogView require(gui/dialog); // 2. 弹出文件选择器从 SD 卡根目录开始、不限制扩展名 let path filePicker.pickFile(/ext, *); // 3. 处理返回结果 if (path) { // 用户选中了文件显示完整路径 views.helloDialog.set(text, You selected:\n path); } else { // 用户按返回取消给用户友好提示 views.helloDialog.set(text, You didnt select a file); } // 4. 切换到对话框视图展示结果 gui.viewDispatcher.switchTo(views.helloDialog);实战要点取消是常见操作必须处理undefined。Flipper 用户习惯按 Back 键退出弹窗若不判空直接使用返回值后续字符串拼接或存储操作会出错basePath常用/extSD 卡但也可指向任意已挂载路径例如/any、/int内部存储等取决于业务需要该调用是阻塞式的弹出对话框期间脚本暂停用户操作完成后才继续执行因此适合放在事件回调或普通流程代码中而不需要像视图那样手动订阅事件。五、源码级原理pickFile 的底层调用链要深入理解pickFile的行为可以顺着源码追踪其完整调用链1. JS 模块入口C 层file_picker.c 中js_gui_file_picker_pick_file的实现逻辑非常直接解析两个字符串参数base_path、extension通过furi_record_open(RECORD_DIALOGS)打开系统Dialogs 服务构造DialogsFileBrowserOptions配置设置.extension、.icon I_file_10px、.base_path调用dialog_file_browser_show(dialogs, path, path, browser_options)同步弹出文件浏览器若返回true选中用mjs_mk_string把路径字符串返回给 JS 层否则返回MJS_UNDEFINED对应 JS 的undefined释放 FuriString 并关闭 Dialogs 服务记录。值得注意的实现细节模块把文件图标固定为I_file_10px系统内置的通用文件图标同时把base_path既作为浏览起始路径也作为对话框的根路径传入。2. 底层文件浏览器对话框dialog_file_browser_show是固件系统级 API声明于 applications/services/dialogs/dialogs.h实现在 applications/services/dialogs/dialogs_api.c。也就是说JS 脚本使用的文件选择器与原生 C 应用如 Archive、Sub-GHz 等应用内部所调用的是同一个文件浏览器组件界面与交互完全一致。3. DialogsFileBrowserOptions 可配置字段DialogsFileBrowserOptions结构体见 dialogs.h完整定义了文件浏览器行为JS 模块目前只使用了其中三字段字段类型JS 模块中的取值说明extensionconst char*来自extension参数文件扩展名过滤base_pathconst char*来自basePath参数根目录按返回键时回到此处iconconst Icon*I_file_10px文件列表项的图标其余字段如skip_assets、hide_dot_files、hide_ext、select_right等在 JS 模块中被置零/默认因为js_picker结构体是显式初始化的——这意味着 JS 层的pickFile目前不支持隐藏点文件、隐藏扩展名、右侧键选择等高级选项。如果未来需要这些能力需要在 file_picker.c 的模块实现中扩展参数。六、与其它 JS GUI 模块的协作建议文件选择器在典型脚本中的定位是前置步骤常与以下模块组合使用gui/dialog把选中路径展示给用户确认如官方示例所示gui/text_input在文件选择前让用户输入文件名前缀实现输入 选择的复合流程storagedocumentation/js/js_storage.md对pickFile返回的路径执行读取、解析、写入等后续操作。由于pickFile是同步阻塞调用它会暂停车轮事件循环的处理如果需要与event_loop定时器、后台任务并发建议将文件选择放在用户触发按键回调的流程中执行避免在初始化阶段长时间阻塞脚本启动。七、常见问题速查Q1用户取消选择时返回什么返回undefined。务必用if (path) { ... } else { ... }分支处理。Q2如何只让用户选择某种协议文件把扩展名作为第二参数传入如pickFile(/ext/subghz, .sub)。可结合 documentation/js/js_gui.md 中关于模块导入的说明使用。Q3basePath不存在会怎样文件浏览器会尽力在给定路径上初始化为确保体验建议传入已知存在的目录如/ext或先通过 storage 模块检查路径存在性。Q4gui/file_picker与gui主模块的关系它们是独立的模块单元file_picker不需要实例化视图对象直接require后调用pickFile即可主gui模块仍用于视图调度如viewDispatcher。总结gui/file_picker是 Momentum-Firmware JS 运行时中最轻量的 GUI 模块之一一个函数、两个参数、一个返回值就完成了原生文件浏览器与 JS 脚本之间的桥接。它底层复用系统dialogs服务的dialog_file_browser_show因此在 UI 与交互上与原生的文件管理体验完全一致。对脚本开发者而言只需掌握basePath/extension的用法与undefined取消分支即可稳定地把用户选文件这一交互集成到任何脚本中。【免费下载链接】Momentum-Firmware Feature-rich, stable and customizable Flipper Firmware项目地址: https://gitcode.com/GitHub_Trending/mo/Momentum-Firmware创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考