mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5860bbffb6 | ||
|
|
da53d68190 | ||
|
|
b397bf190c | ||
|
|
15d664c361 | ||
|
|
d2f24d8b95 | ||
|
|
b5436659b6 | ||
|
|
1cfc4611cb | ||
|
|
bda0a20743 | ||
|
|
09bad90c0c | ||
|
|
34856607f8 |
Vendored
+1
-22
@@ -1,23 +1,2 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
-keep class eu.darken.capod.BuildConfig { *; }
|
||||
-dontobfuscate
|
||||
@@ -2,4 +2,5 @@
|
||||
<resources>
|
||||
<string name="upgrades_gplay_unavailable_error">Služby Google Play nie sú k dispozícii.</string>
|
||||
<string name="upgrades_no_purchases_found_check_account">Nenašli sa žiadne nákupy. Používate správny účet?</string>
|
||||
<string name="upgrades_gplay_billing_error_label">Chyba Google Play</string>
|
||||
</resources>
|
||||
|
||||
@@ -2,4 +2,8 @@
|
||||
<resources>
|
||||
<string name="upgrades_gplay_unavailable_error">Google Play 服務無法使用。</string>
|
||||
<string name="upgrades_no_purchases_found_check_account">未找到訂單,確定帳戶無誤?</string>
|
||||
<string name="upgrades_gplay_billing_error_label">Google Play 錯誤</string>
|
||||
<string name="upgrades_gplay_billing_error_description">Google Play 發生錯誤。請稍後再試或重新啟動手機。\n\n錯誤:%s</string>
|
||||
<string name="upgrades_gplay_billing_result_error_label">Google Play 結帳錯誤</string>
|
||||
<string name="upgrades_gplay_billing_result_error_description">向 Google Play 請求購買明細時發生錯誤。請清除 Google Play 快取並重新啟動手機。\n\n錯誤:%s</string>
|
||||
</resources>
|
||||
|
||||
@@ -12,8 +12,8 @@ import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.ParcelUuid
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import eu.darken.capod.common.coroutine.AppScope
|
||||
import eu.darken.capod.common.coroutine.DispatcherProvider
|
||||
import eu.darken.capod.common.debug.Bugs
|
||||
import eu.darken.capod.common.debug.logging.Logging.Priority.ERROR
|
||||
@@ -21,27 +21,38 @@ import eu.darken.capod.common.debug.logging.Logging.Priority.VERBOSE
|
||||
import eu.darken.capod.common.debug.logging.Logging.Priority.WARN
|
||||
import eu.darken.capod.common.debug.logging.log
|
||||
import eu.darken.capod.common.debug.logging.logTag
|
||||
import eu.darken.capod.common.flow.setupCommonEventHandlers
|
||||
import eu.darken.capod.pods.core.apple.protocol.ContinuityProtocol
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.retryWhen
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.plus
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import java.io.IOException
|
||||
import java.time.Instant
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class BluetoothManager2 @Inject constructor(
|
||||
private val manager: BluetoothManager,
|
||||
@ApplicationContext private val context: Context,
|
||||
@AppScope private val appScope: CoroutineScope,
|
||||
private val dispatcherProvider: DispatcherProvider,
|
||||
@ApplicationContext private val context: Context,
|
||||
private val manager: BluetoothManager,
|
||||
) {
|
||||
|
||||
val adapter: BluetoothAdapter?
|
||||
@@ -89,7 +100,7 @@ class BluetoothManager2 @Inject constructor(
|
||||
|
||||
override fun onServiceDisconnected(profile: Int) {
|
||||
log(TAG, WARN) { "onServiceDisconnected(profile=$profile)" }
|
||||
close(IOException("BluetoothProfile service disconnected (profile=$profile)"))
|
||||
close() // Close gracefully without exception to prevent crash
|
||||
}
|
||||
|
||||
}, profile)
|
||||
@@ -103,59 +114,117 @@ class BluetoothManager2 @Inject constructor(
|
||||
}
|
||||
|
||||
|
||||
private fun monitorDevicesForProfile(
|
||||
private fun monitorProfile(
|
||||
profile: Int = BluetoothProfile.HEADSET
|
||||
): Flow<Set<BluetoothDevice>> = getBluetoothProfile(profile).flatMapLatest { bluetoothProfile ->
|
||||
callbackFlow {
|
||||
log(TAG, VERBOSE) { "connectedDevices(profile=$profile) starting" }
|
||||
trySend(bluetoothProfile.connectedDevices)
|
||||
log(TAG, VERBOSE) { "monitorProfile(): for profile=$profile starting" }
|
||||
|
||||
try {
|
||||
trySend(bluetoothProfile.connectedDevices)
|
||||
} catch (e: Exception) {
|
||||
log(TAG, ERROR) { "monitorProfile(): Error querying initial connected devices: $e" }
|
||||
close(e)
|
||||
return@callbackFlow
|
||||
}
|
||||
|
||||
val filter = IntentFilter().apply {
|
||||
addAction(BluetoothDevice.ACTION_ACL_CONNECTED)
|
||||
addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
|
||||
addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)
|
||||
}
|
||||
|
||||
val handlerThread = HandlerThread("BluetoothEventReceiver").apply {
|
||||
start()
|
||||
}
|
||||
val handlerThread = HandlerThread("BluetoothEventReceiver").apply { start() }
|
||||
val handler = Handler(handlerThread.looper)
|
||||
|
||||
val receiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
log(TAG, VERBOSE) { "Bluetooth event (intent=$intent, extras=${intent.extras})" }
|
||||
val action = intent.action
|
||||
if (action == null) {
|
||||
log(TAG, ERROR) { "Bluetooth event without action, how did we get this?" }
|
||||
log(TAG, VERBOSE) { "monitorProfile(): Bluetooth event (intent=$intent, extras=${intent.extras})" }
|
||||
|
||||
if (intent.action == null) {
|
||||
log(TAG, ERROR) { "monitorProfile(): Bluetooth event without action?" }
|
||||
return
|
||||
}
|
||||
val device = intent.getParcelableExtra<BluetoothDevice?>(BluetoothDevice.EXTRA_DEVICE)
|
||||
if (device == null) {
|
||||
log(TAG, ERROR) { "Connection event is missing EXTRA_DEVICE: ${intent.extras}" }
|
||||
log(TAG, ERROR) { "monitorProfile(): Event is missing EXTRA_DEVICE" }
|
||||
return
|
||||
}
|
||||
|
||||
this@callbackFlow.launch {
|
||||
val currentDevices = bluetoothProfile.connectedDevices
|
||||
if (intent.action != BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED) {
|
||||
log(TAG, WARN) { "Unknown action: ${intent.action}" }
|
||||
return@launch
|
||||
}
|
||||
|
||||
when (action) {
|
||||
BluetoothDevice.ACTION_ACL_CONNECTED -> {
|
||||
log(TAG) { "Adding $device to current devices $currentDevices" }
|
||||
trySend(currentDevices.plus(device))
|
||||
// Profile connection changed - query actual state from proxy
|
||||
val statePrevious = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1)
|
||||
log(TAG) { "monitorProfile(): HEADSET profile state changed for $device - previous: $statePrevious" }
|
||||
|
||||
val stateNow = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)
|
||||
log(TAG) { "monitorProfile(): HEADSET profile state changed for $device - now: $stateNow" }
|
||||
|
||||
val currentDevices = try {
|
||||
bluetoothProfile.connectedDevices
|
||||
} catch (e: Exception) {
|
||||
log(TAG, ERROR) { "monitorProfile(): Error handling profile event: $e" }
|
||||
// Log but continue - don't kill the whole Flow for one bad event
|
||||
emptySet()
|
||||
}.toMutableSet()
|
||||
log(TAG) { "monitorProfile(): currentDevices: $currentDevices" }
|
||||
|
||||
when (stateNow) {
|
||||
BluetoothProfile.STATE_CONNECTING -> {
|
||||
log(TAG) { "monitorProfile(): Currently connecting $device" }
|
||||
}
|
||||
|
||||
BluetoothDevice.ACTION_ACL_DISCONNECTED -> {
|
||||
log(TAG) { "Removing $device from current devices $currentDevices" }
|
||||
trySend(currentDevices.minus(device))
|
||||
BluetoothProfile.STATE_CONNECTED -> {
|
||||
log(TAG) { "monitorProfile(): Device has connected $device" }
|
||||
if (!currentDevices.contains(device)) {
|
||||
log(
|
||||
TAG,
|
||||
VERBOSE
|
||||
) { "monitorProfile(): $device not in proxy yet, adding manually" }
|
||||
currentDevices.add(device)
|
||||
}
|
||||
trySend(currentDevices)
|
||||
}
|
||||
|
||||
BluetoothProfile.STATE_DISCONNECTING -> {
|
||||
log(TAG) { "monitorProfile(): Currently DISconnecting $device" }
|
||||
}
|
||||
|
||||
BluetoothProfile.STATE_DISCONNECTED -> {
|
||||
log(TAG) { "monitorProfile(): Device has disconnected $device" }
|
||||
if (currentDevices.contains(device)) {
|
||||
log(
|
||||
TAG,
|
||||
VERBOSE
|
||||
) { "monitorProfile(): $device still in proxy, removing manually" }
|
||||
currentDevices.remove(device)
|
||||
}
|
||||
trySend(currentDevices)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
context.registerReceiver(receiver, filter, null, handler)
|
||||
|
||||
try {
|
||||
context.registerReceiver(receiver, filter, null, handler)
|
||||
} catch (e: Exception) {
|
||||
log(TAG, ERROR) { "monitorProfile(): Failed to register receiver: $e" }
|
||||
close(e)
|
||||
return@callbackFlow
|
||||
}
|
||||
|
||||
awaitClose {
|
||||
log(TAG, VERBOSE) { "connectedDevices(profile=$profile) closed." }
|
||||
context.unregisterReceiver(receiver)
|
||||
log(TAG, VERBOSE) { "monitorProfile(): profile=$profile closed." }
|
||||
try {
|
||||
context.unregisterReceiver(receiver)
|
||||
} catch (e: Exception) {
|
||||
log(TAG, ERROR) { "monitorProfile(): Error unregistering receiver: $e" }
|
||||
} finally {
|
||||
handlerThread.quitSafely()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,10 +232,11 @@ class BluetoothManager2 @Inject constructor(
|
||||
private val seenDevicesLock = Mutex()
|
||||
private val seenDevicesCache = mutableMapOf<String, Instant>()
|
||||
|
||||
fun connectedDevices(
|
||||
featureFilter: Set<ParcelUuid> = ContinuityProtocol.BLE_FEATURE_UUIDS
|
||||
): Flow<List<BluetoothDevice2>> = isBluetoothEnabled
|
||||
.flatMapLatest { monitorDevicesForProfile(BluetoothProfile.HEADSET) }
|
||||
val connectedDevices: Flow<List<BluetoothDevice2>> = isBluetoothEnabled
|
||||
.flatMapLatest { enabled ->
|
||||
if (enabled) monitorProfile(BluetoothProfile.HEADSET)
|
||||
else flowOf(emptySet()) // Return empty when Bluetooth is off
|
||||
}
|
||||
.map { devices ->
|
||||
val currentAddresses = devices.map { it.address }
|
||||
|
||||
@@ -177,7 +247,9 @@ class BluetoothManager2 @Inject constructor(
|
||||
}
|
||||
|
||||
devices
|
||||
.filter { device -> featureFilter.any { feature -> device.hasFeature(feature) } }
|
||||
.filter { device ->
|
||||
ContinuityProtocol.BLE_FEATURE_UUIDS.any { feature -> device.hasFeature(feature) }
|
||||
}
|
||||
.map { device ->
|
||||
BluetoothDevice2(
|
||||
internal = device,
|
||||
@@ -189,6 +261,30 @@ class BluetoothManager2 @Inject constructor(
|
||||
)
|
||||
}
|
||||
}
|
||||
.retryWhen { cause, attempt ->
|
||||
log(TAG, WARN) { "connectedDevices Flow failed (attempt ${attempt + 1}): $cause" }
|
||||
if (attempt < 3) {
|
||||
delay(1000 * (attempt + 1)) // 1s, 2s, 3s exponential backoff
|
||||
true // Retry
|
||||
} else {
|
||||
false // Give up after 3 attempts
|
||||
}
|
||||
}
|
||||
.catch { e ->
|
||||
log(TAG, ERROR) { "connectedDevices Flow failed after retries: $e" }
|
||||
emit(emptyList()) // Emit empty list and complete gracefully
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.setupCommonEventHandlers(TAG) { "connectedDevices" }
|
||||
.stateIn(
|
||||
scope = appScope + dispatcherProvider.IO,
|
||||
started = SharingStarted.WhileSubscribed(
|
||||
stopTimeoutMillis = 5_000L,
|
||||
replayExpirationMillis = 0L,
|
||||
),
|
||||
initialValue = null
|
||||
)
|
||||
.filterNotNull()
|
||||
|
||||
fun bondedDevices(): Flow<Set<BluetoothDevice2>> = flow {
|
||||
val rawDevices = adapter?.bondedDevices ?: throw IllegalStateException("Bluetooth adapter unavailable")
|
||||
|
||||
@@ -90,7 +90,7 @@ class OverviewFragmentVM @Inject constructor(
|
||||
|
||||
val shouldStartMonitor = when (generalSettings.monitorMode.value) {
|
||||
MonitorMode.MANUAL -> false
|
||||
MonitorMode.AUTOMATIC -> bluetoothManager.connectedDevices().first().isNotEmpty()
|
||||
MonitorMode.AUTOMATIC -> bluetoothManager.connectedDevices.first().isNotEmpty()
|
||||
MonitorMode.ALWAYS -> true
|
||||
}
|
||||
if (shouldStartMonitor) {
|
||||
|
||||
@@ -148,7 +148,7 @@ class MonitorWorker @AssistedInject constructor(
|
||||
combine(
|
||||
generalSettings.monitorMode.flow,
|
||||
profilesRepo.profiles,
|
||||
bluetoothManager.connectedDevices(),
|
||||
bluetoothManager.connectedDevices,
|
||||
) { monitorMode, profiles, connectedDevices ->
|
||||
listOf(monitorMode, profiles, connectedDevices)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import eu.darken.capod.profiles.core.DeviceProfilesRepo
|
||||
import eu.darken.capod.reaction.core.ReactionSettings
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.distinctUntilChangedBy
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
@@ -39,7 +38,7 @@ class AutoConnect @Inject constructor(
|
||||
.flatMapLatest { isAutoConnectEnabled ->
|
||||
if (isAutoConnectEnabled) {
|
||||
combine(
|
||||
bluetoothManager.connectedDevices().distinctUntilChanged(),
|
||||
bluetoothManager.connectedDevices,
|
||||
podMonitor.primaryDevice().filterNotNull().distinctUntilChangedBy { it.rawDataHex },
|
||||
) { connectedDevices, mainDevice ->
|
||||
connectedDevices to mainDevice
|
||||
|
||||
@@ -35,7 +35,7 @@ class PlayPause @Inject constructor(
|
||||
reactionSettings.autoPause.flow,
|
||||
reactionSettings.onePodMode.flow,
|
||||
) { play, pause, _ -> play || pause }
|
||||
.flatMapLatest { if (it) bluetoothManager.connectedDevices() else emptyFlow() }
|
||||
.flatMapLatest { if (it) bluetoothManager.connectedDevices else emptyFlow() }
|
||||
.flatMapLatest {
|
||||
if (it.isEmpty()) {
|
||||
log(TAG) { "No known devices connected." }
|
||||
|
||||
@@ -16,7 +16,6 @@ import eu.darken.capod.pods.core.apple.DualApplePods
|
||||
import eu.darken.capod.reaction.core.ReactionSettings
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.distinctUntilChangedBy
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
@@ -116,7 +115,7 @@ class PopUpReaction @Inject constructor(
|
||||
if (!isEnabled) return@flatMapLatest emptyFlow()
|
||||
|
||||
combine(
|
||||
bluetoothManager.connectedDevices().distinctUntilChanged(),
|
||||
bluetoothManager.connectedDevices,
|
||||
podMonitor.primaryDevice().distinctUntilChangedBy { it?.rawDataHex },
|
||||
) { devices, broadcast ->
|
||||
log(TAG) { "$broadcast $devices " }
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<string name="settings_support_description">Si necesitas ayuda.</string>
|
||||
<string name="issue_tracker_label">Seguidor de problemas</string>
|
||||
<string name="issue_tracker_description">Un seguidor público de problemas para reportes de errores y solicitudes de funciones (solo en inglés).</string>
|
||||
<string name="discord_label">En español</string>
|
||||
<string name="discord_label">Discord</string>
|
||||
<string name="discord_description">Un lugar para pasar el rato y hacer preguntas.</string>
|
||||
<string name="changelog_label">Registro de cambios</string>
|
||||
<string name="settings_label">Ajustes</string>
|
||||
@@ -98,7 +98,7 @@
|
||||
<string name="help_translate_label">Traducción</string>
|
||||
<string name="help_translate_description">Ayuda a traducir esta aplicación a tu idioma favorito.</string>
|
||||
<string name="translators_thanks_title">Traductores</string>
|
||||
<string name="translators_thanks_description">español</string>
|
||||
<string name="translators_thanks_description">Jaime Muñoz(jmmartin_5@outlook.com)</string>
|
||||
<string name="widget_description">Un widget que muestra el último estado conocido del dispositivo.</string>
|
||||
<string name="widget_configuration_title">Selecciona el dispositivo</string>
|
||||
<string name="widget_configuration_description">Elige qué perfil del dispositivo debe mostrar este complemento.</string>
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
<string name="settings_autopause_description">기기를 귀에서 빼면 오디오를 일시 중지합니다.</string>
|
||||
<string name="settings_autopplay_label">자동 재생</string>
|
||||
<string name="settings_autoplay_description">기기를 착용하면 오디오 재생을 시작합니다.</string>
|
||||
<string name="settings_eardetection_info_label">착용 감지 알림</string>
|
||||
<string name="settings_eardetection_info_description">Apple의 제한으로 착용 감지가 마이크를 이용하는 데 사용되는 한쪽 유닛만 작동할 수 있습니다. Apple 기기에서 다음에 따라 설정할 수 있습니다. 설정 → 블루투스 → Airpods → 마이크</string>
|
||||
<string name="settings_fake_data_label">가짜 데이터</string>
|
||||
<string name="settings_fake_data_description">가짜 데이터를 표시합니다. 즉, 존재하지 않는 기기를 시뮬레이션합니다.</string>
|
||||
<string name="settings_debug_label">디버그 설정</string>
|
||||
@@ -35,7 +37,7 @@
|
||||
<string name="settings_signal_minimum_label">최소 신호 품질</string>
|
||||
<string name="settings_signal_minimum_description">기기가 사용자의 것으로 간주되기 위해 필요한 최소 신호 품질입니다.</string>
|
||||
<string name="settings_autoconnect_label">자동 연결</string>
|
||||
<string name="settings_autoconnect_description">Android가 자동으로 연결되지 않으면 저희도 요청할 수 있습니다. 이렇게 하면 모니터 모드 설정이 \"항상\"으로 설정됩니다.</string>
|
||||
<string name="settings_autoconnect_description">Android가 자동으로 연결되지 않으면 저희도 요청할 수 있습니다. 이렇게 하면 모니터링 모드 설정이 \"항상\"으로 설정됩니다.</string>
|
||||
<string name="settings_autoconnect_condition_label">자동 연결 조건</string>
|
||||
<string name="settings_autoconnect_condition_description">언제 기기에 연결을 시도해야 할까요?</string>
|
||||
<string name="settings_devices_label">장치</string>
|
||||
@@ -49,7 +51,7 @@
|
||||
<string name="settings_compat_offloaded_filtering_disabled_summary">데이터 필터링을 시스템에 위임하지 말고 대신 모든 데이터를 가져와 앱 내에서 필터링합니다.</string>
|
||||
<string name="settings_compat_offloaded_batching_disabled_title">하드웨어 일괄 처리 비활성화</string>
|
||||
<string name="settings_compat_offloaded_batching_disabled_summary">수집된 BLE 데이터를 저희에게 전달하기 전에 시스템이 그룹화하도록 허용하지 마십시오.</string>
|
||||
<string name="settings_onepod_mode_label">단일 Pod 모드</string>
|
||||
<string name="settings_onepod_mode_label">단일 유닛 모드</string>
|
||||
<string name="settings_onepod_mode_description">양쪽 기기를 모두 착용할 필요 없이 한쪽만 착용해도 앱이 반응합니다.</string>
|
||||
<string name="settings_popup_caseopen_label">케이스 팝업 표시</string>
|
||||
<string name="settings_popup_caseopen_description">기기 케이스를 열면 팝업을 표시합니다(실험적).</string>
|
||||
@@ -98,6 +100,10 @@
|
||||
<string name="translators_thanks_title">번역가</string>
|
||||
<string name="translators_thanks_description">윤지호(annyeong1alt@gmail.com)</string>
|
||||
<string name="widget_description">마지막으로 알려진 기기 상태를 표시하는 위젯입니다.</string>
|
||||
<string name="widget_configuration_title">기기 선택</string>
|
||||
<string name="widget_configuration_description">이 위젯에 표시할 기기 프로필을 선택해 주세요.</string>
|
||||
<string name="common_feature_requires_pro_msg">이 기능을 사용하기 위해 CAPod Pro가 필요합니다.</string>
|
||||
<string name="widget_no_data_label">데이터 없음</string>
|
||||
<string name="settings_compat_indirectcallback_title">간접 데이터 전달</string>
|
||||
<string name="settings_compat_indirectcallback_summary">시스템에서 BLE 데이터를 수신하는 대체 방법을 사용합니다(콜백 대신 브로드캐스트).</string>
|
||||
<string name="troubleshooter_title">문제 해결사</string>
|
||||
@@ -130,15 +136,27 @@
|
||||
<string name="overview_nomaindevice_label">설정된 장치가 없음</string>
|
||||
<string name="overview_nomaindevice_description">배터리 잔량 감시와 추가 기능을 활성화하기 위해 당신의 장치를 설정하십시오.</string>
|
||||
<string name="overview_bluetooth_disabled_label">Bluetooth가 꺼져 있습니다</string>
|
||||
<string name="overview_monitoring_active_label">장치 감시중</string>
|
||||
<string name="overview_bluetooth_disabled_description">블루투스를 켜야 연결할 수 있어요 ;)</string>
|
||||
<string name="overview_monitoring_active_label">기기 모니터링 중</string>
|
||||
<string name="overview_monitoring_active_description">기기가 켜진 상태에서 가까이 위치해 있는지 확인해 주세요.</string>
|
||||
<string name="overview_unmatched_devices_label">일치하지 않는 기기</string>
|
||||
<plurals name="overview_unmatched_devices_count">
|
||||
<item quantity="other">%d프로필과 일치하지 않는 기기</item>
|
||||
</plurals>
|
||||
<string name="permission_bluetooth_connect_label">블루투스 연결</string>
|
||||
<string name="permission_bluetooth_connect_description">이 앱은 페어링된 기기와 상호작용하고 연결을 시작하기 위해 \"Bluetooth 연결\"권한을 필요로 합니다.</string>
|
||||
<string name="permission_bluetooth_connect_description">이 앱은 페어링 된 기기와 상호작용하고 연결을 시작하기 위해 \"Bluetooth 연결\"권한을 필요로 합니다.</string>
|
||||
<string name="permission_bluetooth_scan_label">Bluetooth 검색</string>
|
||||
<string name="permission_bluetooth_scan_description">\"Bluetooth 검색\" 권한은 앱이 당신의 AirPods같은 주변의 기기를 찾고 Bluetooth 데이터를 받도록 합니다.</string>
|
||||
<string name="permission_bluetooth_label">Bluetooth</string>
|
||||
<string name="permission_bluetooth_description">이 앱은 페어링 된 기기에 접근하기 위해 블루투스 권한을 필요로 합니다.</string>
|
||||
<string name="permission_access_fine_location_label">정밀 위치 접근</string>
|
||||
<string name="permission_access_fine_location_description">CAPod는 BLE 정보를 받기 위해 정밀 위치 접근 권한을 사용합니다. 앱은 블루투스 헤드폰의 BLE 기술을 사용해 기기의 상태에 접근합니다. CAPod는 이 권한으로 사용자의 위치를 확인하지 않습니다.</string>
|
||||
<string name="permission_background_location_label">백그라운드 위치 접근</string>
|
||||
<string name="permission_background_location_description">CAPod는 팝업 보기나 자동 연결과 같은 기능을 앱이 꺼져있는 상태에서도 사용할 수 있게 하기 위해 백그라운드 위치 접근 권한을 사용합니다. 백그라운드 위치 접근 권한은 백그라운드에서도 BLE 정보를 받을 수 있게 합니다. CAPod는 이 권한으로 사용자의 위치를 확인하지 않습니다.</string>
|
||||
<string name="permission_ignore_battery_optimizations_label">배터리 사용량 최적화 비활성화</string>
|
||||
<string name="permission_ignore_battery_optimizations_description">배터리 사용량 최적화는 앱이 백그라운드에서 Bluetooth 신호를 지속적으로 받지 못하게 합니다.</string>
|
||||
<string name="permission_required_title">다음과 같은 권한이 필요합니다:</string>
|
||||
<string name="permission_system_alert_window_label">시스템 알림창</string>
|
||||
<string name="permission_system_alert_window_description">\"팝업 표시\" 기능을 사용하려면 다른 앱 위에 그리기를 허용해야 합니다.</string>
|
||||
<string name="settings_scanner_mode_lowpower_label">저전력</string>
|
||||
<string name="settings_scanner_mode_balanced_label">균형잡힌</string>
|
||||
@@ -148,12 +166,57 @@
|
||||
<string name="settings_monitor_mode_always_label">항상</string>
|
||||
<string name="settings_reaction_autoconnect_whenseen_label">앱이 장치를 찾았을때</string>
|
||||
<string name="settings_reaction_autoconnect_caseopen_label">케이스가 열렸을때</string>
|
||||
<string name="settings_reaction_autoconnect_inear_label">귀에 착용했을때</string>
|
||||
<string name="settings_reaction_autoconnect_inear_label">귀에 착용했을 때</string>
|
||||
<string name="pods_dual_left_label">왼쪽 유닛</string>
|
||||
<string name="pods_dual_right_label">오른쪽 유닛</string>
|
||||
<string name="pods_case_label">케이스</string>
|
||||
<string name="pods_case_status_open_label">열림</string>
|
||||
<string name="pods_case_status_closed_label">닫힘</string>
|
||||
<string name="pods_connection_state_disconnected_label">연결되지 않음</string>
|
||||
<string name="pods_connection_state_idle_label">대기 모드</string>
|
||||
<string name="pods_connection_state_music_label">음악 모드</string>
|
||||
<string name="pods_connection_state_call_label">통화 모드</string>
|
||||
<string name="pods_connection_state_ringing_label">수신 중</string>
|
||||
<string name="pods_connection_state_hanging_up_label">끊는 중</string>
|
||||
<string name="pods_connection_state_unknown_label">연결 상태 알 수 없음</string>
|
||||
<string name="pods_unknown_raw_data_label">Raw data</string>
|
||||
<string name="pods_unknown_label">알 수 없는 기기</string>
|
||||
<string name="pods_unknown_contact_dev">알 수 없는 기기이나 비슷한 형식으로 정보를 보내는 기기인 것 같습니다. 제게 알려주시면 앱에 해당 기기 지원을 추가해 드릴게요 :)</string>
|
||||
<string name="pods_none_label_short">기기 없음</string>
|
||||
<string name="pods_charging_label">충전 중</string>
|
||||
<string name="pods_inear_label">착용 중</string>
|
||||
<string name="pods_microphone_label">마이크</string>
|
||||
<string name="pods_yours">내 기기</string>
|
||||
<string name="headset_being_worn_label">착용 중</string>
|
||||
<string name="headset_not_being_worn_label">착용하지 않음</string>
|
||||
<string name="pods_case_unknown_state">알 수 없는 상태</string>
|
||||
<string name="last_seen_x">마지막 업데이트: %s</string>
|
||||
<string name="first_seen_x">처음 업데이트: %s</string>
|
||||
<string name="permission_post_notifications_label">알림 표시</string>
|
||||
<string name="permission_post_notifications_description">"CAPod이 현재 연결 상태 등 AirPods에 대한 알림을 표시할 수 있도록 허용합니다."</string>
|
||||
<!-- Device profiles -->
|
||||
<string name="profiles_empty_title">기기 프로필이 설정되지 않음</string>
|
||||
<string name="profiles_empty_description">여러 기기를 설정하고 우선순위를 지정하기 위해 기기 프로필을 생성하세요.</string>
|
||||
<string name="profiles_add_action">프로필 추가</string>
|
||||
<string name="profiles_create_title">프로필 생성</string>
|
||||
<string name="profiles_name_label">프로필 이름</string>
|
||||
<string name="profiles_name_default">나의 헤드폰</string>
|
||||
<string name="profiles_model_label">기기 모델</string>
|
||||
<string name="profiles_paired_device_label">페어링 된 기기</string>
|
||||
<string name="profiles_paired_device_none">없음</string>
|
||||
<string name="profiles_paired_device_none_description">선택된 기기가 없습니다.</string>
|
||||
<string name="profiles_save_action">프로필 저장</string>
|
||||
<string name="profiles_drag_handle_description">드래그하여 순서 변경</string>
|
||||
<string name="profiles_delete_title">프로필 삭제</string>
|
||||
<string name="profiles_delete_message">프로필을 삭제하시겠습니까?
|
||||
이 작업은 취소할 수 없습니다.</string>
|
||||
<string name="profiles_delete_action">삭제</string>
|
||||
<string name="profiles_basic_info_title">기기 정보</string>
|
||||
<string name="profiles_basic_info_description">기기의 이름, 모델 및 선택적 블루투스 페어링을 설정하세요.</string>
|
||||
<string name="profiles_signal_quality_title">최소 신호 품질</string>
|
||||
<string name="profiles_signal_quality_description">이 수치 이상의 신호 세기를 가진 기기만이 감지 됩니다. 낮은 값은 감지 범위를 넓히지만, 오탐을 일으킬 수 있습니다. 너무 높은 값은 블루투스 수신이 거리와 장애물에 민감하기에 권장하지 않습니다.</string>
|
||||
<string name="profiles_identitykey_label">ID 키</string>
|
||||
<string name="profilessettings_maindevice_identitykey_description">기기의 ID 확인 키(IRK)로, CAPod가 주변 기기 중에서 해당 기기를 식별하는 데 도움이 됩니다.</string>
|
||||
<string name="profiles_maindevice_identitykey_explanation">AirPods은 개인정보 보호를 위해 자주 Bluetooth 주소를 변경합니다. IRK는 앱이 당신의 기기를 인식하는데 도움이 됩니다. MacBook을 잠깐 사용해야 합니다.</string>
|
||||
<string name="profiles_maindevice_encryptionkey_label">암호화 키</string>
|
||||
<string name="profiles_maindevice_encryptionkey_description">당신의 기기의 암호화 키. 앱이 구체적인 상태 정보를 불러올 수 있게 합니다.</string>
|
||||
@@ -163,4 +226,9 @@
|
||||
<string name="profiles_priority_hint">프로필 순서는 우선순위를 결정합니다. 프로필을 드래그하여 순서를 변경하세요.
|
||||
리스트의 위에 있을수록 여러 장치가 일치할때 우선순위가 높습니다.</string>
|
||||
<!-- Unsaved changes dialog -->
|
||||
<string name="general_unsaved_changes_title">저장되지 않은 변경 사항</string>
|
||||
<string name="general_unsaved_changes_message">저장되지 않은 변경 사항이 있습니다. 어떻게 하시겠습니까?</string>
|
||||
<string name="general_save_and_exit_action">저장 & 종료</string>
|
||||
<string name="general_discard_action">무시</string>
|
||||
<string name="general_keep_editing_action">계속 수정하기</string>
|
||||
</resources>
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
<string name="settings_autopause_description">Pauzeer de muziek wanneer u het apparaat van uw oor haalt.</string>
|
||||
<string name="settings_autopplay_label">Automatisch afspelen</string>
|
||||
<string name="settings_autoplay_description">Start audioweergave wanneer het apparaat wordt gedragen.</string>
|
||||
<string name="settings_eardetection_info_label">Ear detectie notitie</string>
|
||||
<string name="settings_eardetection_info_description">Als oordetectie slechts voor één pod werkt, is dit een beperking van Apple. Alleen de \"primaire pod\" (gebruikt voor de microfoon) wordt gedetecteerd. Configureer op Apple-apparaten: Instellingen → Bluetooth → AirPods → Microfoon.</string>
|
||||
<string name="settings_fake_data_label">Nep gegevens</string>
|
||||
<string name="settings_fake_data_description">Toon nepgegevens, d.w.z. simuleer apparaten die niet bestaan.</string>
|
||||
<string name="settings_debug_label">Foutopsporingsinstellingen</string>
|
||||
@@ -98,6 +100,10 @@
|
||||
<string name="translators_thanks_title">Vertalers</string>
|
||||
<string name="translators_thanks_description">darken</string>
|
||||
<string name="widget_description">Een widget dat de laatst gekende apparaatstatus toont.</string>
|
||||
<string name="widget_configuration_title">Selecteer Apparaat</string>
|
||||
<string name="widget_configuration_description">Kies welk apparaatprofiel deze widget moet weergeven.</string>
|
||||
<string name="common_feature_requires_pro_msg">Voor deze functie is CAPod Pro vereist.</string>
|
||||
<string name="widget_no_data_label">Geen data</string>
|
||||
<string name="settings_compat_indirectcallback_title">Onrechtstreekse data aflevering</string>
|
||||
<string name="settings_compat_indirectcallback_summary">Gebruik een alternatieve methode om BLE data van het systeem (broadcast inplaats van callback).</string>
|
||||
<string name="troubleshooter_title">Probleemoplossing</string>
|
||||
@@ -134,6 +140,10 @@
|
||||
<string name="overview_monitoring_active_label">Monitoring voor apparaten</string>
|
||||
<string name="overview_monitoring_active_description">Zorg ervoor dat je apparaat in de buurt is en actief is.</string>
|
||||
<string name="overview_unmatched_devices_label">Niet overeenkomende apparaten</string>
|
||||
<plurals name="overview_unmatched_devices_count">
|
||||
<item quantity="one">%d apparaat zonder overeenkomend profiel</item>
|
||||
<item quantity="other">%d apparaten zonder overeenkomend profiel</item>
|
||||
</plurals>
|
||||
<string name="permission_bluetooth_connect_label">Bluetooth-verbinding</string>
|
||||
<string name="permission_bluetooth_connect_description">Deze app heeft de toestemming voor \'Bluetooth verbinden\' nodig om met gekoppelde apparaten te communiceren en verbindingen tot stand te brengen.</string>
|
||||
<string name="permission_bluetooth_scan_label">Bluetooth-scannen</string>
|
||||
@@ -159,6 +169,17 @@
|
||||
<string name="settings_reaction_autoconnect_caseopen_label">Zaak is geopend</string>
|
||||
<string name="settings_reaction_autoconnect_inear_label">In oor</string>
|
||||
<string name="pods_dual_left_label">Linker pod</string>
|
||||
<string name="pods_dual_right_label">Rechter pod</string>
|
||||
<string name="pods_case_label">Geval</string>
|
||||
<string name="pods_case_status_open_label">Open</string>
|
||||
<string name="pods_case_status_closed_label">Gesloten</string>
|
||||
<string name="pods_connection_state_disconnected_label">Niet verbonden met een apparaat</string>
|
||||
<string name="pods_connection_state_idle_label">Aangesloten op een apparaat, maar inactief</string>
|
||||
<string name="pods_connection_state_music_label">In muziekmodus</string>
|
||||
<string name="pods_connection_state_call_label">In oproepmodus</string>
|
||||
<string name="pods_connection_state_ringing_label">Rinkelen</string>
|
||||
<string name="pods_connection_state_hanging_up_label">Ophangen</string>
|
||||
<string name="pods_connection_state_unknown_label">Onbekende verbindingsstatus</string>
|
||||
<!-- Device profiles -->
|
||||
<string name="profiles_maindevice_encryptionkey_explanation">AirPods sturen een statusbericht, waarvan een deel versleuteld is. De encryptiesleutel stelt CAPod in staat het volledige bericht te ontsleutelen. Je hebt hiervoor eenmalige toegang tot een MacBook nodig.</string>
|
||||
<string name="profiles_key_invalid_format">Ongeldige sleutelindeling</string>
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<string name="general_save_action">儲存</string>
|
||||
<string name="general_guide_action">指南</string>
|
||||
<string name="general_continue_action">繼續</string>
|
||||
<string name="general_show_action">顯示</string>
|
||||
<string name="general_hide_action">隱藏</string>
|
||||
<string name="general_example_label">例如:%s</string>
|
||||
<string name="upgrade_capod_label">升級 CAPod</string>
|
||||
<string name="upgrade_capod_description">取得附加功能並支持開發人員。</string>
|
||||
@@ -18,12 +20,16 @@
|
||||
<string name="settings_monitor_mode_description">在這種情況下應用程式會監視藍牙資料。</string>
|
||||
<string name="settings_monitor_connected_notification_label">額外通知</string>
|
||||
<string name="settings_monitor_connected_notification_description">裝置連接時顯示額外通知。這讓您可以停用「裝置狀態」頻道來隱藏永久的「沒有裝置」通知。</string>
|
||||
<string name="settings_keep_notification_after_disconnect_label">斷線後保留通知</string>
|
||||
<string name="settings_keep_notification_after_disconnect_description">即使 AirPods 斷線後仍顯示上次的電量</string>
|
||||
<string name="settings_scanner_mode_label">掃描模式</string>
|
||||
<string name="settings_scanner_mode_description">低功耗藍牙掃描器應該優先考慮效能還是節能?</string>
|
||||
<string name="settings_autopause_label">自動暫停</string>
|
||||
<string name="settings_autopause_description">從耳中摘下時自動暫停。</string>
|
||||
<string name="settings_autopplay_label">自動播放</string>
|
||||
<string name="settings_autoplay_description">佩戴到耳上時自動播放。</string>
|
||||
<string name="settings_eardetection_info_label">耳朵偵測提示</string>
|
||||
<string name="settings_eardetection_info_description">若耳朵偵測僅對其中一隻耳機有效,這是 Apple 的限制。只有「主要耳機」(用作麥克風的那一隻)會被偵測。可在 Apple 裝置中設定:設定 → 藍牙 → AirPods → 麥克風。</string>
|
||||
<string name="settings_fake_data_label">假資料</string>
|
||||
<string name="settings_fake_data_description">顯示假資料,模擬不存在的裝置。</string>
|
||||
<string name="settings_debug_label">偵錯設定</string>
|
||||
@@ -34,6 +40,8 @@
|
||||
<string name="settings_autoconnect_description">如果 Android 不會自動連線,我們也可以要求它。這將把監視模式設定為「一律」。</string>
|
||||
<string name="settings_autoconnect_condition_label">自動連線條件</string>
|
||||
<string name="settings_autoconnect_condition_description">何時連線到您的裝置?</string>
|
||||
<string name="settings_devices_label">裝置</string>
|
||||
<string name="settings_devices_description">管理你的裝置。</string>
|
||||
<string name="settings_reaction_label">反應</string>
|
||||
<string name="settings_reaction_description">對事件和行為作出反應。</string>
|
||||
<string name="settings_category_yourdevice_label">您的裝置</string>
|
||||
@@ -68,6 +76,7 @@
|
||||
<string name="settings_support_description">如果您需要協助。</string>
|
||||
<string name="issue_tracker_label">問題追蹤器</string>
|
||||
<string name="issue_tracker_description">一個用於錯誤回報和功能需求的公用問題追蹤器 (僅英文)。</string>
|
||||
<string name="discord_label">Discord</string>
|
||||
<string name="discord_description">一個可以在其中閒逛並提出問題的地方。</string>
|
||||
<string name="changelog_label">變更記錄</string>
|
||||
<string name="settings_label">設定</string>
|
||||
@@ -91,9 +100,14 @@
|
||||
<string name="translators_thanks_title">翻譯人員</string>
|
||||
<string name="translators_thanks_description">人工知能</string>
|
||||
<string name="widget_description">顯示最後已知裝置狀態的小工具。</string>
|
||||
<string name="widget_configuration_title">選擇裝置</string>
|
||||
<string name="widget_configuration_description">選擇此小工具要顯示的裝置設定檔。</string>
|
||||
<string name="common_feature_requires_pro_msg">此功能需 CAPod Pro。</string>
|
||||
<string name="widget_no_data_label">無資料</string>
|
||||
<string name="settings_compat_indirectcallback_title">間接資料傳遞</string>
|
||||
<string name="settings_compat_indirectcallback_summary">使用替代方法從系統中接收低功耗藍牙資料 (廣播而非回撥)。</string>
|
||||
<string name="troubleshooter_title">疑難排解員</string>
|
||||
<string name="troubleshooter_summary">診斷並修復藍牙連線問題。</string>
|
||||
<string name="troubleshooter_ble_intro_title">低功耗藍牙廣播</string>
|
||||
<string name="troubleshooter_ble_intro_body1">AirPods (和類似的耳機) 使用一種叫做「廣告」的低功耗藍牙技術廣播狀態資訊。部分手機不能正確實作這項技術。CAPod 可以嘗試透過不同的相容性選項來修正這個問題,直到收到資料。在耳機上開始播放音樂,並把它們放在靠近手機的地方,然後啟動這個處理程序。</string>
|
||||
<string name="troubleshooter_ble_intro_start_action">啟動疑難排解</string>
|
||||
@@ -112,6 +126,107 @@
|
||||
<string name="onboarding_body3">CAPod 沒有廣告,也不會收集您的資料。</string>
|
||||
<string name="onboarding_body4">您可以升級到 CAPod Pro 以獲得額外功能並支援開發。</string>
|
||||
<!-- Strings from app-common -->
|
||||
<string name="app_name">CAPod</string>
|
||||
<string name="app_name_pro">CAPod Pro</string>
|
||||
<string name="app_name_foss">CAPod FOSS</string>
|
||||
<string name="general_value_not_available_label">不適用</string>
|
||||
<string name="general_error_label">錯誤</string>
|
||||
<string name="general_grant_permission_action">授予權限</string>
|
||||
<string name="general_manage_devices_action">設備管理</string>
|
||||
<string name="overview_nomaindevice_label">尚未設定裝置</string>
|
||||
<string name="overview_nomaindevice_description">設定你的裝置以開始監測電量並啟用其他功能。</string>
|
||||
<string name="overview_bluetooth_disabled_label">藍牙已停用</string>
|
||||
<string name="overview_bluetooth_disabled_description">藍牙已停用,請啟用它 ;)</string>
|
||||
<string name="overview_monitoring_active_label">正在監測裝置</string>
|
||||
<string name="overview_monitoring_active_description">請確保你的裝置在附近且處於啟用狀態。</string>
|
||||
<string name="overview_unmatched_devices_label">未配對的裝置</string>
|
||||
<plurals name="overview_unmatched_devices_count">
|
||||
<item quantity="other">%d 個裝置沒有相符的設定檔</item>
|
||||
</plurals>
|
||||
<string name="permission_bluetooth_connect_label">藍牙連線</string>
|
||||
<string name="permission_bluetooth_connect_description">此應用程式需要「藍牙連線」權限,才能與已配對的裝置互動並建立連線。</string>
|
||||
<string name="permission_bluetooth_scan_label">藍牙掃描中</string>
|
||||
<string name="permission_bluetooth_scan_description">「藍牙掃描」權限可讓此應用程式探索並接收來自附近裝置的藍牙資料,例如你的 AirPods。</string>
|
||||
<string name="permission_bluetooth_label">藍牙</string>
|
||||
<string name="permission_bluetooth_description">這個應用程式需要「藍牙」權限與已配對裝置連線。</string>
|
||||
<string name="permission_access_fine_location_label">存取精確位置</string>
|
||||
<string name="permission_access_fine_location_description">CAPod 使用「精確位置」權限以接收低功耗藍牙資料。您的耳機使用低功耗藍牙技術以廣播其狀態。這個應用程式不會使用藍牙資料來確定您的位置。</string>
|
||||
<string name="permission_background_location_label">背景位置存取</string>
|
||||
<string name="permission_background_location_description">CAPods 在應用程式關閉時使用「背景位置存取」來啟用諸如「顯示彈出式視窗」和「自動連線」等功能。背景位置存取允許這個應用程式在背景接收低功耗藍牙資料。這個應用程式不會使用藍牙資料來確定您的位置。</string>
|
||||
<string name="permission_ignore_battery_optimizations_label">停用電池效能最佳化</string>
|
||||
<string name="permission_ignore_battery_optimizations_description">電池效能最佳化使這個應用程式在背景時無法可靠地接收藍牙資料。</string>
|
||||
<string name="permission_required_title">可能要求下列權限:</string>
|
||||
<string name="permission_system_alert_window_label">系統警報視窗</string>
|
||||
<string name="permission_system_alert_window_description">允許 CAPod 在其他應用程式上繪圖,使「顯示彈出式視窗」功能成為可能。</string>
|
||||
<string name="settings_scanner_mode_lowpower_label">低功耗</string>
|
||||
<string name="settings_scanner_mode_balanced_label">平衡</string>
|
||||
<string name="settings_scanner_mode_lowlatency_label">低延遲</string>
|
||||
<string name="settings_monitor_mode_manual_label">應用程式開啟時</string>
|
||||
<string name="settings_monitor_mode_automatic_label">裝置連線時</string>
|
||||
<string name="settings_monitor_mode_always_label">一律</string>
|
||||
<string name="settings_reaction_autoconnect_whenseen_label">看到時</string>
|
||||
<string name="settings_reaction_autoconnect_caseopen_label">充電盒開啟</string>
|
||||
<string name="settings_reaction_autoconnect_inear_label">在耳中</string>
|
||||
<string name="pods_dual_left_label">左耳</string>
|
||||
<string name="pods_dual_right_label">右耳</string>
|
||||
<string name="pods_case_label">充電盒</string>
|
||||
<string name="pods_case_status_open_label">已開啟</string>
|
||||
<string name="pods_case_status_closed_label">已關閉</string>
|
||||
<string name="pods_connection_state_disconnected_label">未連線到裝置</string>
|
||||
<string name="pods_connection_state_idle_label">已連線到裝置,閒置中</string>
|
||||
<string name="pods_connection_state_music_label">音樂模式</string>
|
||||
<string name="pods_connection_state_call_label">呼叫模式</string>
|
||||
<string name="pods_connection_state_ringing_label">響鈴中</string>
|
||||
<string name="pods_connection_state_hanging_up_label">正在掛斷</string>
|
||||
<string name="pods_connection_state_unknown_label">未知連線狀態</string>
|
||||
<string name="pods_unknown_raw_data_label">原始資料</string>
|
||||
<string name="pods_unknown_label">未知裝置</string>
|
||||
<string name="pods_unknown_contact_dev">這是一個未知裝置,但可以使用相似的訊息格式。聯絡我以為此裝置新增相關支援 :)</string>
|
||||
<string name="pods_none_label_short">無裝置</string>
|
||||
<string name="pods_charging_label">充電中</string>
|
||||
<string name="pods_inear_label">在耳中</string>
|
||||
<string name="pods_microphone_label">麥克風</string>
|
||||
<string name="pods_yours">您的</string>
|
||||
<string name="headset_being_worn_label">正被配戴</string>
|
||||
<string name="headset_not_being_worn_label">未配戴</string>
|
||||
<string name="pods_case_unknown_state">未知狀態</string>
|
||||
<string name="last_seen_x">最後連線:%s</string>
|
||||
<string name="first_seen_x">首次連線:%s</string>
|
||||
<string name="permission_post_notifications_label">顯示通知</string>
|
||||
<string name="permission_post_notifications_description">"允許 CAPod 顯示關於您 AirPods 的通知,例如在連線時顯示它們的目前狀態。"</string>
|
||||
<!-- Device profiles -->
|
||||
<string name="profiles_empty_title">尚未設定任何裝置設定檔</string>
|
||||
<string name="profiles_empty_description">建立裝置設定檔,以自訂設定與優先順序來管理多個裝置。</string>
|
||||
<string name="profiles_add_action">新增設定檔</string>
|
||||
<string name="profiles_create_title">建立設定檔</string>
|
||||
<string name="profiles_name_label">設定檔名稱</string>
|
||||
<string name="profiles_name_default">我的耳機</string>
|
||||
<string name="profiles_model_label">設備型號</string>
|
||||
<string name="profiles_paired_device_label">已配對裝置</string>
|
||||
<string name="profiles_paired_device_none">無</string>
|
||||
<string name="profiles_paired_device_none_description">尚未選擇裝置</string>
|
||||
<string name="profiles_save_action">儲存設定檔</string>
|
||||
<string name="profiles_drag_handle_description">拖曳重新排序</string>
|
||||
<string name="profiles_delete_title">刪除設定檔</string>
|
||||
<string name="profiles_delete_message">是否確定要刪除此設定檔?此操作無法撤銷。</string>
|
||||
<string name="profiles_delete_action">刪除</string>
|
||||
<string name="profiles_basic_info_title">設備資訊</string>
|
||||
<string name="profiles_basic_info_description">設定你的裝置名稱、型號,以及可選的藍牙配對。</string>
|
||||
<string name="profiles_signal_quality_title">最低訊號品質</string>
|
||||
<string name="profiles_signal_quality_description">僅偵測訊號強度高於此閾值的裝置。數值越低可增加偵測範圍,但可能導致誤判。請勿將此值設得太高——藍牙接收通常較弱,且會受距離與障礙物影響。</string>
|
||||
<string name="profiles_identitykey_label">身份金鑰</string>
|
||||
<string name="profilessettings_maindevice_identitykey_description">您裝置的身份解析金鑰 (IRK),協助 CAPod 在附近的裝置中識別它。</string>
|
||||
<string name="profiles_maindevice_identitykey_explanation">為保護隱私,AirPods 會經常更改其藍牙位址。IRK 可協助 CAPod 識別您的裝置。您需要一次性存取 MacBook。</string>
|
||||
<string name="profiles_maindevice_encryptionkey_label">加密金鑰</string>
|
||||
<string name="profiles_maindevice_encryptionkey_description">您裝置的加密金鑰,允許 CAPod 檢索詳細的狀態資訊。</string>
|
||||
<string name="profiles_maindevice_encryptionkey_explanation">AirPods 會傳送狀態訊息,其中一部分已加密。加密金鑰允許 CAPod 解密完整的訊息。您需要一次性存取 MacBook。</string>
|
||||
<string name="profiles_key_invalid_format">無效的金鑰格式</string>
|
||||
<string name="profiles_key_expected_format">預期格式:%1$s</string>
|
||||
<string name="profiles_priority_hint">設定檔的順序決定優先權。拖曳設定檔以重新排序——當多個裝置符合時,列表中較上方的設定檔將具有較高優先權。</string>
|
||||
<!-- Unsaved changes dialog -->
|
||||
<string name="general_unsaved_changes_title">修改未儲存</string>
|
||||
<string name="general_unsaved_changes_message">您有未儲存的變更。您想如何處理?</string>
|
||||
<string name="general_save_and_exit_action">儲存並退出</string>
|
||||
<string name="general_discard_action">捨棄</string>
|
||||
<string name="general_keep_editing_action">繼續編輯</string>
|
||||
</resources>
|
||||
|
||||
@@ -15,4 +15,4 @@ CAPod no tiene publicidad. Algunas características requieren ser compradas dent
|
||||
Los AirPods y Beats más populares son soportados.
|
||||
Si su dispositivo es similar a AirPods pero aún no es compatible, envíeme un correo.
|
||||
|
||||
¿Tienes una buena idea para una nueva característica? ¡Háznoslo saber!
|
||||
¿Tienes una buena idea para una nueva característica? ¡Contáctanos!
|
||||
@@ -2,17 +2,17 @@ CAPod 是一個能提供 AirPods 相關功能的應用程式。
|
||||
|
||||
功能:
|
||||
|
||||
。
|
||||
。
|
||||
。
|
||||
* 顯示耳機和充電盒電力。
|
||||
* 顯示耳機和充電盒充電狀態。
|
||||
* 顯示有關連線、麥克風、充電盒的附加資訊。
|
||||
* 可以接收並顯示附近的所有裝置。
|
||||
* 耳朵偵測,自動播放/暫停。
|
||||
* 自動連線手機和 AirPods。
|
||||
。
|
||||
* 開啟充電盒時顯示彈出式視窗。
|
||||
|
||||
CAPod 是無廣告的應用程式。 一些功能需要應用程式內購。 。
|
||||
CAPod 是無廣告的應用程式。 一些功能需要應用程式內購。 。 一些功能需要應用程式內購。
|
||||
|
||||
支援大部分流行的 AirPods 和 Beats 裝置。
|
||||
如果您的裝置和 AirPods 相似但並不支援,請寄給我一封郵件。
|
||||
|
||||
有新功能的好點子? 與我溝通一下吧! !
|
||||
有新功能的好點子? 與我溝通一下吧!
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
### Updated by release.sh ###
|
||||
project.versioning.major=3
|
||||
project.versioning.minor=0
|
||||
project.versioning.patch=1
|
||||
project.versioning.patch=3
|
||||
project.versioning.build=0
|
||||
project.versioning.type=rc
|
||||
#############################
|
||||
|
||||
Reference in New Issue
Block a user