GalaxyBudsClient 法语本地化翻译状态深度解析:从缺失字符串报告到 XAML 资源字典工作机制
GalaxyBudsClient 法语本地化翻译状态深度解析:从缺失字符串报告到 XAML 资源字典工作机制
GalaxyBudsClient 是一款非官方的 Galaxy Buds 桌面管理工具,支持 Windows、macOS、Linux 与 Android,其界面本地化覆盖 27 种语言。本文以仓库中自动生成的 meta/fr.md 法语翻译状态报告为线索,系统梳理当前法语翻译的完整度、294 条缺失字符串清单背后的功能模块,并深入 GalaxyBudsClient/i18n/fr.axaml 法语资源字典与 LocalizationUtils.cs 本地化引擎源码,帮助读者理解这套基于 Avalonia 资源字典的翻译体系如何工作、法语翻译当前处于什么水平,以及贡献者应如何补齐缺失词条。
一、这份"翻译状态报告"是什么:meta/fr.md 的定位与生成机制
meta/fr.md 并非人工撰写的文档,而是一份自动生成并自动更新的机器报告。文件开头的声明已经明确说明:
This file is auto-generated and automatically updated. Do not modify this file manually.
它由项目使用的 XamlTranslationValidator)与法语资源字典(GalaxyBudsClient/i18n/fr.axaml),列出法语中缺失、尚未翻译的字符串条目,供翻译贡献者按图索骥。同一目录下的 meta/translations.md 汇总了全部 27 种语言的翻译进度总表。
当前法语翻译进度
报告给出两个核心数字:
| 指标 | 数值 |
|---|---|
| 翻译完成度 | 50% |
| 缺失字符串数 | 294 条 |
作为横向参照,meta/translations.md 的总表中,完成度最高的 br(巴西)、pt(葡萄牙)达到 98%,仅缺失 7 条;而 fr(法国)与 ro(罗马尼亚)、ua(乌克兰)并列处于 50% 的中游水平。也就是说,法语界面大约有一半的 UI 文案仍是英文原文,本地化工作还有较大的补齐空间。
报告的结构:Key 与原文的对照表
报告主体是一张"Missing strings"对照表,每行包含两列:
- Key:字符串的资源键名(如
both、next、prev),这是 XAML 资源字典中x:Key属性的值; - Original string:英文基准字符串,即该键在 en.axaml 中的原文内容。
贡献者翻译时,只需在 GalaxyBudsClient/i18n/fr.axaml 中为对应 Key 补充法语文案即可。需要注意的是,缺失的是"键",而不是"值"——fr.axaml 中已存在的键即使译文质量有争议,也不会出现在缺失列表中;只有完全未翻译的键才会被报告。
二、294 条缺失字符串全景:覆盖哪些功能模块
仔细审读这份缺失清单,可以还原出法语翻译当前尚未覆盖的功能领域。报告中的字符串并非随机罗列,而是按模块聚类的,逐条分析如下。
通用基础词条(最容易补齐的一批)
报告开头的通用词条属于高频基础词汇,翻译成本极低:
| Key | 原文 | 说明 |
|---|---|---|
both |
Both | 左/右耳"两只" |
next / prev |
Next / Previous | 向导页的"下一步/上一步" |
off / on |
Off / On | 开关状态 |
hint / help / important |
Hint / Help / Important | 提示文案 |
home |
Home | 主页面 |
read_failed |
Failed to read file. Access denied. | 文件读取失败 |
please_wait |
Please wait... | 等待提示 |
value_left_right_inline |
Left: {0}, Right: {1} | 带占位符的左右值格式串 |
value_left_right_multiline |
Left: {0}⏎Right: {1} | 多行版本的左右值格式串 |
other_x |
Other ({0}) | 带参数的"其他" |
no_data_stored / not_available / file_not_found |
无数据/不可用/文件未找到 | 空态文案 |
last_updated_at_n |
Last updated at {0} | 时间占位符 |
这类字符串在 fr.axaml 中很多已经有对应译文(例如 okay→"Ok"、left→"Gauche"、right→"Droit"、case→"Boîtier"),但 both、next、prev 等基础词尚未翻译,是新手贡献者最好的切入点。
主题与外观(Appearance)
adaptive(Adaptive):自适应降噪模式名;darkmode_blur_enabled(On, with blur effect)与darkmode_mica_enabled(On, with mica effect):Windows 上两种深色模式背景特效(模糊 / Mica 材质)。
欢迎页与 Android 提示
welcome_register 与 welcome_register_desc 对应设备注册引导;welcome_android_hint_title / welcome_android_hint 是给 Android 用户的重要提示,原文明确说明:应用最初面向桌面设计,需要后台运行的功能(自定义触控动作、电池统计)在当前 Android 版本不可用,且若官方 Samsung Wearable 应用同时运行可能引发连接冲突——这是开发者对 Android 平台限制的如实声明。
设备管理(Devices)
devsel_manual_pair_title(Is your device not listed?)等引导用户使用手动连接;devices_header(Paired devices)、devices_new/devices_new_long(Pair new device)、devices_select_inactive/devices_select_active(Select / Selected)、devices_delete/devices_delete_long(Delete device)、devices_delete_confirmation、devices_settings_link/devices_settings_link_desc:对应 DevicesPage.axaml 的设备列表、增删与主设备选择界面。
触控板与自定义触控动作
这是缺失量较大的模块,对应 TouchpadPage 与触控动作编辑功能:
touchpad_gesture_header(Enable touchpad gestures)及touchpad_gesture_single/double/triple/hold与各自 desc:单击播放/暂停、双击下一曲、三击上一曲、长按执行自定义动作,以及通话中的双击应答/挂断、长按拒接;touchpad_default_action(Built-in touch action)、touchpad_gestures(Advanced touch lock)、touchpad_gestures_description(Disable default touch gestures);touchpad_noise_control_mode_l/r与touchpad_noise_control_mode_desc:左右耳降噪模式切换;cact_function_param(Function)、cact_hotkey_param(Hotkey)、cact_path_param(File path):自定义动作的三种参数类型(执行功能、触发热键、启动外部程序)。
系统信息与隐藏模式(Hidden Mode)
隐藏模式是 GalaxyBudsClient 的特色高级功能,缺失词条集中在 HiddenModeTerminalDialog.axaml 与系统页:
system_hidden_at_mode/system_hidden_at_mode_desc:编辑序列号、UART 状态等隐藏系统设置;system_usage_reports/system_usage_reports_desc:查看耳机自带的用量/计量报告;system_battery_statistics/system_battery_statistics_desc:电池统计;system_no_response、system_cradle_swver(充电盒软件版本)、system_cradle_serial(充电盒序列号)、system_btaddr_template、system_sku;hidden_mode_warning(Proceed with caution)与hidden_mode_warning_desc:警告部分更改无法通过恢复出厂设置还原、并非所有型号支持;hidden_mode_target/hidden_mode_target_l_desc/hidden_mode_target_r_desc:通过把另一只耳机放入盒中来切换目标耳机的操作提示;hidden_mode_input_wrong_length(新值必须恰好为 {0} 个字符)、hidden_mode_uart_on_confirm/hidden_mode_uart_off_confirm(UART 成功启用/禁用)、hidden_mode_uart/hidden_mode_uart_desc(临时启用 PCB 物理 UART 口用于调试);hidden_mode_power(Power menu)及power_menu_reboot/shutdown/sleep(重启/关机/工厂睡眠模式);hidden_mode_serial_change、hidden_mode_did_change(DID 号与颜色)、hidden_mode_sku_change(SKU 码)、hidden_mode_bt_peer_addr_change(对端蓝牙地址)、hidden_mode_bt_local_addr_change(本机蓝牙地址)——这组功能直接对应 scripts/DumpSKU.cs 所涉及的 SKU/DID 底层数据结构;hidden_mode_terminal/hidden_mode_terminal_desc:向耳机发送自定义 AT 命令的隐藏命令终端;at_terminal_cmd_id/at_terminal_cmd_param/at_terminal_cmd_id_invalid(须输入 16 位十六进制值,如 0007 或 004C)/at_terminal_output/at_terminal_send:AT 终端的输入校验与交互文案。
用量报告与电池历史(Usage Reports & Battery History)
usage_reports_header/usage_reports_hint/usage_reports_usage/usage_reports_metering:报告页与提示(耳机自行收集的数据按原样显示、官方 Wearable 应用会周期性重置多数计数器并上传 Samsung,充电循环等部分计数器不重置);milliamp_hours_unit({0}mAh)、metering_total_batt_capacity(总电池容量)、metering_a2dp_time(A2DP 音乐播放时长)、metering_esco_time(eSCO 通话时长);batt_hist_hint(仅在应用后台活动且耳机连接时收集数据)、batt_hist_no_data_title/batt_hist_no_data、batt_hist_y_axis(Charge (%));- 时间跨度选项:
batt_hist_last_hour/last_6_hours/last_12_hours/last_24_hours/last_3_days/last_7_days; - 叠加层:
batt_hist_overlay_none/overlay_noise_controls(降噪状态)/overlay_wearing(佩戴状态)/overlay_host_device(蓝牙主耳机)/overlay_legend; - 工具:
batt_hist_tools_pan_and_zoom/measure_time(测量时间跨度)/measure_battery(测量电量差)/batt_hist_show_legend/batt_hist_measure_difference_display/batt_hist_measure_timespan_display/batt_hist_measure_timespan_unit_long; - 使用提示:
batt_hist_time_span_tip_title/batt_hist_control_tip_title/batt_hist_control_tip(拖拽平移、滚轮缩放、悬停 X/Y 轴单向缩放)/batt_hist_overlay_tip_title/batt_hist_overlay_tip/batt_hist_tools_tip_title/batt_hist_tools_tip。
这套交互对应 BatteryHistoryPage.axaml 的电量历史图表界面,其数据持久化由 BatteryHistoryManager.cs 与 Migrations 目录中的 EF Core 迁移(如 20240503133123_InitialBatteryStatsDb)支撑。
设置与 Multipoint
settings_save_fail_no_access(配置保存失败、权限被拒时的提示,含文件路径占位符);settings_appearance、settings_blurstrength/settings_blurstrength_description(仅兼容深色模式,非所有系统支持)、settings_accent/settings_accent_description(自定义强调色)、settings_localization_description(切换语言)、settings_realistic_earbud_icons/settings_realistic_earbud_icons_description(真实感耳机图片)、settings_color_override/settings_color_override_description(耳机颜色覆盖)、settings_nav_sidebar/settings_nav_sidebar_description(左侧导航栏折叠)、settings_tray_settings、settings_dyn_tray_mode(托盘图标动态显示电量)及off/battery_min(最低电量)/battery_avg(平均电量)三种模式、settings_devmode_description(蓝牙流量检查器与开发者工具)、settings_crowdsourcing/settings_crowd_allow/settings_crowd_allow_description(众包收集三星私有蓝牙协议结构数据)、settings_crowd_crashreport/settings_crowd_crashreport_description(通过 Sentry 自动上报崩溃)、settings_cpopup_position_description;- Multipoint:
settings_multipoint_header/settings_multipoint_auto/settings_multipoint_auto_description(无三星账号解锁多设备连接,每次连接写入缺失的版本标记,耳机断电后标记清除)/settings_multipoint_apply/settings_multipoint_apply_description(重新写入标记,耳机将短暂断开重连)/settings_multipoint_applied/settings_multipoint_failed。该功能的实现细节可参考 MultipointPatcher.cs。
查找耳机与 SmartThings Find
fmg_smart_things_find_manage/fmg_smart_things_find_manage_desc、fmg_smart_things_find_open/fmg_smart_things_find_open_desc(需三星账号与官方 SmartThings Find 应用);smart_things_find、smart_things_find_clear/smart_things_find_clear_desc(清除耳机中的三星账号数据)、smart_things_find_iv(初始化向量)、smart_things_find_secret_key、smart_things_find_region、smart_things_find_fmm_token、smart_things_find_no_link(未接入网络)、smart_things_find_write_fail/smart_things_find_write_ok/smart_things_find_write_ok_desc。
佩戴检测、EQ 与降噪
gft_warning(请佩戴两只耳机)、gft_desc、gft_bad(Bad fit)、gft_good(Good fit)、gft_fail(Test failed):耳塞贴合度测试;eq_enable_description(应用 EQ 滤波器)、nc_as_anc_description(降低背景噪音)、nc_one_earbud/nc_one_earbud_description(单耳机降噪,防止不适)、nc_ambient/nc_ambient_description(自定义环境音)、nc_voicedetect_timeout_description、nc_as_header/nc_as_custom/nc_as_custom_description、nc_as_custom_volume_l/r(左右环境音音量)、nc_as_custom_tone及clear/soft/neutral(音色)、nc_as_custom_vol_normal、as_header_description(Hear your surroundings)、as_voicefocus_description(突出人声)。
高级设置与 Bixby 重映射
adv_pause_playback/adv_pause_playback_desc(取下耳机暂停播放,仅桌面端)、adv_callpath/adv_callpath_desc(通话音频路径:入耳走耳机、未入耳走扬声器)、adv_extra_clear_call/adv_extra_clear_call_desc(通话清晰度增强,更耗电);bixby_remap_lang_desc/bixby_remap_action_desc(激活短语语言与动作)。
连接失败与官方应用冲突
connlost(Connection lost)、connlost_troubleshoot/connlost_troubleshoot_title/connlost_troubleshoot_content:这是重要的排障文案,原文建议彻底关闭三星官方 Wearable 应用,否则其会反复抢占耳机连接导致频繁掉线;解决方案包括在 Wearable 应用内解绑、卸载 Galaxy Buds 插件,或用 Hail/Ice Box 冻结插件。
固件更新相关
pairingmode_done(耳机已进入配对模式并断开当前连接);fw_select_install_short(Install)、fw_select_from_disk_short(Open)、fw_select_refresh(Refresh)、fw_select_no_results_short(No updates found)、fw_select_verify_model_mismatch_fail(型号不匹配警告:向 {1} 刷入 {0} 固件会永久变砖——该提示可在 FirmwareUpdateDialog.cs 中找到对应逻辑);window_open(Open)、budsapp_header/budsapp_text_p1/p2/p3(官方应用并存时的蓝牙兼容性提示)。
手动配对、重命名与 360 音频(Spatial Audio)
manualpair_title/manualpair_title_dialog/manualpair_model/manualpair_note:手动选择设备型号,对应 ManualPairDialog.axaml;rename/rename_desc/rename_warn(官方应用限制仅三星手机可重命名,可能需本应用重置名称,改名后需重新配对才能生效)/rename_warn_oneui_title/rename_warn_oneui(OneUI 用户应使用三星官方方式改名,否则会出现连接问题)/rename_too_short/rename_hint/rename_label/rename_reading_name/rename_ok_title/rename_ok;- 360 音频(SpatialAudio 模块的界面文案):
page_spatial_audio(360 Audio)、spatial_audio_desc、spatial_enable/spatial_enable_desc(头部追踪)、spatial_recenter/spatial_recenter_desc(重置正面朝向)、spatial_demo_play/spatial_demo_stop/spatial_demo_desc(3D 空间音效演示)、spatial_broadcast_osc/spatial_broadcast_osc_desc(通过 OSC 向 localhost:9000 广播 yaw/pitch/roll 与四元数,供 DAW/插件使用)、spatial_broadcast_opentrack/spatial_broadcast_opentrack_desc(FreeTrack/OpenTrack UDP 到 localhost:4242,供飞行/驾驶模拟游戏)、spatial_tracking_active/spatial_tracking_inactive、spatial_speaker_angle/spatial_speaker_angle_desc(虚拟声场宽度)、spatial_ambience/spatial_ambience_desc(房间混响)、spatial_system_audio/spatial_system_audio_desc(全局 360 音频)、macOS 端 BlackHole 虚拟驱动系列文案(spatial_blackhole_status_ok/restart_needed/missing/missing_desc/howto/install/restart)、spatial_open_audio_midi/spatial_open_sound_pref、spatial_windows_info(Windows 通过 WASAPI Loopback 原生捕获系统音频,无需第三方驱动)。
三、fr.axaml 已完成的法语翻译:资源字典内部结构
要理解缺失清单,必须先看懂法语资源字典本身。已翻译的词条集中在 GalaxyBudsClient/i18n/fr.axaml(共 528 行),其结构如下。
文件骨架
fr.axaml 是一个 Avalonia ResourceDictionary,通过 xmlns:sys="clr-namespace:System;assembly=mscorlib" 引入 sys:String 类型,每个词条是一个带 x:Key 的字符串资源:
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- English name of this language -->
<sys:String x:Key="language_name_en">French</sys:String>
<sys:String x:Key="okay">Ok</sys:String>
<sys:String x:Key="left">Gauche</sys:String>
<sys:String x:Key="right">Droit</sys:String>
<sys:String x:Key="case">Boîtier</sys:String>
...
</ResourceDictionary>
文件按功能模块用 XML 注释分区组织,例如 Source code(源码内字符串)、XAML files (static)(界面静态文本)、Welcome page、Main page、Update page、Device selection page (setup)、Touchpad page、Custom touchpad action page、System/Self-Test、Settings、Factory reset、Find my Gear、Equalizer、Noise control、Ambient sound、Advanced page、Remap bixby wakeup、Connection lost page、Firmware update disclaimer、Firmware selection、Firmware transfer、Spatial test、Header。这种分区与缺失报告按模块聚类的特征一一对应。
带占位符的格式串
法语译文完整保留了大括号占位符({0}、{1}),保证格式化字符串能正确替换运行时值。例如:
connpopup_title:法语版为{1} de {0},与英文{0}'s {1}词序不同但占位符一致——这是翻译质量正常的体现;value_left_right_inline(缺失,英文为Left: {0}, Right: {1})等待补齐;- 多行字符串则直接跨行书写(如
value_left_right_multiline的英文原文),XAML 中换行会被完整保留。
译文中的术语一致性
从已完成的译文可看出法语术语约定:okay→"Ok"、left→"Gauche"、right→"Droit"、case→"Boîtier"(充电盒)、anc→"Réduction de bruit active"(主动降噪)、touchpad→"Pavé tactile"(触控板)、ambient sound→"Son environnant"(环境音)、equalizer→"Égaliseur"。后续补齐词条时应遵循这套术语,保持前后一致。
四、本地化引擎源码:缺失词条如何被兜底
理解"缺失"的确切含义,需要看 LocalizationUtils.cs 中的 Loc 静态类——这是整个本地化体系的核心。
英文兜底机制
Loc 在静态构造函数中首先加载英文基准字典作为兜底:
static Loc()
{
// Load English fallback strings
LoadInternalLanguage("en", ref FallbackStrings);
}
运行时解析词条时采用"当前语言优先、英文兜底"的策略:
public static string Resolve(string resName) =>
ResolveOrDefault(resName) ?? $"{resName}";
public static string? ResolveOrDefault(string resName) =>
_strings.TryGetValue(resName, out var result) ? result :
FallbackStrings.TryGetValue(resName, out var fallbackResult) ? fallbackResult : null;
这意味着:法语缺失的 294 条词条,运行时并不会显示为空白或键名,而是自动回退显示英文原文。这与报告中"Original string"一列的意义完全吻合——缺失时用户实际看到的就是那列英文。若连英文兜底都没有,才会退化为显示键名本身。
语言切换与外部翻译文件
语言通过 Settings.Data.Locale 配置,Load() 方法按语言码加载内置字典,并支持"翻译者模式":若数据目录下存在 custom_language.xaml(路径由 PlatformUtils.CombineDataPath("custom_language.xaml") 计算),且语言设置为 custom,则通过 LoadExternalLanguage 解析外部 XAML 覆盖内置词条;该模式下还会根据 IsRightToLeft 词条自动切换界面文字方向(RTL),以支持阿拉伯语等从右到左的语言:
public static FlowDirection ResolveFlowDirection()
{
var rtlSetting = ResolveOrDefault("IsRightToLeft");
...
}
加载完成后,LanguageUpdated 事件与 NotifyObservers() 会通知所有注册的观察者刷新界面文本。
动态刷新:TranslateExtension
界面中的文本绑定通过 TranslateExtension.cs 实现。它是一个 Avalonia MarkupExtension,同时实现 IObservable<string>,作为 XamlUIExtension 不支持文本动态资源的替代方案:
public class TranslateExtension(string key) : MarkupExtension, IObservable<string>
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this.ToBinding();
}
public IDisposable Subscribe(IObserver<string> observer)
{
return Loc.AddObserverForKey(key, observer);
}
}
Loc.AddObserverForKey(LocalizationUtils.cs)使用弱引用字典维护每个键的观察者列表,注册后立即推送当前解析值,语言切换时通过 NotifyObservers() 向每个观察者推送新译文,界面随之实时更新。XAML 中的典型用法形如 Text="{translate:Translate key}" 或 Text="{translate:Translate 'settings_header'}"。
生成器辅助
项目还通过 LocalizationKeySourceGenerator.cs 在编译期生成强类型的本地化键常量,配合 LocalizableDescriptionAttribute 让枚举等类型可以携带本地化描述,这与 EnumToDescriptionConverter.cs(GalaxyBudsClient/Interface/Converters)共同完成枚举值到本地化文案的转换。
五、如何为法语翻译贡献:实操路径
综合报告与源码,补齐法语翻译的完整工作流如下:
- 读取缺失清单:打开 meta/fr.md,以"Missing strings"表格为准(当前 294 条);
- 定位资源字典:在 GalaxyBudsClient/i18n/fr.axaml 中按模块注释分区找到对应位置,为缺失 Key 添加
<sys:String x:Key="...">法语译文</sys:String>; - 遵循英文基准:以 GalaxyBudsClient/i18n/en.axaml 对应 Key 的原文为准翻译,保留
{0}、{1}占位符与换行结构; - 保持术语一致:沿用 fr.axaml 既有术语(Pavé tactile、Son environnant、Réduction de bruit active 等);
- 不可手动改动报告:meta/fr.md 由 XamlTranslationValidator 自动生成,翻译贡献者不应手工编辑该文件,只需更新 fr.axaml;工具在下次运行时会自动重新生成报告与 meta/translations.md 进度总表;
- 验证:运行时缺失词条会回退为英文(见
Loc.ResolveOrDefault的兜底逻辑),翻译完成后应实际运行应用切换法语界面检查显示效果。
六、从 fr.md 管窥项目本地化体系全貌
虽然 fr.md 只是单语言报告,但它完整展示了 GalaxyBudsClient 本地化工程的运作模式:
- 自动化闭环:报告由 XamlTranslationValidator 自动对比基准与目标字典生成,进度、缺失数、缺失明细均为机器产出,避免人工维护的滞后与错漏;
- 中心化的资源字典:所有语言共享同一套 Key 体系,界面通过
TranslateExtension+Loc动态绑定,新增词条只需改 en.axaml 与各语言字典,无需改动界面代码; - 健壮的降级策略:任何语言的缺失词条都不会破坏界面,而是优雅回退英文,缺失报告由此既是"待办清单"也是"运行时行为说明书";
- 覆盖面广的功能模块:从基础词条到隐藏模式、Multipoint、360 音频、固件刷写等深度功能均有对应文案,反映该项目在桌面端提供的功能远多于官方应用。
当前法语 50% 的进度意味着用户有一半界面以英文呈现。对于想看到完整法语界面的用户,最直接的路径就是按上述流程补齐 fr.axaml 中的缺失词条;对于想了解本地化机制的开发者,LocalizationUtils.cs、TranslateExtension.cs 与 LocalizationKeySourceGenerator.cs 则是理解整套体系的最佳入口。