Browse Source

feat(floating_ui): 新增悬浮UI插件实现翻译悬浮窗和录音悬浮条功能

- 添加Android系统悬浮窗服务实现翻译悬浮窗功能
- 实现录音悬浮条服务支持显示/更新/隐藏操作
- 新增iOS画中画(PiP)内容视图支持动态更新翻译文本
- 完善权限检查和事件回传机制
- 更新README详细说明插件功能和使用方式
newdev_shunjiawei
lxm 9 months ago
parent
commit
231bc66f5f
  1. 0
      local_plugins/floating_ui_plugin/.gitignore
  2. 0
      local_plugins/floating_ui_plugin/.metadata
  3. 0
      local_plugins/floating_ui_plugin/CHANGELOG.md
  4. 0
      local_plugins/floating_ui_plugin/LICENSE
  5. 120
      local_plugins/floating_ui_plugin/README.md
  6. 0
      local_plugins/floating_ui_plugin/analysis_options.yaml
  7. 0
      local_plugins/floating_ui_plugin/android/.gitignore
  8. 0
      local_plugins/floating_ui_plugin/android/build.gradle
  9. 1
      local_plugins/floating_ui_plugin/android/settings.gradle
  10. 0
      local_plugins/floating_ui_plugin/android/src/main/AndroidManifest.xml
  11. 0
      local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/FloatingWindowService.kt
  12. 0
      local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/NativePlugin.kt
  13. 0
      local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/RecordingFloatingService.kt
  14. 0
      local_plugins/floating_ui_plugin/android/src/test/java/com/example/native_plugin/NativePluginTest.java
  15. 0
      local_plugins/floating_ui_plugin/ios/.gitignore
  16. 0
      local_plugins/floating_ui_plugin/ios/Assets/.gitkeep
  17. 0
      local_plugins/floating_ui_plugin/ios/Classes/FLNativeView.swift
  18. 0
      local_plugins/floating_ui_plugin/ios/Classes/NativePlugin.swift
  19. 0
      local_plugins/floating_ui_plugin/ios/Classes/PlayerView.swift
  20. 0
      local_plugins/floating_ui_plugin/ios/Resources/PrivacyInfo.xcprivacy
  21. 0
      local_plugins/floating_ui_plugin/ios/floating_ui_plugin.podspec
  22. 0
      local_plugins/floating_ui_plugin/lib/native_plugin.dart
  23. 0
      local_plugins/floating_ui_plugin/lib/native_plugin_method_channel.dart
  24. 0
      local_plugins/floating_ui_plugin/lib/native_plugin_platform_interface.dart
  25. 0
      local_plugins/floating_ui_plugin/pubspec.yaml
  26. 15
      local_plugins/native_plugin/README.md
  27. 1
      local_plugins/native_plugin/android/settings.gradle
  28. 2
      pubspec.yaml

0
local_plugins/native_plugin/.gitignore → local_plugins/floating_ui_plugin/.gitignore

0
local_plugins/native_plugin/.metadata → local_plugins/floating_ui_plugin/.metadata

0
local_plugins/native_plugin/CHANGELOG.md → local_plugins/floating_ui_plugin/CHANGELOG.md

0
local_plugins/native_plugin/LICENSE → local_plugins/floating_ui_plugin/LICENSE

120
local_plugins/floating_ui_plugin/README.md

@ -0,0 +1,120 @@
# floating_ui_plugin
该目录是一个本地 Flutter 插件包,当前在项目中主要承担「悬浮 UI」相关的原生能力:
- Android:翻译悬浮窗(系统悬浮窗 / overlay window)+ 录音悬浮条(计时/暂停/关闭)+ 悬浮窗权限检查/跳转。
- iOS:为系统画中画(PiP)提供可渲染的原生内容 View,并支持动态更新翻译文本。
> 说明:Flutter 包名为 floating_ui_plugin(见本插件 pubspec.yaml),主工程通过 path 依赖引用本目录。
## 主要能力
### 1) Android 翻译悬浮窗(Translation Floating Window)
- 通道:`MethodChannel('floating_window')`
- 原理:Flutter 调用通道方法 → Android 启动/更新 `FloatingWindowService` → service 通过系统 WindowManager 显示 overlay view。
- 交互回传:service 会反向调用同一通道,把状态/点击/关闭事件回传给 Flutter。
支持的方法(Flutter → Android):
- `enableFloatingWindow`:启动悬浮窗服务(如果已在运行,相当于确保存在)。
- `disableFloatingWindow`:停止悬浮窗服务。
- `showFloatingWindow`:显示悬浮窗(当前实现等价于启动服务)。
- `hideFloatingWindow`:隐藏悬浮窗(stopSelf)。
- `updateContent(Map)`:更新展示内容。
- `setPosition({x,y})`:设置悬浮窗位置。
回传的方法(Android → Flutter):
- `onFloatingWindowStateChanged({state})`:`hidden|minimized|expanded`
- `onFloatingWindowClosed()`:用户关闭。
- `onFloatingWindowClicked()`:用户点击语言区域(service 内部会 bringAppToFront)。
数据协议(updateContent):
- `sourceText` / `translatedText`
- `sourceLanguage` / `targetLanguage`
- `timestamp`(毫秒时间戳)
- `isIntermediate`(是否中间态)
对应实现:
- Android 插件入口:[NativePlugin.kt](file:///Users/liuxiamin/work/flutter_projects/deep_voice/local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/NativePlugin.kt)
- 悬浮窗服务:[FloatingWindowService.kt](file:///Users/liuxiamin/work/flutter_projects/deep_voice/local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/FloatingWindowService.kt)
### 2) Android 悬浮窗权限(Overlay Permission)
- 通道:`MethodChannel('overlay_permission')`
- 方法:
- `hasOverlayPermission`:是否具备 SYSTEM_ALERT_WINDOW
- `requestOverlayPermission`:跳转系统页面申请
对应实现:[NativePlugin.kt](file:///Users/liuxiamin/work/flutter_projects/deep_voice/local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/NativePlugin.kt)
### 3) Android 录音悬浮条(Recording Floating Bar)
- 通道:`MethodChannel('native_plugin')`
- 原理:Flutter 下发 show/update/hide → Android 启动/更新 `RecordingFloatingService` → service 以 overlay 方式显示一个小型悬浮条。
支持的方法(Flutter → Android):
- `showRecordingFloatingBar({duration, recordingType, isPaused})`
- `updateRecordingFloatingBar({duration, recordingType, isPaused})`
- `hideRecordingFloatingBar()`
用户操作回传(Android → Flutter):
- 事件通道:`EventChannel('native_plugin/recording_floating_actions')`
- action 字符串:
- `togglePause`:点击暂停/继续
- `openMeetingRecord`:点击中间区域,拉起 App 并打开录音页
- `closeFloatingBar`:关闭悬浮条
对应实现:
- 服务:[RecordingFloatingService.kt](file:///Users/liuxiamin/work/flutter_projects/deep_voice/local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/RecordingFloatingService.kt)
- 事件桥接:[NativePlugin.emitRecordingFloatingAction](file:///Users/liuxiamin/work/flutter_projects/deep_voice/local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/NativePlugin.kt#L26-L39)
## iOS:PiP 内容 View(Picture-in-Picture Content View)
- 通道:`MethodChannel('native_plugin')`
- 目标:创建一个用于 PiP 渲染的原生 `UIView`(`PlayerView`),并支持后续更新显示内容。
支持的方法:
- `createPipContentView()`:返回一个 `viewId`(本质是 PlayerView 的指针值)。
- `updatePipContentView({viewId?, lang, cn, en})`:更新内容。
- `disposePipContentView(viewId)`:释放。
对应实现:
- 插件入口:[NativePlugin.swift](file:///Users/liuxiamin/work/flutter_projects/deep_voice/local_plugins/floating_ui_plugin/ios/Classes/NativePlugin.swift)
- 具体 UI:[PlayerView.swift](file:///Users/liuxiamin/work/flutter_projects/deep_voice/local_plugins/floating_ui_plugin/ios/Classes/PlayerView.swift)
## 在主工程中的调用链路(现状)
### Android:翻译悬浮窗
- 入口:翻译页控制器 [TranslationController](file:///Users/liuxiamin/work/flutter_projects/deep_voice/lib/modules/translation/controllers/translation_controller.dart)
- `toggleFloatingWindow()` → `_enableFloatingWindow()`
- 管理器:[FloatingWindowManager](file:///Users/liuxiamin/work/flutter_projects/deep_voice/lib/core/services/floating_window_manager.dart)
- `enableFloatingWindow()`:先通过 [OverlayPermissionUtil](file:///Users/liuxiamin/work/flutter_projects/deep_voice/lib/core/utils/overlay_permission_util.dart) 请求权限,再调用 `TranslationFloatingWindowApi.enable()`
- `_setupMethodCallHandler()`:接收 `onFloatingWindowStateChanged/onFloatingWindowClicked/onFloatingWindowClosed` 并更新状态/路由跳转
- 内容更新:`TranslationController._updateFloatingWindowWithTranslation()` → `FloatingWindowManager.updateFloatingWindowContent()` → `updateContent(Map)`
### Android:录音悬浮条
- 入口:会议录音控制器 [MeetingRecordController](file:///Users/liuxiamin/work/flutter_projects/deep_voice/lib/modules/meeting/controllers/meeting_record_controller.dart)
- `showBackgroundRecordingIndicator()` → `_startAndroidRecordingFloatingBar()` → `NativePlugin.showRecordingFloatingBar()`
- 定时器每秒 `updateRecordingFloatingBar()` 更新 duration/isPaused
- `_setupRecordingFloatingBarActionListener()` 监听 `recordingFloatingActionStream` 并处理 `togglePause/openMeetingRecord/closeFloatingBar`
### iOS:翻译悬浮显示(PiP)
- 入口同样在 [TranslationController](file:///Users/liuxiamin/work/flutter_projects/deep_voice/lib/modules/translation/controllers/translation_controller.dart)
- `_startPip()`:`NativePlugin.createPipContentView()` → 将 viewId 传给第三方 PiP 组件的 `PipOptions.contentView`
- `_updateFloatingWindowWithTranslation()`:`NativePlugin.updatePipContentView({viewId, cn, en, lang})`
## 权限与 Manifest
- Android 需要:`android.permission.SYSTEM_ALERT_WINDOW`
- 本插件自带 AndroidManifest 声明(包含两项 service):
- [android/src/main/AndroidManifest.xml](file:///Users/liuxiamin/work/flutter_projects/deep_voice/local_plugins/floating_ui_plugin/android/src/main/AndroidManifest.xml)
## 平台差异与注意事项
- Android 与 iOS 的“悬浮显示”实现不同:Android 用系统悬浮窗;iOS 走系统 PiP。
- `createPipContentView/updatePipContentView/disposePipContentView` 仅 iOS 实现;Android 侧没有实现这些 method,请务必用 `Platform.isIOS` 保护调用。
- `floating_window` / `overlay_permission` / `native_plugin/recording_floating_actions` 都是固定通道名,避免在其他地方重复注册同名通道。
- 工程 `android/app/src/main/kotlin/com/saitong/voitrans/` 下存在同名通道的旧实现文件(未在 MainActivity 注册),当前实际走的是本插件实现;如后续要启用 app 侧实现,需要先解决通道名冲突与 service 声明问题。

0
local_plugins/native_plugin/analysis_options.yaml → local_plugins/floating_ui_plugin/analysis_options.yaml

0
local_plugins/native_plugin/android/.gitignore → local_plugins/floating_ui_plugin/android/.gitignore

0
local_plugins/native_plugin/android/build.gradle → local_plugins/floating_ui_plugin/android/build.gradle

1
local_plugins/floating_ui_plugin/android/settings.gradle

@ -0,0 +1 @@
rootProject.name = 'floating_ui_plugin'

0
local_plugins/native_plugin/android/src/main/AndroidManifest.xml → local_plugins/floating_ui_plugin/android/src/main/AndroidManifest.xml

0
local_plugins/native_plugin/android/src/main/kotlin/com/example/native_plugin/FloatingWindowService.kt → local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/FloatingWindowService.kt

0
local_plugins/native_plugin/android/src/main/kotlin/com/example/native_plugin/NativePlugin.kt → local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/NativePlugin.kt

0
local_plugins/native_plugin/android/src/main/kotlin/com/example/native_plugin/RecordingFloatingService.kt → local_plugins/floating_ui_plugin/android/src/main/kotlin/com/example/native_plugin/RecordingFloatingService.kt

0
local_plugins/native_plugin/android/src/test/java/com/example/native_plugin/NativePluginTest.java → local_plugins/floating_ui_plugin/android/src/test/java/com/example/native_plugin/NativePluginTest.java

0
local_plugins/native_plugin/ios/.gitignore → local_plugins/floating_ui_plugin/ios/.gitignore

0
local_plugins/native_plugin/ios/Assets/.gitkeep → local_plugins/floating_ui_plugin/ios/Assets/.gitkeep

0
local_plugins/native_plugin/ios/Classes/FLNativeView.swift → local_plugins/floating_ui_plugin/ios/Classes/FLNativeView.swift

0
local_plugins/native_plugin/ios/Classes/NativePlugin.swift → local_plugins/floating_ui_plugin/ios/Classes/NativePlugin.swift

0
local_plugins/native_plugin/ios/Classes/PlayerView.swift → local_plugins/floating_ui_plugin/ios/Classes/PlayerView.swift

0
local_plugins/native_plugin/ios/Resources/PrivacyInfo.xcprivacy → local_plugins/floating_ui_plugin/ios/Resources/PrivacyInfo.xcprivacy

0
local_plugins/native_plugin/ios/floating_ui_plugin.podspec → local_plugins/floating_ui_plugin/ios/floating_ui_plugin.podspec

0
local_plugins/native_plugin/lib/native_plugin.dart → local_plugins/floating_ui_plugin/lib/native_plugin.dart

0
local_plugins/native_plugin/lib/native_plugin_method_channel.dart → local_plugins/floating_ui_plugin/lib/native_plugin_method_channel.dart

0
local_plugins/native_plugin/lib/native_plugin_platform_interface.dart → local_plugins/floating_ui_plugin/lib/native_plugin_platform_interface.dart

0
local_plugins/native_plugin/pubspec.yaml → local_plugins/floating_ui_plugin/pubspec.yaml

15
local_plugins/native_plugin/README.md

@ -1,15 +0,0 @@
# native_plugin
A new Flutter plugin project.
## Getting Started
This project is a starting point for a Flutter
[plug-in package](https://flutter.dev/to/develop-plugins),
a specialized package that includes platform-specific implementation code for
Android and/or iOS.
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

1
local_plugins/native_plugin/android/settings.gradle

@ -1 +0,0 @@
rootProject.name = 'native_plugin'

2
pubspec.yaml

@ -117,7 +117,7 @@ dependencies:
qq_music: qq_music:
path: local_plugins/qq_music path: local_plugins/qq_music
floating_ui_plugin: floating_ui_plugin:
path: local_plugins/native_plugin path: local_plugins/floating_ui_plugin
test: test:
path: local_plugins/test path: local_plugins/test

Loading…
Cancel
Save