Browse Source

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

为支持安卓前台服务的通知本地化,在多个语言文件中新增翻译键值。
同时在对应的安卓服务文件中添加注释,说明前台通知的触发条件。
weicu
lxm 8 months ago
parent
commit
1be9bd4cfe
  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': '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 //permission_util.dart
'permissionUtilNeed': 'يحتاج ', 'permissionUtilNeed': 'يحتاج ',
'permissionUtilPermission': ' إذن', 'permissionUtilPermission': ' إذن',

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

@ -1101,6 +1101,21 @@ const Map<String, String> deDE = {
'storagePermissionPermanentDenial': '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.', '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 //permission_util.dart
'permissionUtilNeed': 'Benötige ', 'permissionUtilNeed': 'Benötige ',
'permissionUtilPermission': ' Berechtigung', 'permissionUtilPermission': ' Berechtigung',

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

@ -1088,6 +1088,22 @@ const Map<String, String> frFR = {
'storagePermissionPermanentDenial': 'storagePermissionPermanentDenial':
'Storage permission has been permanently denied. To continue using this feature, please go to app settings to manually enable storage permission.', '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 //permission_util.dart
'permissionUtilNeed': 'Need ', 'permissionUtilNeed': 'Need ',
'permissionUtilPermission': ' Permission', 'permissionUtilPermission': ' Permission',

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

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

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

@ -1027,6 +1027,21 @@ const Map<String, String> koKR = {
'storagePermissionPermanentDenial': 'storagePermissionPermanentDenial':
'Storage permission has been permanently denied. To continue using this feature, please go to app settings to manually enable storage permission.', '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 //permission_util.dart
'permissionUtilNeed': 'Need ', 'permissionUtilNeed': 'Need ',
'permissionUtilPermission': ' Permission', 'permissionUtilPermission': ' Permission',

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

@ -1093,6 +1093,21 @@ const Map<String, String> ruRU = {
'storagePermissionPermanentDenial': '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 //permission_util.dart
'permissionUtilNeed': 'Need ', 'permissionUtilNeed': 'Need ',
'permissionUtilPermission': ' Permission', 'permissionUtilPermission': ' Permission',

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

@ -980,6 +980,19 @@ const Map<String, String> zhHK = {
'storagePermissionPermanentDenial': '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 //permission_util.dart
'permissionUtilNeed': '需要', 'permissionUtilNeed': '需要',
'permissionUtilPermission': '權限', 'permissionUtilPermission': '權限',

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

@ -980,6 +980,19 @@ const Map<String, String> zhTW = {
'storagePermissionPermanentDenial': '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 //permission_util.dart
'permissionUtilNeed': '需要', 'permissionUtilNeed': '需要',
'permissionUtilPermission': '權限', '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) isRunning.set(true)
// 前台通知显示条件:
// - 只要 BleMediaService 被启动(Flutter 调用 AgentService.startAgentService),onCreate 会立刻执行 startForeground();
// - 渠道使用 IMPORTANCE_LOW,通常不会弹出“抬头横幅(Heads-up)”,但会在下拉通知栏里显示常驻通知;
// - Flutter 侧常见入口:PairingController 跳过配对时会调用 BleManager.startAgentService()。
startForeground(NOTIFICATION_ID, createNotification()) startForeground(NOTIFICATION_ID, createNotification())
// 初始化BLE伴侣设备管理器 - 使用单例模式获取实例 // 初始化BLE伴侣设备管理器 - 使用单例模式获取实例
companionManager = BleCompanionManager.getInstance(this) 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() { override fun onCreate() {
super.onCreate() super.onCreate()
instance = this instance = this
// 前台通知显示条件:
// - 只要该 Service 被启动(ContextCompat.startForegroundService / startForegroundService),onCreate 就会立刻调用 startForeground();
// - 通知渠道使用 IMPORTANCE_LOW,通常不会弹出“抬头横幅(Heads-up)”,但会在下拉通知栏里出现常驻通知;
// - Flutter 侧需要调用插件 com.yunqiinnovation.amap_service 的 "start"(会走 NavigationServiceHelper.startNavigation -> 启动该 Service),
// 调用 "open" 只会打开导航页面,不会启动该前台服务,因此不会有通知。
startForegroundNotification() startForegroundNotification()
// 注册广播监听器 // 注册广播监听器
@ -150,6 +155,8 @@ class NavigationService: Service(),AMapNaviListener {
.setOngoing(true) .setOngoing(true)
.build() .build()
// 触发系统显示“前台服务常驻通知”的关键点:startForeground()
// 如果 Android 13+ 未授予通知权限 / 用户关闭了该渠道通知,可能导致通知不可见或启动前台服务失败(不同 ROM 行为可能不同)。
startForeground(NOTIFICATION_ID, notification) 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() val notification = createNotification()
// 前台通知显示条件:
// - 只要该 Service 被启动(AzureSpeechPlugin/AzureAsrHelper 在 enableRecord 时会启动它),就会在 onStartCommand 里立刻调用 startForeground();
// - 渠道为 IMPORTANCE_LOW,通常不会弹出“抬头横幅(Heads-up)”,但会在下拉通知栏显示常驻通知;
// - Android 13+ 如果未授予通知权限 / 用户关闭通知,可能出现通知不可见或启动前台服务失败(不同 ROM 行为可能不同)。
// 必须立即调用 startForeground 以满足 Android 8.0+ 的要求 // 必须立即调用 startForeground 以满足 Android 8.0+ 的要求
startForeground(NOTIFICATION_ID, notification) 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() setupMediaSession()
val waitingTitle = getNativeLocalizedString("native.notification.music.waiting", "等待播放") val waitingTitle = getNativeLocalizedString("native.notification.music.waiting", "等待播放")
val appName = getNativeLocalizedString("native.notification.appName", "Voitrans") 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, "")) startForeground(NOTIFICATION_ID, createNotification(waitingTitle, appName, ""))
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager

Loading…
Cancel
Save