feat(android): 交付 APK v1 移动端运行时与悬浮窗录音#641
Conversation
引入独立的 Tauri 移动端运行时,具备专有的调用处理器(invoke handler)、移动端存根(mobile stubs)以及针对特定目标的 Cargo 依赖。由此,Android 构建版本将不再引入仅限桌面的 crate(如 updater、autostart、single-instance、global-hotkey、enigo)。桌面端行为在 run_desktop() 逻辑下保持不变。 新增 PlatformCapabilities(包含 supportsAutoUpdate、supportsInAppDictation 等字段)并据此对前端进行门控处理:在概览页启用应用内听写;Android 入门引导不再因麦克风权限处于“未确定”状态而阻塞;同时在移动端隐藏桌面热键、本地 ASR 以及自动更新/Beta 渠道的相关 UI。 包含 Android 清单文件代码片段(v1 版本的 RECORD_AUDIO;标记为未来版本的 v2/v3 IME/叠加层权限)、Kotlin 基础架构、JNI 权限/IME/叠加层存根、移动端 tauri.android.conf.json 以及 docs/android-mobile-apk-overlay-plan.md 文档。
引入了 GitHub Actions 工作流,以实现 Android 应用调试 APK 构建的自动化。该工作流在匹配 'v*-tauri' 模式的标签推送时触发,并支持手动调度。它包括设置 Java 环境、Android SDK 和 NDK、安装依赖项、构建前端以及合并 APK 清单等步骤。生成的 APK 将作为 artifact 上传,并可附加到 GitHub Releases 中。此外,还更新了 package.json,新增了一个用于合并 Android 清单的脚本。
在文档中添加了 Android capability 的平台隔离详情。更新了 default.json 以指定桌面端支持的平台,并更新了 mobile.json 将 Android 定义为目标平台。这确保了应用程序能够正确处理权限并实现特定于平台的行为。
更新了文档和 default.json,将“macos”统一改为“macOS”,以保持各平台间的一致性。此更改增强了清晰度,并维护了平台命名规范的统一。
Co-authored-by: Cursor <cursoragent@cursor.com>
• 分别删除了 android_ime.rs 和 android_overlay.rs 中未使用的 AndroidImeState 和 AndroidOverlayPermissionState 导入。 • 更新了 insertion.rs 中的条件编译标志,在非 macOS 和非 Android 的检查中排除了 iOS。 • 在 lib.rs 的 app_invoke_handler_mobile 中添加了 #[macro_export] 以提高可访问性。 • 调整了 types.rs 中的类型检查,将移动平台纳入功能条件中。
在 app_invoke_handler_mobile 宏中,将直接命令引用替换为 crate 限定路径,以提高整个代码库的清晰度和一致性。
• 引入了 set_settings_common 来处理持久化用户偏好设置和发布更改的核心逻辑。 • 更新了各平台特定的 set_settings 函数以使用新的通用函数,从而提高了代码复用性和清晰度。 • 确保非移动平台的托盘麦克风菜单刷新的主线程处理保持不变。
• 添加了 Gradle 设置操作以优化构建流程。 • 引入了带有重试逻辑的 Gradle Wrapper 预热步骤,以提高构建过程中的可靠性。
Fixes startup UnsatisfiedLinkError for __cxa_pure_virtual when loading libopenless_lib.so. Co-authored-by: Cursor <cursoragent@cursor.com>
Plain c++_static left __cxa_pure_virtual undefined at dlopen; whole-archive pulls required symbols from libc++_static.a. Co-authored-by: Cursor <cursoragent@cursor.com>
build-script cfg(target_os=android) never ran on Linux CI hosts; use runtime target check so whole-archive c++_static applies. Co-authored-by: Cursor <cursoragent@cursor.com>
static=c++_static failed without -L; CARGO_CFG_TARGET_OS ensures the link runs on Linux CI hosts. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Compile windows_ime_profile on all desktop targets so get_windows_ime_status can call its non-Windows stub. Remove duplicate CLIPBOARD_RESTORE_DELAY cfg on Windows. Co-authored-by: Cursor <cursoragent@cursor.com>
|
目前还有两个功能没有写完:一个是 QA 功能,另一个是取消录音功能。不过在这两个功能完成之前,我决定先请求合并这个 PR。因为如果研发周期再拖长,产生的冲突可能会达到无法处理的程度。为了尽可能跟上项目的最新变更,建议先合并这个 PR,随后在最新的 Beta 版本中完成剩余的 QA 功能和取消录音功能。 |
PR Reviewer Guide 🔍(Review updated until commit 8eebffb)Here are some key observations to aid the review process:
|
Consolidate Rust android_* modules, Kotlin scaffolding, and frontend Android UI under openless-all/app/android/ with crate::android and @android imports to improve maintainability without changing runtime behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
Load android/types.rs from types.rs directly so backend-tests can compile types without the full android module tree. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit 237a60a |
摘要
Fixes #(无关联 issue 时可删此行,或填实际 issue 号)。 将 Android 相关 Rust、Kotlin 与前端代码收敛到 修复 / 新增 / 改进
兼容
测试计划
|
Stage deletions left over from the android/ directory migration so the working tree matches the relocated kotlin and manifest sources. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit 58c7c91 |
|
有冲突,请解决一下 |
|
Persistent review updated to latest commit 841215e |
|
Persistent review updated to latest commit 582af09 |
|
合并安卓的可以先放缓,因为我又新增了一些功能,并尝试修复一些已经存在的问题。 |
|
Persistent review updated to latest commit cef63e1 |
扩展 Android overlay/accessibility 类型与 JNI 桥接,优化悬浮窗交互与权限引导 UI,并同步 coordinator 移动端录音协调逻辑。 Co-authored-by: Cursor <cursoragent@cursor.com>
|
Persistent review updated to latest commit 8eebffb |
|
可以合并全部了。 |
User description
摘要
为 OpenLess 增加 Android APK v1 移动端运行时:在保持桌面端零破坏的前提下,完成应用内录音、麦克风权限、悬浮窗前台服务、手势驱动的听写/问答管线,以及 debug APK CI 构建链路;修复真机 native 加载与 JNI 初始化等多轮闪退。
修复 / 新增 / 改进
lib.rs、mobile_runtime.rs、mobile_stubs/*、PlatformCapabilities门控,前端platform.ts/ipc.ts在移动端隐藏桌面专属能力.github/workflows/android-apk.yml(workflow_dispatch+v*-tauritag)、四 ABI 分包产物、merge-android-v1-manifest.mjs/copy-android-scaffolding.mjsOpenLessOverlayService、AccessibilityService、JNI bridge(android_jni.rs/android_native_bridge.rs)、听写与 QA 管线接线androidOverlayActivationMode、左滑动作、取消滑向、androidOverlaySizeDp;搁置「键盘触发显示」并迁移历史值为background__cxa_pure_virtual:build.rs在CARGO_CFG_TARGET_OS=android时链接c++_static+c++abindk-context未初始化、FGS 启动超时、clipboard / accessibility JNI 签名与生命周期、overlay 重复窗口等多轮真机崩溃macos-private-api恢复至 base tauri features;windows_ime_profilestub 暴露;clipboard delay 去重set_settings_common抽取共享偏好写入;.gitignore忽略 Android 调试日志与本地 CI 产物;补充docs/android-mobile-apk-overlay-plan.md兼容
background)#[cfg(mobile)]/#[cfg(not(mobile))]/ capability 门控隔离tauri:android:*的开发者无额外依赖;现有cargo check与桌面 release 流程不受影响release-tauri.yml桌面发布链路ANDROID_HOME/NDK_HOME及aarch64-linux-android等 Rust target测试计划
命令:
cd openless-all/app && npm run build && cargo check --manifest-path src-tauri/Cargo.toml结果:桌面侧编译通过,无 mobile 分层污染
证据路径:本地
cargo check输出命令:
gh workflow run "Android APK (debug)" --repo appergb/openless --ref openless-android→gh run watch <run-id> --exit-status结果:四 ABI debug APK artifact
openless-android-debug上传成功证据路径:GitHub Actions run URL / 下载的
OpenLess-android-debug-run-*.apk命令:
adb install -r <apk>→adb shell am start -n com.openless.app/.MainActivity→ 授权麦克风与悬浮窗 → 应用内录音 → 悬浮窗手势(点按听写 / 左滑 QA / 录音中上滑取消)→adb logcat -b crash -d结果:无
__cxa_pure_virtual/ndk-context/ FGS timeout 闪退;录音转写与 QA 流程可完成证据路径:
test-captures/openless_after_install.png、test-captures/openless_app_recording_after_tap.png、test-captures/openless_app_recording_after_stop.png、test-captures/run73-start.png、test-captures/qa-repeat-current.pngPR Type
Enhancement, Bug fix
Description
Add Android mobile runtime with platform capabilities gating
Implement floating overlay v3 with dictation and QA pipelines
Add microphone and accessibility permission handling
Enable debug APK CI and fix JNI initialization crashes
Diagram Walkthrough
flowchart LR Entry["Main Entry"] --> Check{"Platform"} Check --> Desktop["Desktop Runtime"] Check --> Mobile["Mobile Runtime"] Mobile --> Overlay["Floating Overlay"] Mobile --> Permissions["Permissions"] Permissions --> Mic["Microphone"] Permissions --> OverlayPerm["Overlay"] Permissions --> Accessibility["Accessibility"] Overlay --> Gestures["Gesture Dictation/QA"]File Walkthrough
19 files
Refactor commands for mobile conditional compilation and add AndroidcommandsSplit runtime into desktop and mobile with macro handler selectionAdd Android overlay and QA session management logicAdd JNI bridge for Android system APIsImplement minimal mobile Tauri runtimeAdd native bridge for overlay communicationAdd Android-specific types and enumsImplement floating overlay lifecycleImplement accessibility service integrationAdd external URL opening supportAdd text insertion strategy for AndroidModule declaration for Android routinesAdd Android permissions UI settings panelImplement microphone permission bridgeAdd PlatformCapabilities detection for mobileAdd Android microphone permission hookProvide mobile stub for selection moduleProvide mobile stub for combo hotkeyProvide mobile stub for hotkey module1 files
Add CI workflow for debug APK building80 files