Browse Source

feat(i18n): 添加安卓前台服务通知的多语言翻译

为支持安卓前台服务的通知本地化,在多个语言文件中新增翻译键值。
同时在对应的安卓服务文件中添加注释,说明前台通知的触发条件。
newdev_shunjiawei
lxm 8 months ago
parent
commit
40df5f0f00
  1. 15
      lib/core/translations/language/ar_sa.dart
  2. 15
      lib/core/translations/language/de_de.dart
  3. 16
      lib/core/translations/language/fr_fr.dart
  4. 30
      lib/core/translations/language/ja_jp.dart
  5. 15
      lib/core/translations/language/ko_kr.dart
  6. 15
      lib/core/translations/language/ru_ru.dart
  7. 13
      lib/core/translations/language/zh_hk.dart
  8. 13
      lib/core/translations/language/zh_tw.dart
  9. 4
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt
  10. 7
      local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/NavigationService.kt
  11. 4
      local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/AudioRecordingForegroundService.kt
  12. 5
      local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicService.kt

15
lib/core/translations/language/ar_sa.dart

@ -1064,6 +1064,21 @@ const Map<String, String> arSA = {
'storagePermissionPermanentDenial':
'تم اكتشاف أنك رفضت إذن التخزين بشكل دائم. للمتابعة في استخدام هذه الميزة، يرجى الانتقال إلى إعدادات التطبيق لتمكين إذن التخزين يدويًا.',
// 原生前台服务通知(Android)
'native.notification.appName': 'VOITRANS', // VOITRANS
'native.notification.navigation.title': 'التنقل جارٍ', // 导航进行中
'native.notification.navigation.keepRunning':
'التنقل جارٍ، يرجى إبقاء التطبيق قيد التشغيل', // 正在导航中,请保持应用运行
'native.notification.bleAgent.running': 'المساعد الصوتي قيد التشغيل', // 语音助手正在运行
'native.notification.audioRecording.recording':
'يتم التسجيل، اضغط للعودة إلى التطبيق', // 正在录音,点击返回应用
'native.notification.music.waiting': 'في انتظار التشغيل', // 等待播放
'native.notification.music.previous': 'السابق', // 上一首
'native.notification.music.next': 'التالي', // 下一首
'native.notification.music.play': 'تشغيل', // 播放
'native.notification.music.pause': 'إيقاف مؤقت', // 暂停
'native.notification.qqMusic.playing': 'يتم تشغيل الموسيقى', // 正在播放音乐
//permission_util.dart
'permissionUtilNeed': 'يحتاج ',
'permissionUtilPermission': ' إذن',

15
lib/core/translations/language/de_de.dart

@ -1101,6 +1101,21 @@ const Map<String, String> deDE = {
'storagePermissionPermanentDenial':
'Speicherberechtigung wurde dauerhaft verweigert. Um diese Funktion weiterhin nutzen zu können, gehen Sie bitte zu den App-Einstellungen, um die Speicherberechtigung manuell zu aktivieren.',
// 原生前台服务通知(Android)
'native.notification.appName': 'VOITRANS', // VOITRANS
'native.notification.navigation.title': 'Navigation läuft', // 导航进行中
'native.notification.navigation.keepRunning':
'Navigation läuft, App geöffnet lassen', // 正在导航中,请保持应用运行
'native.notification.bleAgent.running': 'Sprachassistent läuft', // 语音助手正在运行
'native.notification.audioRecording.recording':
'Audioaufnahme läuft, tippen um zur App zurückzukehren', // 正在录音,点击返回应用
'native.notification.music.waiting': 'Warte auf Wiedergabe', // 等待播放
'native.notification.music.previous': 'Vorheriger Titel', // 上一首
'native.notification.music.next': 'Nächster Titel', // 下一首
'native.notification.music.play': 'Wiedergabe', // 播放
'native.notification.music.pause': 'Pause', // 暂停
'native.notification.qqMusic.playing': 'Musik wird wiedergegeben', // 正在播放音乐
//permission_util.dart
'permissionUtilNeed': 'Benötige ',
'permissionUtilPermission': ' Berechtigung',

16
lib/core/translations/language/fr_fr.dart

@ -1088,6 +1088,22 @@ const Map<String, String> frFR = {
'storagePermissionPermanentDenial':
'Storage permission has been permanently denied. To continue using this feature, please go to app settings to manually enable storage permission.',
// 原生前台服务通知(Android)
'native.notification.appName': 'VOITRANS', // VOITRANS
'native.notification.navigation.title': 'Navigation en cours', // 导航进行中
'native.notification.navigation.keepRunning':
'Navigation en cours, gardez l’application active', // 正在导航中,请保持应用运行
'native.notification.bleAgent.running':
'Assistant vocal en cours d’exécution', // 语音助手正在运行
'native.notification.audioRecording.recording':
'Enregistrement audio, appuyez pour revenir à l’application', // 正在录音,点击返回应用
'native.notification.music.waiting': 'En attente de lecture', // 等待播放
'native.notification.music.previous': 'Précédent', // 上一首
'native.notification.music.next': 'Suivant', // 下一首
'native.notification.music.play': 'Lecture', // 播放
'native.notification.music.pause': 'Pause', // 暂停
'native.notification.qqMusic.playing': 'Musique en cours de lecture', // 正在播放音乐
//permission_util.dart
'permissionUtilNeed': 'Need ',
'permissionUtilPermission': ' Permission',

30
lib/core/translations/language/ja_jp.dart

@ -439,11 +439,15 @@ const Map<String, String> jaJP = {
'meetingRecordStopFailed': '録音を停止できませんでした。もう一度お試しください。', // 结束录音失败,请重试
'meetingRecordSaveFailed': '録音を保存できませんでした。もう一度お試しください。', // 保存录音失败,请重试
'meetingRecordRecordingNotificationTitle': '録音中', // 录音进行中
'meetingRecordRecordingNotificationBody': 'バックグラウンドで録音しています。タップしてアプリに戻ります。', // 正在后台录音,点击返回应用
'meetingRecordRecordingNotificationBody':
'バックグラウンドで録音しています。タップしてアプリに戻ります。', // 正在后台录音,点击返回应用
'overlayPermissionTitle': '他のアプリの上に表示', // 悬浮窗权限
'overlayPermissionTranslationDesc': '通話中または音声/動画翻訳中に翻訳結果を表示するため、他のアプリの上に表示する権限が必要です。これにより、他のアプリを使用中でもリアルタイム翻訳を確認できます。', // 为了在通话或音视频翻译时显示翻译结果,需要悬浮窗权限。这样您就可以在使用其他应用时看到实时翻译。
'overlayPermissionRecordingDesc': '録音中に録音フローティングバー(タイマー/一時停止/再開)を表示するため、他のアプリの上に表示する権限が必要です。', // 为了在录音过程中显示录音悬浮条(计时/暂停/继续),需要悬浮窗权限。
'overlayPermissionOpenSettingsFailed': 'システム設定を自動で開けませんでした。設定を開き、手動で「他のアプリの上に表示」を有効にしてください。', // 无法自动跳转到系统设置,请手动前往系统设置开启悬浮窗权限。
'overlayPermissionTranslationDesc':
'通話中または音声/動画翻訳中に翻訳結果を表示するため、他のアプリの上に表示する権限が必要です。これにより、他のアプリを使用中でもリアルタイム翻訳を確認できます。', // 为了在通话或音视频翻译时显示翻译结果,需要悬浮窗权限。这样您就可以在使用其他应用时看到实时翻译。
'overlayPermissionRecordingDesc':
'録音中に録音フローティングバー(タイマー/一時停止/再開)を表示するため、他のアプリの上に表示する権限が必要です。', // 为了在录音过程中显示录音悬浮条(计时/暂停/继续),需要悬浮窗权限。
'overlayPermissionOpenSettingsFailed':
'システム設定を自動で開けませんでした。設定を開き、手動で「他のアプリの上に表示」を有効にしてください。', // 无法自动跳转到系统设置,请手动前往系统设置开启悬浮窗权限。
'transcribing': 'Transcribing...',
'summarizing': 'Summarizing...',
'analyzing': 'Analyzing...',
@ -618,8 +622,7 @@ const Map<String, String> jaJP = {
// Meeting模块 - 发言者相关
'applyToAllParagraphs': 'この話者のすべての段落に適用',
'summaryWillBeUpdatedAutomatically':
'要約はテンプレートに基づいて自動的に更新されます',
'summaryWillBeUpdatedAutomatically': '要約はテンプレートに基づいて自動的に更新されます',
'nameCurrentSpeaker': 'Name Current Speaker',
'recentlyUsedNames': 'Recently Used Names',
'applyToCurrentParagraph': 'Apply to Current Paragraph',
@ -1032,6 +1035,21 @@ const Map<String, String> jaJP = {
'storagePermissionPermanentDenial':
'Storage permission has been permanently denied. To continue using this feature, please go to app settings to manually enable storage permission.',
// 原生前台服务通知(Android)
'native.notification.appName': 'VOITRANS', // VOITRANS
'native.notification.navigation.title': 'ナビゲーション中', // 导航进行中
'native.notification.navigation.keepRunning':
'ナビゲーション中です。アプリを起動したままにしてください', // 正在导航中,请保持应用运行
'native.notification.bleAgent.running': '音声アシスタントが実行中です', // 语音助手正在运行
'native.notification.audioRecording.recording':
'録音中です。タップしてアプリに戻る', // 正在录音,点击返回应用
'native.notification.music.waiting': '再生待機中', // 等待播放
'native.notification.music.previous': '前の曲', // 上一首
'native.notification.music.next': '次の曲', // 下一首
'native.notification.music.play': '再生', // 播放
'native.notification.music.pause': '一時停止', // 暂停
'native.notification.qqMusic.playing': '音楽を再生中', // 正在播放音乐
//permission_util.dart
'permissionUtilNeed': 'Need ',
'permissionUtilPermission': ' Permission',

15
lib/core/translations/language/ko_kr.dart

@ -1027,6 +1027,21 @@ const Map<String, String> koKR = {
'storagePermissionPermanentDenial':
'Storage permission has been permanently denied. To continue using this feature, please go to app settings to manually enable storage permission.',
// 原生前台服务通知(Android)
'native.notification.appName': 'VOITRANS', // VOITRANS
'native.notification.navigation.title': '내비게이션 진행 중', // 导航进行中
'native.notification.navigation.keepRunning':
'내비게이션 중입니다. 앱을 실행 상태로 유지하세요', // 正在导航中,请保持应用运行
'native.notification.bleAgent.running': '음성 비서가 실행 중입니다', // 语音助手正在运行
'native.notification.audioRecording.recording':
'녹음 중, 탭하여 앱으로 돌아가기', // 正在录音,点击返回应用
'native.notification.music.waiting': '재생 대기 중', // 等待播放
'native.notification.music.previous': '이전 곡', // 上一首
'native.notification.music.next': '다음 곡', // 下一首
'native.notification.music.play': '재생', // 播放
'native.notification.music.pause': '일시정지', // 暂停
'native.notification.qqMusic.playing': '음악 재생 중', // 正在播放音乐
//permission_util.dart
'permissionUtilNeed': 'Need ',
'permissionUtilPermission': ' Permission',

15
lib/core/translations/language/ru_ru.dart

@ -1093,6 +1093,21 @@ const Map<String, String> ruRU = {
'storagePermissionPermanentDenial':
'检测到您已永久拒绝存储权限。如需继续使用此功能,请前往应用设置中手动开启存储权限。',
// 原生前台服务通知(Android)
'native.notification.appName': 'VOITRANS', // VOITRANS
'native.notification.navigation.title': 'Навигация запущена', // 导航进行中
'native.notification.navigation.keepRunning':
'Идёт навигация, держите приложение запущенным', // 正在导航中,请保持应用运行
'native.notification.bleAgent.running': 'Голосовой помощник работает', // 语音助手正在运行
'native.notification.audioRecording.recording':
'Идёт запись, нажмите чтобы вернуться в приложение', // 正在录音,点击返回应用
'native.notification.music.waiting': 'Ожидание воспроизведения', // 等待播放
'native.notification.music.previous': 'Предыдущая', // 上一首
'native.notification.music.next': 'Следующая', // 下一首
'native.notification.music.play': 'Воспроизвести', // 播放
'native.notification.music.pause': 'Пауза', // 暂停
'native.notification.qqMusic.playing': 'Воспроизведение музыки', // 正在播放音乐
//permission_util.dart
'permissionUtilNeed': 'Need ',
'permissionUtilPermission': ' Permission',

13
lib/core/translations/language/zh_hk.dart

@ -980,6 +980,19 @@ const Map<String, String> zhHK = {
'storagePermissionPermanentDenial':
'檢測到您已永久拒絕儲存權限。如需繼續使用此功能,請前往應用設定中手動開啟儲存權限。',
// 原生前台服务通知(Android)
'native.notification.appName': 'VOITRANS',
'native.notification.navigation.title': '導航進行中',
'native.notification.navigation.keepRunning': '正在導航中,請保持應用運行',
'native.notification.bleAgent.running': '語音助手正在運行',
'native.notification.audioRecording.recording': '正在錄音,點擊返回應用',
'native.notification.music.waiting': '等待播放',
'native.notification.music.previous': '上一首',
'native.notification.music.next': '下一首',
'native.notification.music.play': '播放',
'native.notification.music.pause': '暫停',
'native.notification.qqMusic.playing': '正在播放音樂',
//permission_util.dart
'permissionUtilNeed': '需要',
'permissionUtilPermission': '權限',

13
lib/core/translations/language/zh_tw.dart

@ -980,6 +980,19 @@ const Map<String, String> zhTW = {
'storagePermissionPermanentDenial':
'檢測到您已永久拒絕儲存權限。如需繼續使用此功能,請前往應用設定中手動開啟儲存權限。',
// 原生前台服务通知(Android)
'native.notification.appName': 'VOITRANS',
'native.notification.navigation.title': '導航進行中',
'native.notification.navigation.keepRunning': '正在導航中,請保持應用運行',
'native.notification.bleAgent.running': '語音助手正在運行',
'native.notification.audioRecording.recording': '正在錄音,點擊返回應用',
'native.notification.music.waiting': '等待播放',
'native.notification.music.previous': '上一首',
'native.notification.music.next': '下一首',
'native.notification.music.play': '播放',
'native.notification.music.pause': '暫停',
'native.notification.qqMusic.playing': '正在播放音樂',
//permission_util.dart
'permissionUtilNeed': '需要',
'permissionUtilPermission': '權限',

4
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt

@ -415,6 +415,10 @@ private var companionManager: BleCompanionManager? = null
// 设置服务状态
isRunning.set(true)
// 前台通知显示条件:
// - 只要 BleMediaService 被启动(Flutter 调用 AgentService.startAgentService),onCreate 会立刻执行 startForeground();
// - 渠道使用 IMPORTANCE_LOW,通常不会弹出“抬头横幅(Heads-up)”,但会在下拉通知栏里显示常驻通知;
// - Flutter 侧常见入口:PairingController 跳过配对时会调用 BleManager.startAgentService()。
startForeground(NOTIFICATION_ID, createNotification())
// 初始化BLE伴侣设备管理器 - 使用单例模式获取实例
companionManager = BleCompanionManager.getInstance(this)

7
local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/NavigationService.kt

@ -61,6 +61,11 @@ class NavigationService: Service(),AMapNaviListener {
override fun onCreate() {
super.onCreate()
instance = this
// 前台通知显示条件:
// - 只要该 Service 被启动(ContextCompat.startForegroundService / startForegroundService),onCreate 就会立刻调用 startForeground();
// - 通知渠道使用 IMPORTANCE_LOW,通常不会弹出“抬头横幅(Heads-up)”,但会在下拉通知栏里出现常驻通知;
// - Flutter 侧需要调用插件 com.yunqiinnovation.amap_service 的 "start"(会走 NavigationServiceHelper.startNavigation -> 启动该 Service),
// 调用 "open" 只会打开导航页面,不会启动该前台服务,因此不会有通知。
startForegroundNotification()
// 注册广播监听器
@ -150,6 +155,8 @@ class NavigationService: Service(),AMapNaviListener {
.setOngoing(true)
.build()
// 触发系统显示“前台服务常驻通知”的关键点:startForeground()
// 如果 Android 13+ 未授予通知权限 / 用户关闭了该渠道通知,可能导致通知不可见或启动前台服务失败(不同 ROM 行为可能不同)。
startForeground(NOTIFICATION_ID, notification)
}

4
local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/tools/AudioRecordingForegroundService.kt

@ -65,6 +65,10 @@ class AudioRecordingForegroundService : Service() {
// 创建前台通知
val notification = createNotification()
// 前台通知显示条件:
// - 只要该 Service 被启动(AzureSpeechPlugin/AzureAsrHelper 在 enableRecord 时会启动它),就会在 onStartCommand 里立刻调用 startForeground();
// - 渠道为 IMPORTANCE_LOW,通常不会弹出“抬头横幅(Heads-up)”,但会在下拉通知栏显示常驻通知;
// - Android 13+ 如果未授予通知权限 / 用户关闭通知,可能出现通知不可见或启动前台服务失败(不同 ROM 行为可能不同)。
// 必须立即调用 startForeground 以满足 Android 8.0+ 的要求
startForeground(NOTIFICATION_ID, notification)

5
local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicService.kt

@ -154,6 +154,11 @@ class MusicService : MediaBrowserServiceCompat() {
setupMediaSession()
val waitingTitle = getNativeLocalizedString("native.notification.music.waiting", "等待播放")
val appName = getNativeLocalizedString("native.notification.appName", "Voitrans")
// 前台通知显示条件:
// - 只要 MusicService 被启动(Flutter 调用 com.yunqiinnovation.music_service 的 play/playlist 等会启动该服务),
// onCreate 会立刻调用 startForeground(),因此下拉通知栏会出现常驻通知(哪怕还没真正开始播放);
// - 渠道为 IMPORTANCE_LOW,通常不会弹出“抬头横幅(Heads-up)”,但会在通知栏里常驻;
// - stop/close 会在 completeStop() 里 stopForeground(true)+stopSelf(),通知随之消失。
startForeground(NOTIFICATION_ID, createNotification(waitingTitle, appName, ""))
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager

Loading…
Cancel
Save