[android] 风格包 ZIP 选中文件后未导入,刷新无效

已关闭
#1,320 4 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

已经有一个关联 PR 被合并了。

  • #1322 来自 @HKLHaoBin —— 已合并

评估

难度
4/5
预计耗时
3-5 天
新手友好度
22/100
Issue 类型
缺陷
描述清晰度
需要澄清
活跃度
活跃
技术栈
android, rust, tauri, typescript
领域
frontend, mobile

调研方向

Start with the import handler in src/pages/Style.tsx (handleImportZip, around lines 586-613) and the error toast in components/SavedToast.tsx, then check mobile_runtime.rs and capabilities/mobile.json for the dialog plugin setup. The backend path is commands/style_packs.rs, which reads content:// URIs. Nothing is reproduced yet, so the first step is adding the four observation points on one known build. Done means the root cause is confirmed on a device and the import succeeds without a broader storage permission.

由索引模型根据 Issue 内容生成。

描述

area:style bug needs-repro P2 platform:android

**2026-10-31 新证据更新:**用户已确认文件选择器正常打开,选中文件并点击“选择”后仍未导入,刷新无效。新日志含 3 次 source_kind=content-uri 后端导入入口记录,排查重点应移至 URI 读取、ZIP 校验/持久化及前端结果链路;具体根因仍未确认。完整脱敏证据与更新后的假设见补充调研。以下正文保留首次调研历史,其中“选择器是否出现尚未区分”的描述已由本更新澄清。

现象

用户反馈:在荣耀 Android 环境进入「风格包」,点击「导入 ZIP」没有可见反应,无法完成本地 ZIP 风格包导入。

本 issue 是用户日志审阅与当前上游源码调研的结果,没有在该设备真机复现,根因未确认;不应把静态候选原因当成已证实的设备缺陷。

环境与复现步骤
  • 平台:Android;应用包名 com.openless.app。
  • 用户提供的环境描述为「荣耀 Magic 11」。日志中的相关口述转写为「系统是荣耀 Magic 11」,因此它可能指系统版本,而非硬件型号;保留原始描述,具体机型、MagicOS 完整版本及 Android API level 待确认,不据此推定型号。
  • 当前安装的 OpenLess 版本、build SHA、系统 WebView 版本未知。日志中的 v2.0.1+build.20261016 是此前更新器尝试安装的目标,且安装失败,不能用它确定当前安装版本。
  • 日志:openless-2026-10-31T11-40-09.log.txt,包含 2026-10-23、10-30、10-31 多次启动,主要相关窗口为 2026-10-31 11:26–11:39 UTC。

复现步骤(来自用户报告,非本次真机验证):

  1. 在上述荣耀 Android 环境打开 OpenLess。
  2. 进入「风格包」。
  3. 点击「导入 ZIP」。
  4. 观察系统文件选择器是否出现、按钮是否一直显示加载、是否出现错误,以及风格列表是否变化。

实际:用户感知为点击没有反应,未完成导入。尚未区分「选择器完全没弹出」「选中文件后不返回」「报错短暂闪过」三种子情况,也没有可验证的失败 ZIP 样本。

期望:点击后打开文件选择器;选择合法 ZIP 后导入并在列表中显示;取消应恢复可操作状态;异常应有清晰、可读、可再次显示的反馈。

日志证据与覆盖边界

原日志只读审阅。以下是最小脱敏摘录,行号对应原文件;完整日志包含无关语音转写和会话标识,故不直接公开。

L130 2026-10-31T11:27:22.500136706Z [INFO] [style-pack] command export requested id=builtin.light target_path=content://<已脱敏>
L131 2026-10-31T11:27:24.057395039Z [INFO] [style-pack] command create_from_template name=<已脱敏> base_mode=Light
L132 2026-10-31T11:27:24.328323112Z [INFO] [style-pack] command preview_runtime id=<已脱敏> base_mode=Light prompt_chars=370
L139 2026-10-31T11:28:08.683321064Z [INFO] [style-pack] command create_from_template name=<已脱敏> base_mode=Light
L140 2026-10-31T11:28:08.876978199Z [INFO] [style-pack] command preview_runtime id=<已脱敏> base_mode=Light prompt_chars=370
  • 原文件 L365–367 的语音转写包含用户当时所述「点击导入 zip 没反应」;L989 包含上述系统环境口述。这里只提取问题相关信息,不公开其余转写。
  • 全文检索未找到 [style-pack] command import requested。这只能说明未采集到该事件,不能证明按钮没有执行或后端绝对没有被调用:用户 APK 与所审源码版本未对应,且前端点击、插件异常、Activity 返回均无完整记录。
  • L130 说明至少一次导出命令收到了 Android content:// URI,不代表导出成功,也不能证明导入选择器正常;导入与导出使用不同 Intent 路径。
  • 创建模板、预览能到达后端,不能将本次现象归结为整个风格页 IPC 均失效。
  • 日志中的更新签名错误、加密同步初始化阶段 ERROR、悬浮窗销毁和录音空输入等没有证据与此次 ZIP 导入相关,不作为根因。
行为契约检查
契约 预期与来源 结论
N1 点击导入后出现选择器或可读错误 用户期望及 handleImportZip 调用链 用户报告违反可见结果契约;日志不足以判定选择器启动/返回的具体失败边界
N2 用户选择合法 ZIP 后导入并刷新列表 importStylePackFromZip → loadPacks(imported.id) 证据不足:没有选中文件、URI 读取或归档解析的可关联记录
N3 错误反馈可读,取消后恢复按钮 页面错误处理及按钮 busy 状态 静态发现提示可见期不一致;该设备是否因此漏看错误待验证

当前上游源码调研

审阅基线:beta 的 2b89ecdd727f842443bded33d8dfcf1a21efe598。这不是用户 APK 的已知 SHA。

  1. Style.tsx L586–613:先置 busy=importing,动态加载 @tauri-apps/plugin-dialog,调用带 zip filter 的 open({ multiple:false });仅返回字符串后才调用导入 IPC。null 会静默返回;异常只交给 showSaveStatus,此处没有记录到应用日志。若 open() Promise 一直 pending,finally 不执行,按钮持续加载/禁用。
  2. mobile_runtime.rs 已初始化 dialog 插件;mobile.json 对 main/qa 授予 dialog:default。目前没有源码依据认定是漏初始化/漏 capability,但用户实际 APK 仍需核对。
  3. commands/style_packs.rs 已针对 Android content:// 通过受限 ContentResolver reader 读取,再进行字节导入。不能泛化成「Android URI 被当普通路径读取」;该支持来自已合并 #942。
  4. Style.tsx L218–235 将失败状态保留 6000ms,但页面传入 SavedToast 时,普通失败未传 durationMs;SavedToast.tsx 内部仍默认 800ms 隐藏,且 whiteSpace: nowrap。因此页面的 6 秒计时不等于错误实际可见 6 秒。此项是静态可确认的反馈风险,不是本次导入失败根因的确认。
  5. 当前 Cargo.lock 的 dialog 为 2.8.3。其 Android 实现 使用 ACTION_GET_CONTENT、CATEGORY_OPENABLE、扩展名到 MIME 的映射,以及 EXTRA_MIME_TYPES;保存对话框另用 ACTION_CREATE_DOCUMENT。

Android 官方说明通过 Storage Access Framework 由用户选择文档的访问不需要通用存储权限。因此「设置里无法授予存储权限」本身不能证明失败原因,不建议以增加所有文件访问权限作为默认修复。

待验证假设(均未确认)

ID 假设 / 对应契约 可证伪预测 若成立的修复方向 观测点
H1 Android 文件选择器 Intent/MIME 处理失败(N1) 点击后调用到插件,启动阶段抛出异常;不带 filter 的受控对照可打开,而当前 ZIP filter 不可打开 修复已证实的 Intent/MIME 兼容分支,必要时提供明确的用户触发兜底;保留归档内容校验 P1/P2/P3
H2 Activity 结果或跨层 Promise 未完成(N1/N3) Intent 已启动或已返回,但前端没有终态;按钮持续加载;需按 APK 版本定位具体桥接边界 修复结果回调/桥接生命周期,确保成功、取消、失败均结算一次 P1/P2/P3
H3 插件/读取/归档错误确已返回,但短提示使用户感知无响应(N1/N2/N3) 记录到稳定错误类别,busy 已恢复;UI 错误很快消失或窄屏不可读 对应真实失败修复,并让失败信息持续可读、可重复触发;不能仅延长 toast 就声称导入已修复 P1/P3/P4

相关线索而非结论:

  • tauri-apps/plugins-workspace#3366 是尚未关闭的 Android dialog Promise 首次不完成报告,但涉及不同应用/插件版本,不能认定与本次相同;不采用该讨论中的定时 no-op 轮询作为修复。
  • tauri-apps/plugins-workspace#2826 是历史 Android filters 不弹选择器报告,已关闭且旧实现涉及 ACTION_PICK,当前 2.8.3 为 ACTION_GET_CONTENT;只能帮助设计 MIME 对照,不能套用旧根因。
  • #878 / 已合并 #879 是市场「安装到本地」临时目录问题,与本 issue 的本地「导入 ZIP」入口不同,不按重复 issue 处理。

建议下一步

  1. 补齐实际 APK 版本/SHA、设备型号、完整系统与 WebView 版本;确认选择器出现与否、按钮是否一直加载,以及失败发生在选择文件之前还是之后。
  2. 对同一已知构建做 4 个有界、安全观测点:P1 前端点击与 busy;P2 Android Intent 启动/结果回调;P3 前端 dialog 成功/取消/错误终态;P4 后端导入入口、受限读取与解析结果。仅记录阶段、枚举错误类别、字节数等,禁止记录完整 URI、ZIP 内容、提示词或凭据;必要时同步采集脱敏 logcat。
  3. 在观测证明 MIME 问题后才对照 ZIP filter 与通用文档选择;在观测证明结果丢失后才调整回调/生命周期。不要通过延迟、周期轮询或扩大存储权限掩盖问题。
  4. 在不改变导入安全边界的前提下改善可读错误反馈,并验证重复同一错误仍可见。

影响

受影响环境无法通过本地 ZIP 导入/分享风格包;缺少文件选择器阶段诊断及短暂错误反馈,使问题难以定位。是否涉及其他荣耀机型或其他 Android 系统尚未知。

建议接受标准

  • 原反馈荣耀环境点击「导入 ZIP」能打开选择器,合法 ZIP 成功导入并显示在风格列表中;记录实际构建与真机证据。
  • 取消、选取失败、读取失败和损坏 ZIP 均能结束 busy 状态;取消不被误报为导入失败,重复操作不挂起。
  • 失败提示在窄屏可读且可再次触发;若约定保留 6 秒,组件实际可见期与其一致。
  • 不增加不必要的通用存储/所有文件权限;保留 content URI 的受限读取及 ZIP 大小、解压和内容安全校验。
  • Android 文档提供器场景、桌面本地 ZIP 导入无回归。

TODO / 不确定项

  • 用户 APK 版本、设备型号与系统版本、点击后选择器及 busy 的具体状态、失败 ZIP 样本均待确认。
  • 本次只调研并提交 issue,未修改产品代码、构建 APK 或声称已修复。
主要语言
Rust
星标
3.7k
派生
349
平均合并
1 天 12 小时
30 天内合并 PR
99

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

Open-Less/openless 的其他 Issue

查看 Open-Less/openless 的全部 Issue

相似的 Issue

更多 Rust Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。