From acf2b9bea7409c9317e0b5d344868cc3c9f27138 Mon Sep 17 00:00:00 2001
From: Hen <68553709+henmalib@users.noreply.github.com>
Date: Thu, 13 Nov 2025 03:21:18 +0100
Subject: [PATCH] android(i18n): added ukrainian translation (#245)
feat(i18n): added ukrainian translation with extracting of some string to resources. Auto generation of locale config
---
android/app/build.gradle.kts | 3 +
.../screens/AccessibilitySettingsScreen.kt | 24 +-
.../screens/AirPodsSettingsScreen.kt | 2 +-
.../screens/PressAndHoldSettingsScreen.kt | 8 +-
android/app/src/main/res/resources.properties | 1 +
.../app/src/main/res/values-uk/strings.xml | 217 ++++++++++++++++++
android/app/src/main/res/values/strings.xml | 4 +
7 files changed, 242 insertions(+), 17 deletions(-)
create mode 100644 android/app/src/main/res/resources.properties
create mode 100644 android/app/src/main/res/values-uk/strings.xml
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
index fe0c8bd..cab99bd 100644
--- a/android/app/build.gradle.kts
+++ b/android/app/build.gradle.kts
@@ -38,6 +38,9 @@ android {
compose = true
viewBinding = true
}
+ androidResources {
+ generateLocaleConfig = true
+ }
externalNativeBuild {
cmake {
path = file("src/main/cpp/CMakeLists.txt")
diff --git a/android/app/src/main/java/me/kavishdevar/librepods/screens/AccessibilitySettingsScreen.kt b/android/app/src/main/java/me/kavishdevar/librepods/screens/AccessibilitySettingsScreen.kt
index 0a37dfd..adda25e 100644
--- a/android/app/src/main/java/me/kavishdevar/librepods/screens/AccessibilitySettingsScreen.kt
+++ b/android/app/src/main/java/me/kavishdevar/librepods/screens/AccessibilitySettingsScreen.kt
@@ -160,9 +160,9 @@ fun AccessibilitySettingsScreen(navController: NavController) {
val mediaEQEnabled = remember { mutableStateOf(false) }
val pressSpeedOptions = mapOf(
- 0.toByte() to "Default",
- 1.toByte() to "Slower",
- 2.toByte() to "Slowest"
+ 0.toByte() to stringResource(R.string.default_option),
+ 1.toByte() to stringResource(R.string.slower),
+ 2.toByte() to stringResource(R.string.slowest)
)
val selectedPressSpeedValue =
aacpManager?.controlCommandStatusList?.find { it.identifier == AACPManager.Companion.ControlCommandIdentifiers.DOUBLE_CLICK_INTERVAL }?.value?.takeIf { it.isNotEmpty() }
@@ -196,9 +196,9 @@ fun AccessibilitySettingsScreen(navController: NavController) {
}
val pressAndHoldDurationOptions = mapOf(
- 0.toByte() to "Default",
- 1.toByte() to "Slower",
- 2.toByte() to "Slowest"
+ 0.toByte() to stringResource(R.string.default_option),
+ 1.toByte() to stringResource(R.string.slower),
+ 2.toByte() to stringResource(R.string.slowest)
)
val selectedPressAndHoldDurationValue =
aacpManager?.controlCommandStatusList?.find { it.identifier == AACPManager.Companion.ControlCommandIdentifiers.CLICK_HOLD_INTERVAL }?.value?.takeIf { it.isNotEmpty() }
@@ -234,9 +234,9 @@ fun AccessibilitySettingsScreen(navController: NavController) {
}
val volumeSwipeSpeedOptions = mapOf(
- 1.toByte() to "Default",
- 2.toByte() to "Longer",
- 3.toByte() to "Longest"
+ 1.toByte() to stringResource(R.string.default_option),
+ 2.toByte() to stringResource(R.string.longer),
+ 3.toByte() to stringResource(R.string.longest)
)
val selectedVolumeSwipeSpeedValue =
aacpManager?.controlCommandStatusList?.find { it.identifier == AACPManager.Companion.ControlCommandIdentifiers.VOLUME_SWIPE_INTERVAL }?.value?.takeIf { it.isNotEmpty() }
@@ -322,7 +322,7 @@ fun AccessibilitySettingsScreen(navController: NavController) {
label = stringResource(R.string.press_speed),
description = stringResource(R.string.press_speed_description),
options = pressSpeedOptions.values.toList(),
- selectedOption = selectedPressSpeed?: "Default",
+ selectedOption = selectedPressSpeed?: stringResource(R.string.default_option),
onOptionSelected = { newValue ->
selectedPressSpeed = newValue
aacpManager?.sendControlCommand(
@@ -340,7 +340,7 @@ fun AccessibilitySettingsScreen(navController: NavController) {
label = stringResource(R.string.press_and_hold_duration),
description = stringResource(R.string.press_and_hold_duration_description),
options = pressAndHoldDurationOptions.values.toList(),
- selectedOption = selectedPressAndHoldDuration?: "Default",
+ selectedOption = selectedPressAndHoldDuration?: stringResource(R.string.default_option),
onOptionSelected = { newValue ->
selectedPressAndHoldDuration = newValue
aacpManager?.sendControlCommand(
@@ -403,7 +403,7 @@ fun AccessibilitySettingsScreen(navController: NavController) {
label = stringResource(R.string.volume_swipe_speed),
description = stringResource(R.string.volume_swipe_speed_description),
options = volumeSwipeSpeedOptions.values.toList(),
- selectedOption = selectedVolumeSwipeSpeed?: "Default",
+ selectedOption = selectedVolumeSwipeSpeed?: stringResource(R.string.default_option),
onOptionSelected = { newValue ->
selectedVolumeSwipeSpeed = newValue
aacpManager?.sendControlCommand(
diff --git a/android/app/src/main/java/me/kavishdevar/librepods/screens/AirPodsSettingsScreen.kt b/android/app/src/main/java/me/kavishdevar/librepods/screens/AirPodsSettingsScreen.kt
index 90ef913..aaeda6a 100644
--- a/android/app/src/main/java/me/kavishdevar/librepods/screens/AirPodsSettingsScreen.kt
+++ b/android/app/src/main/java/me/kavishdevar/librepods/screens/AirPodsSettingsScreen.kt
@@ -384,7 +384,7 @@ fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService,
.fillMaxWidth(0.9f)
) {
Text(
- text = "Troubleshoot Connection",
+ text = stringResource(R.string.troubleshooting),
style = TextStyle(
fontSize = 16.sp,
fontWeight = FontWeight.Medium,
diff --git a/android/app/src/main/java/me/kavishdevar/librepods/screens/PressAndHoldSettingsScreen.kt b/android/app/src/main/java/me/kavishdevar/librepods/screens/PressAndHoldSettingsScreen.kt
index c6b2e40..6768694 100644
--- a/android/app/src/main/java/me/kavishdevar/librepods/screens/PressAndHoldSettingsScreen.kt
+++ b/android/app/src/main/java/me/kavishdevar/librepods/screens/PressAndHoldSettingsScreen.kt
@@ -186,7 +186,7 @@ fun LongPress(navController: NavController, name: String) {
listeningModeItems.add(
SelectItem(
name = stringResource(R.string.off),
- description = "Turns off noise management",
+ description = stringResource(R.string.listening_mode_off_description),
iconRes = R.drawable.noise_cancellation,
selected = (currentByte and 0x01) != 0,
onClick = {
@@ -212,7 +212,7 @@ fun LongPress(navController: NavController, name: String) {
listeningModeItems.addAll(listOf(
SelectItem(
name = stringResource(R.string.transparency),
- description = "Lets in external sounds",
+ description = stringResource(R.string.listening_mode_transparency_description),
iconRes = R.drawable.transparency,
selected = (currentByte and 0x04) != 0,
onClick = {
@@ -235,7 +235,7 @@ fun LongPress(navController: NavController, name: String) {
),
SelectItem(
name = stringResource(R.string.adaptive),
- description = "Dynamically adjust external noise",
+ description = stringResource(R.string.listening_mode_adaptive_description),
iconRes = R.drawable.adaptive,
selected = (currentByte and 0x08) != 0,
onClick = {
@@ -258,7 +258,7 @@ fun LongPress(navController: NavController, name: String) {
),
SelectItem(
name = stringResource(R.string.noise_cancellation),
- description = "Blocks out external sounds",
+ description = stringResource(R.string.listening_mode_noise_cancellation_description),
iconRes = R.drawable.noise_cancellation,
selected = (currentByte and 0x02) != 0,
onClick = {
diff --git a/android/app/src/main/res/resources.properties b/android/app/src/main/res/resources.properties
new file mode 100644
index 0000000..92481bb
--- /dev/null
+++ b/android/app/src/main/res/resources.properties
@@ -0,0 +1 @@
+unqualifiedResLocale=en
diff --git a/android/app/src/main/res/values-uk/strings.xml b/android/app/src/main/res/values-uk/strings.xml
new file mode 100644
index 0000000..c3ae2a0
--- /dev/null
+++ b/android/app/src/main/res/values-uk/strings.xml
@@ -0,0 +1,217 @@
+
+ LibrePods
+ Звільніть ваші AirPods від екосистеми Apple
+ Перегляньте статус батареї ваших AirPods прямо з головного екрана!
+ Доступність
+ Гучність Тону
+ Налаштуйте гучність тону звукових ефектів, які відтворюються на AirPods.
+ Аудіо
+ Адаптивний Звук
+ Налаштувати Адаптивний Звук
+ Адаптивний звук динамічно реагує на ваше оточення та приглушує або пропускає зовнішній шум. Ви можете налаштувати Адаптивний Звук, щоб пропускати більше або менше шуму.
+ Навушники
+ Кейс
+ Тест
+ Назва
+ Режим Прослуховування
+ Вимкнено
+ Проникність
+ Адаптування
+ Шумогасіння
+ Натисніть і утримуйте AirPods
+ Натисніть і утримуйте ніжку, щоб перемикатися між обраними режимами прослуховування.
+ Жести Головою
+ Лівий
+ Правий
+ Виявлення Розмови
+ Знижує гучність медіа та зменшує фоновий шум, коли ви починаєте говорити.
+ Персональна Гучність
+ Налаштовує гучність медіа відповідно до вашого оточення.
+ Шумогасіння з одним AirPod
+ Дозволяє вмикати режим шумогасіння на AirPods, коли лише один AirPod знаходиться у вашому вусі.
+ Налаштування Гучності
+ Налаштуйте гучність, проводячи вгору або вниз по сенсору, розташованому на ніжці AirPods Pro.
+ AirPods не підключені
+ Будь ласка, підключіть ваші AirPods, щоб отримати доступ до налаштувань.
+ Назад
+ Персоналізація
+ Відносна гучність
+ Зменшує до відсотка від поточної гучності, а не від максимальної.
+ Призупинити Музику
+ Коли ви почнете говорити, музику буде призупинено.
+ ПРИКЛАД
+ Додати віджет
+ Керуйте режимом шумоконтролю прямо з головного екрана.
+ Підключено
+ Підключено до Linux
+ Підключено
+ Переміщено до Linux
+ Переміщено до %1$s
+ Перепідключитися через повідомлення
+ Відстеження Голови
+ Кивніть, щоб відповісти на дзвінок, і похитайте головою, щоб відхилити.
+ Основне
+ Дія плитки швидких налаштувань
+ Показати діалог шумоконтролю при натисканні.
+ Перемикатися між режимами при натисканні.
+ Розробник
+ Відкрити Налаштування AirPods
+ Керуйте функціями та налаштуваннями AirPods
+ Автоматичне Розпізнавання Вуха
+ Автовідтворення
+ Автопауза
+ Усунення несправностей
+ Зібрати логи для діагностики проблем з підключенням AirPods
+ Зібрати Логи
+ Збережені Логи
+ Збережені Логи не знайдено
+ Налаштування авто-підключення
+ Підключатися до ваших AirPods, коли їхній статус:
+ Відʼєднано
+ AirPods не підключені до жодного пристрою
+ Бездіяльний
+ Пристрій підключено до ваших AirPods, але не відтворює медіа і не на дзвінку
+ Відтворення медіа
+ Пристрій відтворює медіа на ваших AirPods
+ На дзвінку
+ Пристрій на дзвінку з вашими AirPods
+ Підключатися до AirPods, коли ваш телефон:
+ Отримання дзвінка
+ Ваш телефон починає дзвонити
+ Початок відтворення медіа
+ Ваш телефон починає відтворювати медіа
+ Скасувати
+ Ви можете налаштувати режим проникності для ваших AirPods Pro, щоб допомогти чути, що відбувається навколо.
+ Зменшення гучних звуків може активно зменшити вплив гучних навколишніх шумів на вас у режимах Проникності та Адаптування. Зменшення гучних звуків не активне у вимкненому режимі.
+ Зменшення гучних звуків
+ Контроль дзвінків
+ Підключатися до цього пристрою автоматично
+ Коли ця опція ввімкнена, AirPods будуть автоматично підключатися до цього пристрою. Коли вимкнена, вони будуть автопідключатися лише до пристрою, до якого підключалися востаннє.
+ Призупинити медіа при засипанні
+ Вимкнути режим прослуховування
+ Коли це ввімкнено, режими прослуховування AirPods будуть включати опцію «Вимкнено». Гучні звуки не зменшуються, коли режим прослуховування встановлений на «Вимкнено».
+ Мікрофон
+ Режим мікрофона
+ Автоматичний
+ Завжди правий
+ Завжди лівий
+ Відповісти на дзвінок
+ Вимкнути/Увімкнути звук
+ Завершити Дзвінок
+ Натиснути один раз
+ Натиснути двічі
+ Слуховий апарат
+ Налаштування
+ Провести пальцем для керування підсиленням
+ Коли в режимі Проникності і медіа не відтворюється, проведіть пальцем вгору або вниз по сенсорних елементах керування ваших AirPods Pro, щоб збільшити або зменшити підсилення навколишніх звуків.
+ Режим Проникності
+ Налаштувати режим проникності
+ Швидкість натискання
+ Налаштуйте швидкість, необхідну для натискання два або три рази на ваших AirPods.
+ Тривалість натискання і утримування
+ Налаштуйте тривалість, необхідну для натискання і утримування на ваших AirPods.
+ Швидкість проведення пальцем для гучності
+ Щоб запобігти ненавмисним налаштуванням гучності, виберіть бажаний час очікування між проведеннями пальцем.
+ Еквалайзер
+ Застосувати EQ до
+ Телефон
+ Медіа
+ Смуга %d
+ За замовчуванням
+ Повільніше
+ Найповільніше
+ Довше
+ Найдовше
+ Темніше
+ Яскравіше
+ Менше
+ Більше
+ Підсилення
+ Баланс
+ Тон
+ Зменшення навколишнього шуму
+ Підсилення розмови
+ Підсилення розмови фокусує ваші AirPods Pro на людині, яка говорить перед вами, полегшуючи спілкування віч-на-віч.
+ AirPods можуть використовувати результати тесту слуху для налаштувань, які покращують чіткість голосів та звуків навколо вас.\n\nРежим слухового апарата призначений лише для людей із легким або помірним зниженням слуху.
+ Допомога з медіа
+ AirPods Pro можуть використовувати результати тесту слуху для налаштувань, які покращують чіткість музики, відео та дзвінків.
+ Налаштувати музику та відео
+ Налаштувати дзвінки
+ Віджет
+ Показати заряд телефону у віджеті
+ Відображати рівень заряду вашого телефону у віджеті разом із зарядом AirPods
+ Гучність Усвідомлення Розмови
+ Плитка Швидких Налаштувань
+ Відкрити діалог для керування
+ Якщо вимкнено, натискання на плитку швидких налаштувань перемикатиме між режимами. Якщо ввімкнено, вона покаже діалог для керування режимом шумоконтролю та усвідомленням розмови
+ Відʼєднати AirPods, коли ви їх не носите
+ Ви все ще зможете керувати ними через додаток — це просто відʼєднує аудіо.
+ Розширені Налаштування
+ Встановити Ключ Ідентифікації (IRK)
+ Вручну встановити значення IRK, що використовується для розпізнавання випадкових адрес BLE
+ Встановити Ключ Шифрування
+ Вручну встановити значення ENC_KEY, що використовується для розшифровки оголошень BLE
+ Використовувати альтернативні пакети відстеження голови
+ Ввімкніть це, якщо відстеження голови не працює у вас. Це надсилає різні дані до AirPods для запиту/зупинки даних відстеження голови.
+ Діяти як пристрій Apple
+ Увімкнює багатопристроєву з\'єднаність та функції доступності, такі як налаштування режиму проникності (підсилення, тон, зменшення навколишнього шуму, підсилення розмови та еквалайзер)
+ Може бути нестабільним!! Максимум два пристрої можуть бути підключені до ваших AirPods. Якщо ви використовуєте з пристроєм Apple, таким як iPad або Mac, то спочатку підключіть цей пристрій, а потім ваш Android.
+ Скинути Зміщення Хука
+ Це очистить поточне зміщення хука та потребуватиме повторного налаштування. Ви впевнені, що хочете продовжити?
+ Скинути
+ Зміщення хука було скинуто. Перенаправлення до налаштування...
+ Не вдалося скинути зміщення хука
+ IRK було успішно встановлено
+ Ключ шифрування було успішно встановлено
+ Шістнадцяткове Значення IRK
+ Шістнадцяткове Значення ENC_KEY
+ Введіть 16-байтовий IRK як шістнадцятковий рядок (32 символи):
+ Введіть 16-байтовий ENC_KEY як шістнадцятковий рядок (32 символи):
+ Має бути точно 32 шістнадцяткових символи
+ Помилка перетворення шістнадцяткового числа:
+ Знайдено зміщення, будь ласка, перезапустіть Bluetooth
+ Цифровий Асистент
+ Увімкнено
+ Дистанційне Управління Камерою
+ Управління Камерою
+ Зробіть фото, почніть або зупиніть запис та інше, натиснувши один раз або утримавши ніжку. Коли використовуєте AirPods для керування камерою, якщо ви оберете одне натискання, жести керування медіа будуть недоступні, а якщо утримання, режими прослуховування та жести Цифрового Асистента будуть недоступні.
+ Встановіть власну програму для виявлення камери
+ Встановити власний ID програми камери
+ Введіть ID програми камери:
+ Власний ID програми камери
+ Власний ID програми камери встановлено успішно
+ Слухач камери
+ Служба слухача LibrePods для виявлення, коли камера активна, щоб активувати керування камерою на AirPods.
+ Ліцензії Відкритого Коду
+ Оновити Тест Слуху
+ Оновити Результат Тесту Слуху
+ Менеджер АТТ відсутній, спробуйте перепідключитися.
+ Для використання додатку потрібні наступні дозволи. Будь ласка, надайте їх, щоб продовжити.
+ Похитайте головою або кивніть!
+ Потрібен Root-доступ
+ Цей додаток потребує root-доступу, щоб підключитися до бібліотеки Bluetooth
+ Root-доступ було відмовлено. Будь ласка, надайте root-дозволи.
+ Кроки Усунення Несправностей
+ Будь ласка, введіть значення втрат у дБНС
+ Про додаток
+ Назва Моделі
+ Номер Моделі
+ Серійний Номер
+ Версія
+ Здоров\'я Слуху
+ Захист Слуху
+ Використання На Робочому Місці
+ Захист EN 352
+ Захист EN 352 обмежує максимальний рівень медіа до 82 дБА та відповідає застосовним стандартам EN 352 для особистого захисту слуху.
+ Навколишній Шум
+ Перепідключитися до останнього підключеного пристрою
+ Відʼєднатися
+ Підтримати мене
+ Ніколи не показувати знову
+ Нещодавно я втратив свій лівий AirPod. Якщо LibrePods виявилися корисними для вас, розгляньте можливість підтримати мене на GitHub Sponsors, щоб я міг купити заміну та продовжити роботу над цим проектом — навіть невелика допомога має велике значення. Дякую за вашу підтримку!
+ Підтримати LibrePods
+ Вимикає керування шумом
+ Пропускає зовнішні звуки
+ Динамічно налаштовує зовнішній шум
+ Блокує зовнішні звуки
+
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index 4f6b82b..74ae083 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -210,4 +210,8 @@
Never show again
I recently lost my left AirPod. If you\'ve found LibrePods useful, consider supporting me on GitHub Sponsors so I can buy a replacement and continue working on this project- even a little amount goes a long way. Thank you for your support!
Support LibrePods
+ Turns off noise management
+ Lets in external sounds
+ Dynamically adjust external noise
+ Blocks out external sounds