Files
openless/openless-all/app/android
浩彬(^-^)andCursor ec33bd5dd2 fix(android): 修复小屏大字号下的设置与风格页面排版 (#960) (#983)
* fix(android): 修复移动端设置与润色页排版及底栏遮挡 (#960)

设置弹窗 z-index 低于底栏导致底部控件无法点击;润色风格/市场页与 Android 权限区补齐 mobile 布局。

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(ui): 通用设置新增易读布局,大字号小屏防溢出换行

新增 stackedRowLayout 偏好与 useLayoutStack;设置外观区可手动开启同行控件换行,覆盖老人机等极限场景。关联 #960。

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(android): 安全查询悬浮窗权限,修复 HyperOS canDrawOverlays 闪退

WebView IPC 线程不再直接 JNI 调用 Settings.canDrawOverlays,改走 Kotlin 主线程桥接并捕获异常,避免 Redmi/HyperOS 在权限轮询时崩溃。

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(ui): 保守排版开关与易读布局 min-width 增强

新增 conservativeLayout 偏好与 ol-conservative-scope 单列满宽规则;易读布局补充 min-width 换行;设置与主要页面支持双开关独立并存。

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(android): can_draw_overlays JNI 生命周期以通过 Android CI 编译

为 env 与 context 绑定同一 lifetime,满足 call_static_bool_with_context_class 的借用约束。

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(android): 恢复 AccessibilityService 对 Settings.Secure 的 import

isEnabled 仍使用 Settings.Secure 查询无障碍状态,与 canDrawOverlays 移除的 import 无关。

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(ui): 将易读/保守排版开关独立为「布局」区块并置顶

原开关藏在「外观」卡片深处不易发现;现于设置→通用页录音输入下方展示独立「布局」卡片。

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(ui): 统一易读与保守排版布局规则

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-23 00:22:21 +08:00
..

OpenLess Android 平台代码

Android 相关 Rust、Kotlin 与前端代码的统一入口。桌面端通过 #[cfg(not(mobile))] 分层,不受影响。

目录结构

android/
├── kotlin/              # Kotlin 模板(CI 复制到 gen/android/)
├── manifests/           # AndroidManifest snippet + res/xml
└── frontend/            # React 模块(Vite 别名 @android)

src-tauri/src/android/   # Rust 运行时模块(crate::android)

Rust(src-tauri/src/android/)

模块 职责
jni.rs JNI 工具(clipboard、overlay service、accessibility)
native_bridge.rs Kotlin ↔ Coordinator JNI 入口
overlay.rs 悬浮窗权限与 show/hide
accessibility.rs 无障碍服务状态与 paste
shizuku.rs Shizuku 状态诊断与受控无障碍恢复
insert.rs 跨 App 文本插入策略
updater.rs 应用内更新(manifest 拉取、minisign 校验、系统安装器)
updater_logic.rs 更新 URL / 版本比较纯函数(全平台可测)
types.rs Android 偏好与状态类型

主 crate 通过 mod android; 引入,常用 API 经 crate::android:: 扁平 re-export。

Kotlin(android/kotlin/)

tauri android init 后由 scripts/copy-android-scaffolding.mjs 复制到 src-tauri/gen/android/app/src/main/java/com/openless/app/。

Manifest 合并脚本:

前端(android/frontend/,别名 @android)

路径 职责
lib/androidTypes.ts Android 偏好与状态 TS 类型
lib/androidIpc.ts overlay / accessibility / Shizuku Tauri invoke
lib/androidMicrophonePermission.ts WebView 麦克风权限辅助
components/AndroidPermissionsPanel.tsx 设置页 Android 权限与 overlay 配置

src/lib/types.ts 与 src/lib/ipc.ts 保留 re-export,现有 import 路径仍可用。

构建与 CI

CI(overlay / 无障碍 ADB 测试 APK) — 合并 v1 麦克风权限 + overlay / 无障碍 manifest,用于真机 ADB 测试完整悬浮窗与无障碍能力(非仅应用内听写):

cd openless-all/app
npm ci && npm run build
CI=true npm run tauri -- android init --ci
node scripts/copy-android-scaffolding.mjs
node scripts/merge-android-v1-manifest.mjs
node scripts/merge-android-overlay-manifest.mjs
node scripts/merge-android-shizuku-manifest.mjs
node scripts/patch-android-shizuku-deps.mjs
CI=true npm run tauri:android:build

Workflow: .github/workflows/android-apk.yml

本地 overlay / 无障碍开发(v3) — 与 CI 相同的 manifest 合并链,使用本地 init / copy 脚本:

cd openless-all/app
npm run tauri:android:init
npm run copy:android-scaffolding
node scripts/merge-android-v1-manifest.mjs
node scripts/merge-android-overlay-manifest.mjs
node scripts/merge-android-shizuku-manifest.mjs
node scripts/patch-android-shizuku-deps.mjs
npm run tauri:android:build

相关文档