mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e258e65c1 | ||
|
|
9f49b470fe | ||
|
|
4a71cfe65a | ||
|
|
d06959f964 | ||
|
|
8c339ca2eb | ||
|
|
3aab53566d | ||
|
|
749cfed137 | ||
|
|
ce25ad6711 | ||
|
|
568aeec0d5 | ||
|
|
6b02fd66e6 | ||
|
|
0e313004ac | ||
|
|
270de8702b | ||
|
|
324878d68d | ||
|
|
9b39240016 | ||
|
|
4d6f185b58 | ||
|
|
5979081928 | ||
|
|
0d852675cd | ||
|
|
29f9d9e4be | ||
|
|
59c0e818e1 | ||
|
|
6d6647e511 | ||
|
|
612acd6d72 | ||
|
|
425a9f321b |
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
.idea
|
.idea
|
||||||
.gradle
|
.gradle
|
||||||
build/
|
build/
|
||||||
|
/fastlane/report.xml
|
||||||
|
|||||||
+218
@@ -0,0 +1,218 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
CFPropertyList (3.0.5)
|
||||||
|
rexml
|
||||||
|
addressable (2.8.0)
|
||||||
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
|
artifactory (3.0.15)
|
||||||
|
atomos (0.1.3)
|
||||||
|
aws-eventstream (1.2.0)
|
||||||
|
aws-partitions (1.554.0)
|
||||||
|
aws-sdk-core (3.126.0)
|
||||||
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
|
aws-partitions (~> 1, >= 1.525.0)
|
||||||
|
aws-sigv4 (~> 1.1)
|
||||||
|
jmespath (~> 1.0)
|
||||||
|
aws-sdk-kms (1.54.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.126.0)
|
||||||
|
aws-sigv4 (~> 1.1)
|
||||||
|
aws-sdk-s3 (1.112.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.126.0)
|
||||||
|
aws-sdk-kms (~> 1)
|
||||||
|
aws-sigv4 (~> 1.4)
|
||||||
|
aws-sigv4 (1.4.0)
|
||||||
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
|
babosa (1.0.4)
|
||||||
|
claide (1.1.0)
|
||||||
|
colored (1.2)
|
||||||
|
colored2 (3.1.2)
|
||||||
|
commander (4.6.0)
|
||||||
|
highline (~> 2.0.0)
|
||||||
|
declarative (0.0.20)
|
||||||
|
digest-crc (0.6.4)
|
||||||
|
rake (>= 12.0.0, < 14.0.0)
|
||||||
|
domain_name (0.5.20190701)
|
||||||
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
|
dotenv (2.7.6)
|
||||||
|
emoji_regex (3.2.3)
|
||||||
|
excon (0.91.0)
|
||||||
|
faraday (1.9.3)
|
||||||
|
faraday-em_http (~> 1.0)
|
||||||
|
faraday-em_synchrony (~> 1.0)
|
||||||
|
faraday-excon (~> 1.1)
|
||||||
|
faraday-httpclient (~> 1.0)
|
||||||
|
faraday-multipart (~> 1.0)
|
||||||
|
faraday-net_http (~> 1.0)
|
||||||
|
faraday-net_http_persistent (~> 1.0)
|
||||||
|
faraday-patron (~> 1.0)
|
||||||
|
faraday-rack (~> 1.0)
|
||||||
|
faraday-retry (~> 1.0)
|
||||||
|
ruby2_keywords (>= 0.0.4)
|
||||||
|
faraday-cookie_jar (0.0.7)
|
||||||
|
faraday (>= 0.8.0)
|
||||||
|
http-cookie (~> 1.0.0)
|
||||||
|
faraday-em_http (1.0.0)
|
||||||
|
faraday-em_synchrony (1.0.0)
|
||||||
|
faraday-excon (1.1.0)
|
||||||
|
faraday-httpclient (1.0.1)
|
||||||
|
faraday-multipart (1.0.3)
|
||||||
|
multipart-post (>= 1.2, < 3)
|
||||||
|
faraday-net_http (1.0.1)
|
||||||
|
faraday-net_http_persistent (1.2.0)
|
||||||
|
faraday-patron (1.0.0)
|
||||||
|
faraday-rack (1.0.0)
|
||||||
|
faraday-retry (1.0.3)
|
||||||
|
faraday_middleware (1.2.0)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
fastimage (2.2.6)
|
||||||
|
fastlane (2.204.3)
|
||||||
|
CFPropertyList (>= 2.3, < 4.0.0)
|
||||||
|
addressable (>= 2.8, < 3.0.0)
|
||||||
|
artifactory (~> 3.0)
|
||||||
|
aws-sdk-s3 (~> 1.0)
|
||||||
|
babosa (>= 1.0.3, < 2.0.0)
|
||||||
|
bundler (>= 1.12.0, < 3.0.0)
|
||||||
|
colored
|
||||||
|
commander (~> 4.6)
|
||||||
|
dotenv (>= 2.1.1, < 3.0.0)
|
||||||
|
emoji_regex (>= 0.1, < 4.0)
|
||||||
|
excon (>= 0.71.0, < 1.0.0)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
faraday-cookie_jar (~> 0.0.6)
|
||||||
|
faraday_middleware (~> 1.0)
|
||||||
|
fastimage (>= 2.1.0, < 3.0.0)
|
||||||
|
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||||
|
google-apis-androidpublisher_v3 (~> 0.3)
|
||||||
|
google-apis-playcustomapp_v1 (~> 0.1)
|
||||||
|
google-cloud-storage (~> 1.31)
|
||||||
|
highline (~> 2.0)
|
||||||
|
json (< 3.0.0)
|
||||||
|
jwt (>= 2.1.0, < 3)
|
||||||
|
mini_magick (>= 4.9.4, < 5.0.0)
|
||||||
|
multipart-post (~> 2.0.0)
|
||||||
|
naturally (~> 2.2)
|
||||||
|
optparse (~> 0.1.1)
|
||||||
|
plist (>= 3.1.0, < 4.0.0)
|
||||||
|
rubyzip (>= 2.0.0, < 3.0.0)
|
||||||
|
security (= 0.1.3)
|
||||||
|
simctl (~> 1.6.3)
|
||||||
|
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||||
|
terminal-table (>= 1.4.5, < 2.0.0)
|
||||||
|
tty-screen (>= 0.6.3, < 1.0.0)
|
||||||
|
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||||
|
word_wrap (~> 1.0.0)
|
||||||
|
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||||
|
xcpretty (~> 0.3.0)
|
||||||
|
xcpretty-travis-formatter (>= 0.0.3)
|
||||||
|
gh_inspector (1.1.3)
|
||||||
|
google-apis-androidpublisher_v3 (0.16.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-apis-core (0.4.2)
|
||||||
|
addressable (~> 2.5, >= 2.5.1)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
httpclient (>= 2.8.1, < 3.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
representable (~> 3.0)
|
||||||
|
retriable (>= 2.0, < 4.a)
|
||||||
|
rexml
|
||||||
|
webrick
|
||||||
|
google-apis-iamcredentials_v1 (0.10.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-apis-playcustomapp_v1 (0.7.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-apis-storage_v1 (0.11.0)
|
||||||
|
google-apis-core (>= 0.4, < 2.a)
|
||||||
|
google-cloud-core (1.6.0)
|
||||||
|
google-cloud-env (~> 1.0)
|
||||||
|
google-cloud-errors (~> 1.0)
|
||||||
|
google-cloud-env (1.5.0)
|
||||||
|
faraday (>= 0.17.3, < 2.0)
|
||||||
|
google-cloud-errors (1.2.0)
|
||||||
|
google-cloud-storage (1.36.1)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
digest-crc (~> 0.4)
|
||||||
|
google-apis-iamcredentials_v1 (~> 0.1)
|
||||||
|
google-apis-storage_v1 (~> 0.1)
|
||||||
|
google-cloud-core (~> 1.6)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
googleauth (1.1.0)
|
||||||
|
faraday (>= 0.17.3, < 2.0)
|
||||||
|
jwt (>= 1.4, < 3.0)
|
||||||
|
memoist (~> 0.16)
|
||||||
|
multi_json (~> 1.11)
|
||||||
|
os (>= 0.9, < 2.0)
|
||||||
|
signet (>= 0.16, < 2.a)
|
||||||
|
highline (2.0.3)
|
||||||
|
http-cookie (1.0.4)
|
||||||
|
domain_name (~> 0.5)
|
||||||
|
httpclient (2.8.3)
|
||||||
|
jmespath (1.5.0)
|
||||||
|
json (2.6.1)
|
||||||
|
jwt (2.3.0)
|
||||||
|
memoist (0.16.2)
|
||||||
|
mini_magick (4.11.0)
|
||||||
|
mini_mime (1.1.2)
|
||||||
|
multi_json (1.15.0)
|
||||||
|
multipart-post (2.0.0)
|
||||||
|
nanaimo (0.3.0)
|
||||||
|
naturally (2.2.1)
|
||||||
|
optparse (0.1.1)
|
||||||
|
os (1.1.4)
|
||||||
|
plist (3.6.0)
|
||||||
|
public_suffix (4.0.6)
|
||||||
|
rake (13.0.6)
|
||||||
|
representable (3.1.1)
|
||||||
|
declarative (< 0.1.0)
|
||||||
|
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||||
|
uber (< 0.2.0)
|
||||||
|
retriable (3.1.2)
|
||||||
|
rexml (3.2.5)
|
||||||
|
rouge (2.0.7)
|
||||||
|
ruby2_keywords (0.0.5)
|
||||||
|
rubyzip (2.3.2)
|
||||||
|
security (0.1.3)
|
||||||
|
signet (0.16.0)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
faraday (>= 0.17.3, < 2.0)
|
||||||
|
jwt (>= 1.5, < 3.0)
|
||||||
|
multi_json (~> 1.10)
|
||||||
|
simctl (1.6.8)
|
||||||
|
CFPropertyList
|
||||||
|
naturally
|
||||||
|
terminal-notifier (2.0.0)
|
||||||
|
terminal-table (1.8.0)
|
||||||
|
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||||
|
trailblazer-option (0.1.2)
|
||||||
|
tty-cursor (0.7.1)
|
||||||
|
tty-screen (0.8.1)
|
||||||
|
tty-spinner (0.9.3)
|
||||||
|
tty-cursor (~> 0.7)
|
||||||
|
uber (0.1.0)
|
||||||
|
unf (0.1.4)
|
||||||
|
unf_ext
|
||||||
|
unf_ext (0.0.8)
|
||||||
|
unicode-display_width (1.8.0)
|
||||||
|
webrick (1.7.0)
|
||||||
|
word_wrap (1.0.0)
|
||||||
|
xcodeproj (1.21.0)
|
||||||
|
CFPropertyList (>= 2.3.3, < 4.0)
|
||||||
|
atomos (~> 0.1.3)
|
||||||
|
claide (>= 1.0.2, < 2.0)
|
||||||
|
colored2 (~> 3.1)
|
||||||
|
nanaimo (~> 0.3.0)
|
||||||
|
rexml (~> 3.2.4)
|
||||||
|
xcpretty (0.3.0)
|
||||||
|
rouge (~> 2.0.7)
|
||||||
|
xcpretty-travis-formatter (1.0.1)
|
||||||
|
xcpretty (~> 0.2, >= 0.0.7)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
x86_64-linux
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
fastlane
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.2.8
|
||||||
@@ -12,7 +12,7 @@ A companion app that adds support for AirPod specific features to Android:
|
|||||||
* Additional infos about connection, microphone & case.
|
* Additional infos about connection, microphone & case.
|
||||||
* Can receive and show all nearby devices.
|
* Can receive and show all nearby devices.
|
||||||
* Ear detection with automatic play/pause.
|
* Ear detection with automatic play/pause.
|
||||||
* Automatically connect phone & airpods.
|
* Automatically connect phone & AirPods.
|
||||||
* Show popup when case is opened.
|
* Show popup when case is opened.
|
||||||
|
|
||||||
CAPod is ad-free. Some additional features require an in-app purchase.
|
CAPod is ad-free. Some additional features require an in-app purchase.
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="foss_upgrade_donate_label">İanə ver</string>
|
||||||
|
<string name="foss_upgrade_alreadydonated_label">Artıq ianə vermişəm</string>
|
||||||
|
<string name="foss_upgrade_no_money_label">Bütün pulumu AirPods-lara xərcləyirəm</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="foss_upgrade_donate_label">Adomány</string>
|
||||||
|
<string name="foss_upgrade_alreadydonated_label">Már adományoztam</string>
|
||||||
|
<string name="foss_upgrade_no_money_label">Minden pénzemet AirPodokra költöm</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="foss_upgrade_donate_label">Dona</string>
|
||||||
|
<string name="foss_upgrade_alreadydonated_label">Ho già donato</string>
|
||||||
|
<string name="foss_upgrade_no_money_label">Spendo tutti i miei soldi per gli AirPods</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="foss_upgrade_donate_label">תרומה</string>
|
||||||
|
<string name="foss_upgrade_alreadydonated_label">כבר תרמתי</string>
|
||||||
|
<string name="foss_upgrade_no_money_label">מיטב כספי מושקע ב-AirPods</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="foss_upgrade_donate_label">후원하기</string>
|
||||||
|
<string name="foss_upgrade_alreadydonated_label">이미 후원했어요</string>
|
||||||
|
<string name="foss_upgrade_no_money_label">AirPods에 돈을 다 썼어요</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="foss_upgrade_donate_label">Derma</string>
|
||||||
|
<string name="foss_upgrade_alreadydonated_label">Saya sudah menderma</string>
|
||||||
|
<string name="foss_upgrade_no_money_label">Saya belanjakan semua wang saya untuk AirPods</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="foss_upgrade_donate_label">Doneren</string>
|
||||||
|
<string name="foss_upgrade_alreadydonated_label">Ik heb al gedoneerd</string>
|
||||||
|
<string name="foss_upgrade_no_money_label">Ik besteed al mijn geld aan AirPods</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="foss_upgrade_donate_label">Doner</string>
|
||||||
|
<string name="foss_upgrade_alreadydonated_label">Jeg har allerede donert</string>
|
||||||
|
<string name="foss_upgrade_no_money_label">Jeg bruker alle pengene mine på AirPods</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="foss_upgrade_donate_label">Bağış</string>
|
||||||
|
<string name="foss_upgrade_alreadydonated_label">Ben zaten bağışladım</string>
|
||||||
|
<string name="foss_upgrade_no_money_label">Tüm paramı AirPod\'lara harcıyorum</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="foss_upgrade_donate_label">Quyên tặng</string>
|
||||||
|
<string name="foss_upgrade_alreadydonated_label">Tôi đã quyên góp</string>
|
||||||
|
<string name="foss_upgrade_no_money_label">Tôi tiêu hết tiền cho AirPods</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="upgrades_gplay_unavailable_error">Google Play xidmətləri əlçatmazdır.</string>
|
||||||
|
<string name="upgrades_no_purchases_found_check_account">Heç bir satın alma tapılmadı. Doğru hesabı istifadə edirsiniz?</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="upgrades_gplay_unavailable_error">A Google Play szolgáltatások nem érhetők el.</string>
|
||||||
|
<string name="upgrades_no_purchases_found_check_account">Nem található vásárlás. A megfelelő fiókot használod?</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="upgrades_gplay_unavailable_error">I servizi di Google Play non sono disponibili.</string>
|
||||||
|
<string name="upgrades_no_purchases_found_check_account">Nessun acquisto trovato. Stai usando l\'account giusto?</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="upgrades_gplay_unavailable_error">구글 플레이 서비스는 제공되지 않습니다.</string>
|
||||||
|
<string name="upgrades_no_purchases_found_check_account">구매 내역을 찾지 못했습니다. 결제했던 계정이 맞나요?</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="upgrades_gplay_unavailable_error">Perkhidmatan Google Play tidak tersedia.</string>
|
||||||
|
<string name="upgrades_no_purchases_found_check_account">Tiada pembelian ditemui. Adakah anda menggunakan akaun yang betul?</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="upgrades_gplay_unavailable_error">De Google Play-diensten zijn niet beschikbaar.</string>
|
||||||
|
<string name="upgrades_no_purchases_found_check_account">Geen aankopen gevonden. Gebruikt u de juiste rekening?</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="upgrades_gplay_unavailable_error">Google Play-tjenester er utilgjengelige.</string>
|
||||||
|
<string name="upgrades_no_purchases_found_check_account">Ingen kjøp funnet. Bruker du riktig konto?</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="upgrades_gplay_unavailable_error">Google Play hizmetleri kullanılamıyor.</string>
|
||||||
|
<string name="upgrades_no_purchases_found_check_account">Satın alma bulunamadı. Doğru hesabı mı kullanıyorsunuz?</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="upgrades_gplay_unavailable_error">Các dịch vụ của Google Play không khả dụng.</string>
|
||||||
|
<string name="upgrades_no_purchases_found_check_account">Không tìm thấy giao dịch mua nào. Bạn có đang sử dụng đúng tài khoản không?</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -31,8 +31,21 @@ class BleScanner @Inject constructor(
|
|||||||
@SuppressLint("MissingPermission") fun scan(
|
@SuppressLint("MissingPermission") fun scan(
|
||||||
filters: Set<ScanFilter>,
|
filters: Set<ScanFilter>,
|
||||||
scannerMode: ScannerMode,
|
scannerMode: ScannerMode,
|
||||||
|
compatMode: Boolean,
|
||||||
): Flow<List<BleScanResult>> = callbackFlow {
|
): Flow<List<BleScanResult>> = callbackFlow {
|
||||||
|
log(TAG, VERBOSE) { "scan(filters=$filters, scannerMode=$scannerMode, compatMode=$compatMode)" }
|
||||||
|
if (compatMode) log(TAG, WARN) { "Using compatibilityMode!" }
|
||||||
|
|
||||||
val adapter = bluetoothManager.adapter
|
val adapter = bluetoothManager.adapter
|
||||||
|
|
||||||
|
val supportsOffloadFiltering = adapter.isOffloadedFilteringSupported.also {
|
||||||
|
log(TAG, if (it) DEBUG else WARN) { "isOffloadedFilteringSupported=$it" }
|
||||||
|
} && !compatMode
|
||||||
|
|
||||||
|
val supportsOffloadBatching = adapter.isOffloadedScanBatchingSupported.also {
|
||||||
|
log(TAG, if (it) DEBUG else WARN) { "isOffloadedScanBatchingSupported=$it" }
|
||||||
|
} && !compatMode
|
||||||
|
|
||||||
val scanner = bluetoothManager.scanner
|
val scanner = bluetoothManager.scanner
|
||||||
|
|
||||||
val callback = object : ScanCallback() {
|
val callback = object : ScanCallback() {
|
||||||
@@ -43,7 +56,13 @@ class BleScanner @Inject constructor(
|
|||||||
lastScanAt = System.currentTimeMillis()
|
lastScanAt = System.currentTimeMillis()
|
||||||
"onScanResult(delay=${delay}ms, callbackType=$callbackType, result=$result)"
|
"onScanResult(delay=${delay}ms, callbackType=$callbackType, result=$result)"
|
||||||
}
|
}
|
||||||
trySend(listOf(BleScanResult.fromScanResult(result)))
|
val toSend = if (supportsOffloadFiltering || filters.isEmpty() || filters.any { it.matches(result) }) {
|
||||||
|
listOf(BleScanResult.fromScanResult(result))
|
||||||
|
} else {
|
||||||
|
log(TAG, VERBOSE) { "Manual filtering: No match for $result" }
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
trySend(toSend)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBatchScanResults(results: MutableList<ScanResult>) {
|
override fun onBatchScanResults(results: MutableList<ScanResult>) {
|
||||||
@@ -52,7 +71,19 @@ class BleScanner @Inject constructor(
|
|||||||
lastScanAt = System.currentTimeMillis()
|
lastScanAt = System.currentTimeMillis()
|
||||||
"onBatchScanResults(delay=${delay}ms, results=$results)"
|
"onBatchScanResults(delay=${delay}ms, results=$results)"
|
||||||
}
|
}
|
||||||
trySend(results.map { BleScanResult.fromScanResult(it) })
|
|
||||||
|
val toSend = results
|
||||||
|
.filter { result ->
|
||||||
|
val passed = when {
|
||||||
|
supportsOffloadFiltering -> true
|
||||||
|
filters.isEmpty() -> true
|
||||||
|
else -> filters.any { it.matches(result) }
|
||||||
|
}
|
||||||
|
if (!passed) log(TAG, VERBOSE) { "Manually filtered $result" }
|
||||||
|
passed
|
||||||
|
}
|
||||||
|
.map { BleScanResult.fromScanResult(it) }
|
||||||
|
trySend(toSend)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onScanFailed(errorCode: Int) {
|
override fun onScanFailed(errorCode: Int) {
|
||||||
@@ -60,6 +91,7 @@ class BleScanner @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val settings = ScanSettings.Builder().apply {
|
val settings = ScanSettings.Builder().apply {
|
||||||
setScanMode(
|
setScanMode(
|
||||||
when (scannerMode) {
|
when (scannerMode) {
|
||||||
@@ -68,20 +100,24 @@ class BleScanner @Inject constructor(
|
|||||||
ScannerMode.LOW_LATENCY -> ScanSettings.SCAN_MODE_LOW_LATENCY
|
ScannerMode.LOW_LATENCY -> ScanSettings.SCAN_MODE_LOW_LATENCY
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (adapter.isOffloadedScanBatchingSupported) {
|
if (supportsOffloadBatching) {
|
||||||
when (scannerMode) {
|
setReportDelay(
|
||||||
ScannerMode.LOW_POWER -> setReportDelay(2000)
|
when (scannerMode) {
|
||||||
ScannerMode.BALANCED -> setReportDelay(1000)
|
ScannerMode.LOW_POWER -> 2000L
|
||||||
ScannerMode.LOW_LATENCY -> setReportDelay(500)
|
ScannerMode.BALANCED -> 1000L
|
||||||
}
|
ScannerMode.LOW_LATENCY -> 500L
|
||||||
} else {
|
}
|
||||||
log(TAG, WARN) { "isOffloadedScanBatchingSupported=false" }
|
)
|
||||||
}
|
}
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
|
log(TAG, VERBOSE) { "Settings created for offloaded filtering: $settings" }
|
||||||
|
|
||||||
val flushJob = launch {
|
val flushJob = launch {
|
||||||
|
log(TAG) { "Flush job launched" }
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
// Can undercut the minimum setReportDelay(), e.g. 5000ms on a Pixel5@12
|
// Can undercut the minimum setReportDelay(), e.g. 5000ms on a Pixel5@12
|
||||||
|
log(TAG, VERBOSE) { "Flushing scan results." }
|
||||||
adapter.bluetoothLeScanner.flushPendingScanResults(callback)
|
adapter.bluetoothLeScanner.flushPendingScanResults(callback)
|
||||||
when (scannerMode) {
|
when (scannerMode) {
|
||||||
ScannerMode.LOW_POWER -> break
|
ScannerMode.LOW_POWER -> break
|
||||||
@@ -91,19 +127,17 @@ class BleScanner @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adapter.isOffloadedFilteringSupported) {
|
scanner.startScan(
|
||||||
scanner.startScan(filters.toList(), settings, callback)
|
if (supportsOffloadFiltering) filters.toList() else listOf(ScanFilter.Builder().build()),
|
||||||
log(TAG, VERBOSE) { "BleScanner started (filters=$filters, settings=$settings)" }
|
settings,
|
||||||
} else {
|
callback
|
||||||
log(TAG, WARN) { "isOffloadedFilteringSupported=false" }
|
)
|
||||||
scanner.startScan(callback)
|
log(TAG) { "BleScanner started (filters=$filters, settings=$settings)" }
|
||||||
log(TAG, VERBOSE) { "BleScanner started" }
|
|
||||||
}
|
|
||||||
|
|
||||||
awaitClose {
|
awaitClose {
|
||||||
flushJob.cancel()
|
flushJob.cancel()
|
||||||
scanner.stopScan(callback)
|
scanner.stopScan(callback)
|
||||||
log(TAG, INFO) { "BleScanner stopped" }
|
log(TAG) { "BleScanner stopped" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map { fakeBleData.maybeAddfakeData(it) }
|
.map { fakeBleData.maybeAddfakeData(it) }
|
||||||
|
|||||||
@@ -75,6 +75,19 @@ class FakeBleData @Inject constructor(
|
|||||||
fakeDevices.add(this)
|
fakeDevices.add(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tws i99999
|
||||||
|
BleScanResult(
|
||||||
|
address = "5E:9E:D1:29:D2:6D",
|
||||||
|
rssi = Random.nextInt(15, 75) * -1,
|
||||||
|
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 400,
|
||||||
|
manufacturerSpecificData = mapOf(76 to "07 13 01 02 20 71 AA 37 32 00 10 00 64 64 FF 00 00 00 00 00 00".hexToByteArray())
|
||||||
|
).run {
|
||||||
|
if (Random.nextBoolean()) {
|
||||||
|
fakeDevices.add(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Unknown Device
|
// Unknown Device
|
||||||
BleScanResult(
|
BleScanResult(
|
||||||
address = "6E:9E:D1:49:D2:6D",
|
address = "6E:9E:D1:49:D2:6D",
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import android.content.Context
|
|||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import androidx.preference.PreferenceDataStore
|
import androidx.preference.PreferenceDataStore
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import eu.darken.androidstarter.common.preferences.Settings
|
|
||||||
import eu.darken.capod.common.preferences.PreferenceStoreMapper
|
import eu.darken.capod.common.preferences.PreferenceStoreMapper
|
||||||
|
import eu.darken.capod.common.preferences.Settings
|
||||||
import eu.darken.capod.common.preferences.createFlowPreference
|
import eu.darken.capod.common.preferences.createFlowPreference
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package eu.darken.androidstarter.common.preferences
|
package eu.darken.capod.common.preferences
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import androidx.preference.PreferenceDataStore
|
import androidx.preference.PreferenceDataStore
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import eu.darken.androidstarter.common.preferences.Settings
|
import eu.darken.capod.common.preferences.Settings
|
||||||
import eu.darken.capod.main.ui.settings.SettingsFragment
|
import eu.darken.capod.main.ui.settings.SettingsFragment
|
||||||
|
|
||||||
abstract class PreferenceFragment2
|
abstract class PreferenceFragment2
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import android.content.SharedPreferences
|
|||||||
import androidx.preference.PreferenceDataStore
|
import androidx.preference.PreferenceDataStore
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import eu.darken.androidstarter.common.preferences.Settings
|
|
||||||
import eu.darken.capod.common.debug.autoreport.DebugSettings
|
import eu.darken.capod.common.debug.autoreport.DebugSettings
|
||||||
import eu.darken.capod.common.preferences.PreferenceStoreMapper
|
import eu.darken.capod.common.preferences.PreferenceStoreMapper
|
||||||
|
import eu.darken.capod.common.preferences.Settings
|
||||||
import eu.darken.capod.common.preferences.createFlowPreference
|
import eu.darken.capod.common.preferences.createFlowPreference
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -34,6 +34,11 @@ class GeneralSettings @Inject constructor(
|
|||||||
moshi
|
moshi
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val compatibilityMode = preferences.createFlowPreference(
|
||||||
|
"core.compatibility.enabled",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
val showAll = preferences.createFlowPreference(
|
val showAll = preferences.createFlowPreference(
|
||||||
"core.showall.enabled",
|
"core.showall.enabled",
|
||||||
false
|
false
|
||||||
@@ -58,6 +63,7 @@ class GeneralSettings @Inject constructor(
|
|||||||
override val preferenceDataStore: PreferenceDataStore = PreferenceStoreMapper(
|
override val preferenceDataStore: PreferenceDataStore = PreferenceStoreMapper(
|
||||||
monitorMode,
|
monitorMode,
|
||||||
scannerMode,
|
scannerMode,
|
||||||
|
compatibilityMode,
|
||||||
showAll,
|
showAll,
|
||||||
minimumSignalQuality,
|
minimumSignalQuality,
|
||||||
mainDeviceAddress,
|
mainDeviceAddress,
|
||||||
|
|||||||
@@ -14,9 +14,8 @@ import eu.darken.capod.common.lists.modular.mods.TypedVHCreatorMod
|
|||||||
import eu.darken.capod.main.ui.overview.cards.BluetoothDisabledVH
|
import eu.darken.capod.main.ui.overview.cards.BluetoothDisabledVH
|
||||||
import eu.darken.capod.main.ui.overview.cards.MissingMainDeviceVH
|
import eu.darken.capod.main.ui.overview.cards.MissingMainDeviceVH
|
||||||
import eu.darken.capod.main.ui.overview.cards.PermissionCardVH
|
import eu.darken.capod.main.ui.overview.cards.PermissionCardVH
|
||||||
import eu.darken.capod.main.ui.overview.cards.pods.BasicSingleApplePodsCardVH
|
import eu.darken.capod.main.ui.overview.cards.pods.DualPodsCardVH
|
||||||
import eu.darken.capod.main.ui.overview.cards.pods.DualApplePodsCardVH
|
import eu.darken.capod.main.ui.overview.cards.pods.SinglePodsCardVH
|
||||||
import eu.darken.capod.main.ui.overview.cards.pods.SingleApplePodsCardVH
|
|
||||||
import eu.darken.capod.main.ui.overview.cards.pods.UnknownPodDeviceCardVH
|
import eu.darken.capod.main.ui.overview.cards.pods.UnknownPodDeviceCardVH
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -29,9 +28,8 @@ class OverviewAdapter @Inject constructor() :
|
|||||||
init {
|
init {
|
||||||
modules.add(DataBinderMod(data))
|
modules.add(DataBinderMod(data))
|
||||||
modules.add(TypedVHCreatorMod({ data[it] is PermissionCardVH.Item }) { PermissionCardVH(it) })
|
modules.add(TypedVHCreatorMod({ data[it] is PermissionCardVH.Item }) { PermissionCardVH(it) })
|
||||||
modules.add(TypedVHCreatorMod({ data[it] is DualApplePodsCardVH.Item }) { DualApplePodsCardVH(it) })
|
modules.add(TypedVHCreatorMod({ data[it] is DualPodsCardVH.Item }) { DualPodsCardVH(it) })
|
||||||
modules.add(TypedVHCreatorMod({ data[it] is SingleApplePodsCardVH.Item }) { SingleApplePodsCardVH(it) })
|
modules.add(TypedVHCreatorMod({ data[it] is SinglePodsCardVH.Item }) { SinglePodsCardVH(it) })
|
||||||
modules.add(TypedVHCreatorMod({ data[it] is BasicSingleApplePodsCardVH.Item }) { BasicSingleApplePodsCardVH(it) })
|
|
||||||
modules.add(TypedVHCreatorMod({ data[it] is MissingMainDeviceVH.Item }) { MissingMainDeviceVH(it) })
|
modules.add(TypedVHCreatorMod({ data[it] is MissingMainDeviceVH.Item }) { MissingMainDeviceVH(it) })
|
||||||
modules.add(TypedVHCreatorMod({ data[it] is BluetoothDisabledVH.Item }) { BluetoothDisabledVH(it) })
|
modules.add(TypedVHCreatorMod({ data[it] is BluetoothDisabledVH.Item }) { BluetoothDisabledVH(it) })
|
||||||
modules.add(TypedVHCreatorMod({ data[it] is UnknownPodDeviceCardVH.Item }) { UnknownPodDeviceCardVH(it) })
|
modules.add(TypedVHCreatorMod({ data[it] is UnknownPodDeviceCardVH.Item }) { UnknownPodDeviceCardVH(it) })
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import androidx.activity.result.ActivityResultLauncher
|
|||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import eu.darken.capod.BuildConfig
|
||||||
import eu.darken.capod.R
|
import eu.darken.capod.R
|
||||||
import eu.darken.capod.common.colorString
|
import eu.darken.capod.common.colorString
|
||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
@@ -71,6 +72,7 @@ class OverviewFragment : Fragment3(R.layout.main_fragment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vm.listItems.observe2(ui) {
|
vm.listItems.observe2(ui) {
|
||||||
|
if (BuildConfig.DEBUG) toolbar.subtitle = "${it.size} items"
|
||||||
adapter.update(it)
|
adapter.update(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,23 +20,23 @@ import eu.darken.capod.main.core.PermissionTool
|
|||||||
import eu.darken.capod.main.ui.overview.cards.BluetoothDisabledVH
|
import eu.darken.capod.main.ui.overview.cards.BluetoothDisabledVH
|
||||||
import eu.darken.capod.main.ui.overview.cards.MissingMainDeviceVH
|
import eu.darken.capod.main.ui.overview.cards.MissingMainDeviceVH
|
||||||
import eu.darken.capod.main.ui.overview.cards.PermissionCardVH
|
import eu.darken.capod.main.ui.overview.cards.PermissionCardVH
|
||||||
import eu.darken.capod.main.ui.overview.cards.pods.*
|
import eu.darken.capod.main.ui.overview.cards.pods.DualPodsCardVH
|
||||||
|
import eu.darken.capod.main.ui.overview.cards.pods.SinglePodsCardVH
|
||||||
|
import eu.darken.capod.main.ui.overview.cards.pods.UnknownPodDeviceCardVH
|
||||||
import eu.darken.capod.monitor.core.PodMonitor
|
import eu.darken.capod.monitor.core.PodMonitor
|
||||||
import eu.darken.capod.monitor.core.worker.MonitorControl
|
import eu.darken.capod.monitor.core.worker.MonitorControl
|
||||||
|
import eu.darken.capod.pods.core.DualPodDevice
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePods
|
import eu.darken.capod.pods.core.SinglePodDevice
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
|
||||||
import eu.darken.capod.pods.core.apple.SingleApplePods
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class OverviewFragmentVM @Inject constructor(
|
class OverviewFragmentVM @Inject constructor(
|
||||||
handle: SavedStateHandle,
|
@Suppress("UNUSED_PARAMETER") handle: SavedStateHandle,
|
||||||
dispatcherProvider: DispatcherProvider,
|
dispatcherProvider: DispatcherProvider,
|
||||||
private val monitorControl: MonitorControl,
|
private val monitorControl: MonitorControl,
|
||||||
private val podMonitor: PodMonitor,
|
private val podMonitor: PodMonitor,
|
||||||
@@ -74,7 +74,7 @@ class OverviewFragmentVM @Inject constructor(
|
|||||||
monitorControl.startMonitor()
|
monitorControl.startMonitor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map { Unit }
|
.map { }
|
||||||
.asLiveData2()
|
.asLiveData2()
|
||||||
|
|
||||||
val requestPermissionEvent = SingleLiveEvent<Permission>()
|
val requestPermissionEvent = SingleLiveEvent<Permission>()
|
||||||
@@ -129,19 +129,13 @@ class OverviewFragmentVM @Inject constructor(
|
|||||||
pods.map {
|
pods.map {
|
||||||
val now = Instant.now()
|
val now = Instant.now()
|
||||||
when (it) {
|
when (it) {
|
||||||
is DualApplePods -> DualApplePodsCardVH.Item(
|
is DualPodDevice -> DualPodsCardVH.Item(
|
||||||
now = now,
|
now = now,
|
||||||
device = it,
|
device = it,
|
||||||
showDebug = isDebugMode,
|
showDebug = isDebugMode,
|
||||||
isMainPod = it == mainPod,
|
isMainPod = it == mainPod,
|
||||||
)
|
)
|
||||||
is SingleApplePods -> SingleApplePodsCardVH.Item(
|
is SinglePodDevice -> SinglePodsCardVH.Item(
|
||||||
now = now,
|
|
||||||
device = it,
|
|
||||||
showDebug = isDebugMode,
|
|
||||||
isMainPod = it == mainPod,
|
|
||||||
)
|
|
||||||
is BasicSingleApplePods -> BasicSingleApplePodsCardVH.Item(
|
|
||||||
now = now,
|
now = now,
|
||||||
device = it,
|
device = it,
|
||||||
showDebug = isDebugMode,
|
showDebug = isDebugMode,
|
||||||
|
|||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
package eu.darken.capod.main.ui.overview.cards.pods
|
|
||||||
|
|
||||||
import android.graphics.Typeface
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.core.view.isGone
|
|
||||||
import eu.darken.capod.R
|
|
||||||
import eu.darken.capod.common.lists.binding
|
|
||||||
import eu.darken.capod.databinding.OverviewPodsAppleSingleBasicItemBinding
|
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePods
|
|
||||||
import eu.darken.capod.pods.core.getBatteryDrawable
|
|
||||||
import eu.darken.capod.pods.core.getBatteryLevelHeadset
|
|
||||||
import eu.darken.capod.pods.core.lastSeenFormatted
|
|
||||||
import java.time.Instant
|
|
||||||
|
|
||||||
class BasicSingleApplePodsCardVH(parent: ViewGroup) :
|
|
||||||
PodDeviceVH<BasicSingleApplePodsCardVH.Item, OverviewPodsAppleSingleBasicItemBinding>(
|
|
||||||
R.layout.overview_pods_apple_single_basic_item,
|
|
||||||
parent
|
|
||||||
) {
|
|
||||||
|
|
||||||
override val viewBinding = lazy { OverviewPodsAppleSingleBasicItemBinding.bind(itemView) }
|
|
||||||
|
|
||||||
override val onBindData = binding(payload = true) { item: Item ->
|
|
||||||
val device = item.device
|
|
||||||
|
|
||||||
name.apply {
|
|
||||||
text = device.getLabel(context)
|
|
||||||
if (item.isMainPod) setTypeface(typeface, Typeface.BOLD)
|
|
||||||
else setTypeface(typeface, Typeface.NORMAL)
|
|
||||||
}
|
|
||||||
|
|
||||||
deviceIcon.setImageResource(device.iconRes)
|
|
||||||
|
|
||||||
lastSeen.text = device.lastSeenFormatted(item.now)
|
|
||||||
|
|
||||||
reception.text = item.getReceptionText()
|
|
||||||
|
|
||||||
batteryLabel.text = device.getBatteryLevelHeadset(context)
|
|
||||||
batteryIcon.setImageResource(getBatteryDrawable(device.batteryHeadsetPercent))
|
|
||||||
|
|
||||||
status.apply {
|
|
||||||
val sb = StringBuilder()
|
|
||||||
if (item.showDebug) {
|
|
||||||
sb.append("--- Debug ---")
|
|
||||||
sb.append("\n").append(device.rawDataHex)
|
|
||||||
}
|
|
||||||
text = sb
|
|
||||||
isGone = !item.showDebug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Item(
|
|
||||||
override val now: Instant,
|
|
||||||
override val device: BasicSingleApplePods,
|
|
||||||
override val showDebug: Boolean,
|
|
||||||
override val isMainPod: Boolean,
|
|
||||||
) : PodDeviceVH.Item
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
package eu.darken.capod.main.ui.overview.cards.pods
|
|
||||||
|
|
||||||
import android.graphics.Typeface
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.core.view.isGone
|
|
||||||
import androidx.core.view.isInvisible
|
|
||||||
import eu.darken.capod.R
|
|
||||||
import eu.darken.capod.common.lists.binding
|
|
||||||
import eu.darken.capod.databinding.OverviewPodsAppleDualItemBinding
|
|
||||||
import eu.darken.capod.pods.core.*
|
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods.DeviceColor
|
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods.LidState
|
|
||||||
import java.time.Duration
|
|
||||||
import java.time.Instant
|
|
||||||
|
|
||||||
class DualApplePodsCardVH(parent: ViewGroup) :
|
|
||||||
PodDeviceVH<DualApplePodsCardVH.Item, OverviewPodsAppleDualItemBinding>(
|
|
||||||
R.layout.overview_pods_apple_dual_item,
|
|
||||||
parent
|
|
||||||
) {
|
|
||||||
|
|
||||||
override val viewBinding = lazy { OverviewPodsAppleDualItemBinding.bind(itemView) }
|
|
||||||
|
|
||||||
override val onBindData = binding(payload = true) { item: Item ->
|
|
||||||
val device = item.device
|
|
||||||
name.apply {
|
|
||||||
val sb = StringBuilder(device.getLabel(context))
|
|
||||||
if (!listOf(DeviceColor.WHITE, DeviceColor.UNKNOWN).contains(device.deviceColor)) {
|
|
||||||
sb.append(" (${device.deviceColor.name})")
|
|
||||||
}
|
|
||||||
text = sb
|
|
||||||
if (item.isMainPod) setTypeface(typeface, Typeface.BOLD)
|
|
||||||
else setTypeface(typeface, Typeface.NORMAL)
|
|
||||||
if (item.showDebug) {
|
|
||||||
append(" [${device.primaryPod.name}]")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deviceIcon.setImageResource(device.iconRes)
|
|
||||||
|
|
||||||
lastSeen.text = context.getString(R.string.last_seen_x, device.lastSeenFormatted(item.now))
|
|
||||||
firstSeen.text = context.getString(R.string.first_seen_x, device.firstSeenFormatted(item.now))
|
|
||||||
firstSeen.isGone = Duration.between(device.seenFirstAt, device.seenLastAt).toMinutes() < 1
|
|
||||||
|
|
||||||
reception.text = item.getReceptionText()
|
|
||||||
|
|
||||||
// Left Pod
|
|
||||||
device.apply {
|
|
||||||
podLeftBatteryIcon.setImageResource(getBatteryDrawable(batteryLeftPodPercent))
|
|
||||||
podLeftBatteryLabel.text = getBatteryLevelLeftPod(context)
|
|
||||||
|
|
||||||
podLeftChargingIcon.isInvisible = !isLeftPodCharging
|
|
||||||
podLeftChargingLabel.isInvisible = !isLeftPodCharging
|
|
||||||
|
|
||||||
podLeftMicrophoneIcon.isInvisible = !isLeftPodMicrophone
|
|
||||||
podLeftMicrophoneLabel.isInvisible = !isLeftPodMicrophone
|
|
||||||
|
|
||||||
podLeftWearIcon.isInvisible = !isLeftPodInEar
|
|
||||||
podLeftWearLabel.isInvisible = !isLeftPodInEar
|
|
||||||
}
|
|
||||||
|
|
||||||
// Right Pod
|
|
||||||
device.apply {
|
|
||||||
podRightBatteryIcon.setImageResource(getBatteryDrawable(batteryRightPodPercent))
|
|
||||||
podRightBatteryLabel.text = getBatteryLevelRightPod(context)
|
|
||||||
|
|
||||||
podRightChargingIcon.isInvisible = !isRightPodCharging
|
|
||||||
podRightChargingLabel.isInvisible = !isRightPodCharging
|
|
||||||
|
|
||||||
podRightMicrophoneIcon.isInvisible = !isRightPodMicrophone
|
|
||||||
podRightMicrophoneLabel.isInvisible = !isRightPodMicrophone
|
|
||||||
|
|
||||||
podRightWearIcon.isInvisible = !isRightPodInEar
|
|
||||||
podRightWearLabel.isInvisible = !isRightPodInEar
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case
|
|
||||||
device.apply {
|
|
||||||
podCaseBatteryIcon.setImageResource(getBatteryDrawable(batteryCasePercent))
|
|
||||||
podCaseBatteryLabel.text = getBatteryLevelCase(context)
|
|
||||||
|
|
||||||
podCaseChargingIcon.isInvisible = !isCaseCharging
|
|
||||||
podCaseChargingLabel.isInvisible = !isCaseCharging
|
|
||||||
|
|
||||||
podCaseLidLabel.text = when (caseLidState) {
|
|
||||||
LidState.OPEN -> context.getString(R.string.pods_case_status_open_label)
|
|
||||||
LidState.CLOSED -> context.getString(R.string.pods_case_status_closed_label)
|
|
||||||
else -> context.getString(R.string.general_value_unknown_label)
|
|
||||||
}
|
|
||||||
|
|
||||||
val hideInfo = !listOf(LidState.OPEN, LidState.CLOSED).contains(caseLidState)
|
|
||||||
podCaseLidIcon.isInvisible = hideInfo
|
|
||||||
podCaseLidLabel.isInvisible = hideInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
status.apply {
|
|
||||||
val sb = StringBuilder(device.getConnectionStateLabel(context))
|
|
||||||
if (item.showDebug) {
|
|
||||||
sb.append("\n\n").append("---Debug---")
|
|
||||||
sb.append("\n").append(device.rawDataHex)
|
|
||||||
}
|
|
||||||
text = sb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Item(
|
|
||||||
override val now: Instant,
|
|
||||||
override val device: DualApplePods,
|
|
||||||
override val showDebug: Boolean,
|
|
||||||
override val isMainPod: Boolean,
|
|
||||||
) : PodDeviceVH.Item
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
package eu.darken.capod.main.ui.overview.cards.pods
|
||||||
|
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isGone
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
|
import eu.darken.capod.R
|
||||||
|
import eu.darken.capod.common.lists.binding
|
||||||
|
import eu.darken.capod.databinding.OverviewPodsDualItemBinding
|
||||||
|
import eu.darken.capod.pods.core.*
|
||||||
|
import eu.darken.capod.pods.core.apple.DualAirPods
|
||||||
|
import eu.darken.capod.pods.core.apple.DualAirPods.LidState
|
||||||
|
import java.time.Duration
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
class DualPodsCardVH(parent: ViewGroup) :
|
||||||
|
PodDeviceVH<DualPodsCardVH.Item, OverviewPodsDualItemBinding>(
|
||||||
|
R.layout.overview_pods_dual_item,
|
||||||
|
parent
|
||||||
|
) {
|
||||||
|
|
||||||
|
override val viewBinding = lazy { OverviewPodsDualItemBinding.bind(itemView) }
|
||||||
|
|
||||||
|
override val onBindData = binding(payload = true) { item: Item ->
|
||||||
|
val device = item.device
|
||||||
|
name.apply {
|
||||||
|
val sb = StringBuilder(device.getLabel(context))
|
||||||
|
if (device is HasPodStyle && item.showDebug) {
|
||||||
|
val style = device.podStyle
|
||||||
|
sb.append(" (${style.getColor(context)})")
|
||||||
|
}
|
||||||
|
text = sb
|
||||||
|
|
||||||
|
if (item.isMainPod) setTypeface(typeface, Typeface.BOLD)
|
||||||
|
else setTypeface(typeface, Typeface.NORMAL)
|
||||||
|
|
||||||
|
if (device is DualAirPods && item.showDebug) {
|
||||||
|
append(" [${device.primaryPod.name}]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deviceIcon.setImageResource(device.iconRes)
|
||||||
|
|
||||||
|
lastSeen.text = context.getString(R.string.last_seen_x, device.lastSeenFormatted(item.now))
|
||||||
|
firstSeen.text = context.getString(R.string.first_seen_x, device.firstSeenFormatted(item.now))
|
||||||
|
firstSeen.isGone = Duration.between(device.seenFirstAt, device.seenLastAt).toMinutes() < 1
|
||||||
|
|
||||||
|
reception.text = item.getReceptionText()
|
||||||
|
|
||||||
|
// Pods battery state
|
||||||
|
device.apply {
|
||||||
|
podLeftBatteryIcon.setImageResource(getBatteryDrawable(batteryLeftPodPercent))
|
||||||
|
podLeftBatteryLabel.text = getBatteryLevelLeftPod(context)
|
||||||
|
|
||||||
|
podRightBatteryIcon.setImageResource(getBatteryDrawable(batteryRightPodPercent))
|
||||||
|
podRightBatteryLabel.text = getBatteryLevelRightPod(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pods charging state
|
||||||
|
device.apply {
|
||||||
|
if (this is HasChargeDetectionDual) {
|
||||||
|
podLeftChargingIcon.isInvisible = !isLeftPodCharging
|
||||||
|
podLeftChargingLabel.isInvisible = !isLeftPodCharging
|
||||||
|
|
||||||
|
podRightChargingIcon.isInvisible = !isRightPodCharging
|
||||||
|
podRightChargingLabel.isInvisible = !isRightPodCharging
|
||||||
|
} else {
|
||||||
|
podLeftChargingIcon.isGone = true
|
||||||
|
podLeftChargingLabel.isGone = true
|
||||||
|
|
||||||
|
podRightChargingIcon.isGone = true
|
||||||
|
podRightChargingLabel.isGone = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Microphone state
|
||||||
|
device.apply {
|
||||||
|
if (this is HasDualMicrophone) {
|
||||||
|
podLeftMicrophoneIcon.isInvisible = !isLeftPodMicrophone
|
||||||
|
podLeftMicrophoneLabel.isInvisible = !isLeftPodMicrophone
|
||||||
|
|
||||||
|
podRightMicrophoneIcon.isInvisible = !isRightPodMicrophone
|
||||||
|
podRightMicrophoneLabel.isInvisible = !isRightPodMicrophone
|
||||||
|
} else {
|
||||||
|
podLeftMicrophoneIcon.isGone = true
|
||||||
|
podLeftMicrophoneLabel.isGone = true
|
||||||
|
|
||||||
|
podRightMicrophoneIcon.isGone = true
|
||||||
|
podRightMicrophoneLabel.isGone = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pods wear state
|
||||||
|
device.apply {
|
||||||
|
if (this is HasEarDetectionDual) {
|
||||||
|
podLeftWearIcon.isInvisible = !isLeftPodInEar
|
||||||
|
podLeftWearLabel.isInvisible = !isLeftPodInEar
|
||||||
|
|
||||||
|
podRightWearIcon.isInvisible = !isRightPodInEar
|
||||||
|
podRightWearLabel.isInvisible = !isRightPodInEar
|
||||||
|
} else {
|
||||||
|
podLeftWearIcon.isGone = true
|
||||||
|
podLeftWearLabel.isGone = true
|
||||||
|
|
||||||
|
podRightWearIcon.isGone = true
|
||||||
|
podRightWearLabel.isGone = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case charge state
|
||||||
|
device.apply {
|
||||||
|
if (this is HasCase) {
|
||||||
|
podCaseBatteryIcon.isGone = false
|
||||||
|
podCaseBatteryIcon.setImageResource(getBatteryDrawable(batteryCasePercent))
|
||||||
|
podCaseBatteryLabel.text = getBatteryLevelCase(context)
|
||||||
|
|
||||||
|
podCaseChargingIcon.isInvisible = !isCaseCharging
|
||||||
|
podCaseChargingLabel.isInvisible = !isCaseCharging
|
||||||
|
} else {
|
||||||
|
podCaseBatteryIcon.isGone = true
|
||||||
|
podCaseBatteryLabel.isGone = true
|
||||||
|
|
||||||
|
podCaseChargingIcon.isGone = true
|
||||||
|
podCaseChargingLabel.isGone = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case lid state
|
||||||
|
device.apply {
|
||||||
|
if (this is DualAirPods) {
|
||||||
|
podCaseLidLabel.text = when (caseLidState) {
|
||||||
|
LidState.OPEN -> context.getString(R.string.pods_case_status_open_label)
|
||||||
|
LidState.CLOSED -> context.getString(R.string.pods_case_status_closed_label)
|
||||||
|
else -> context.getString(R.string.pods_case_unknown_state)
|
||||||
|
}
|
||||||
|
|
||||||
|
val hideInfo = !listOf(LidState.OPEN, LidState.CLOSED).contains(caseLidState)
|
||||||
|
podCaseLidIcon.isInvisible = hideInfo
|
||||||
|
podCaseLidLabel.isInvisible = hideInfo
|
||||||
|
} else {
|
||||||
|
podCaseLidIcon.isGone = true
|
||||||
|
podCaseLidLabel.isGone = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection state
|
||||||
|
device.apply {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
if (this is HasStateDetection) {
|
||||||
|
sb.append(state.getLabel(context))
|
||||||
|
}
|
||||||
|
if (item.showDebug) {
|
||||||
|
sb.append("\n\n").append("---Debug---")
|
||||||
|
sb.append("\n").append(rawDataHex)
|
||||||
|
}
|
||||||
|
status.text = sb
|
||||||
|
status.isGone = sb.isEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Item(
|
||||||
|
override val now: Instant,
|
||||||
|
override val device: DualPodDevice,
|
||||||
|
override val showDebug: Boolean,
|
||||||
|
override val isMainPod: Boolean,
|
||||||
|
) : PodDeviceVH.Item
|
||||||
|
}
|
||||||
-65
@@ -1,65 +0,0 @@
|
|||||||
package eu.darken.capod.main.ui.overview.cards.pods
|
|
||||||
|
|
||||||
import android.graphics.Typeface
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.core.view.isGone
|
|
||||||
import androidx.core.view.isInvisible
|
|
||||||
import eu.darken.capod.R
|
|
||||||
import eu.darken.capod.common.lists.binding
|
|
||||||
import eu.darken.capod.databinding.OverviewPodsAppleSingleItemBinding
|
|
||||||
import eu.darken.capod.pods.core.apple.SingleApplePods
|
|
||||||
import eu.darken.capod.pods.core.getBatteryDrawable
|
|
||||||
import eu.darken.capod.pods.core.getBatteryLevelHeadset
|
|
||||||
import eu.darken.capod.pods.core.lastSeenFormatted
|
|
||||||
import java.time.Instant
|
|
||||||
|
|
||||||
class SingleApplePodsCardVH(parent: ViewGroup) :
|
|
||||||
PodDeviceVH<SingleApplePodsCardVH.Item, OverviewPodsAppleSingleItemBinding>(
|
|
||||||
R.layout.overview_pods_apple_single_item,
|
|
||||||
parent
|
|
||||||
) {
|
|
||||||
|
|
||||||
override val viewBinding = lazy { OverviewPodsAppleSingleItemBinding.bind(itemView) }
|
|
||||||
|
|
||||||
override val onBindData = binding(payload = true) { item: Item ->
|
|
||||||
val device = item.device
|
|
||||||
|
|
||||||
name.apply {
|
|
||||||
text = device.getLabel(context)
|
|
||||||
if (item.isMainPod) setTypeface(typeface, Typeface.BOLD)
|
|
||||||
else setTypeface(typeface, Typeface.NORMAL)
|
|
||||||
}
|
|
||||||
|
|
||||||
deviceIcon.setImageResource(device.iconRes)
|
|
||||||
|
|
||||||
lastSeen.text = device.lastSeenFormatted(item.now)
|
|
||||||
|
|
||||||
reception.text = item.getReceptionText()
|
|
||||||
|
|
||||||
batteryLabel.text = device.getBatteryLevelHeadset(context)
|
|
||||||
batteryIcon.setImageResource(getBatteryDrawable(device.batteryHeadsetPercent))
|
|
||||||
|
|
||||||
chargingIcon.isInvisible = device.isHeadsetBeingCharged
|
|
||||||
chargingLabel.isInvisible = device.isHeadsetBeingCharged
|
|
||||||
|
|
||||||
wearIcon.isInvisible = device.isHeadphonesBeingWorn
|
|
||||||
wearLabel.isInvisible = device.isHeadphonesBeingWorn
|
|
||||||
|
|
||||||
status.apply {
|
|
||||||
val sb = StringBuilder()
|
|
||||||
if (item.showDebug) {
|
|
||||||
sb.append("--- Debug ---")
|
|
||||||
sb.append("\n").append(device.rawDataHex)
|
|
||||||
}
|
|
||||||
text = sb
|
|
||||||
isGone = !item.showDebug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Item(
|
|
||||||
override val now: Instant,
|
|
||||||
override val device: SingleApplePods,
|
|
||||||
override val showDebug: Boolean,
|
|
||||||
override val isMainPod: Boolean,
|
|
||||||
) : PodDeviceVH.Item
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package eu.darken.capod.main.ui.overview.cards.pods
|
||||||
|
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isGone
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
|
import eu.darken.capod.R
|
||||||
|
import eu.darken.capod.common.lists.binding
|
||||||
|
import eu.darken.capod.databinding.OverviewPodsSingleItemBinding
|
||||||
|
import eu.darken.capod.pods.core.*
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
class SinglePodsCardVH(parent: ViewGroup) :
|
||||||
|
PodDeviceVH<SinglePodsCardVH.Item, OverviewPodsSingleItemBinding>(
|
||||||
|
R.layout.overview_pods_single_item,
|
||||||
|
parent
|
||||||
|
) {
|
||||||
|
|
||||||
|
override val viewBinding = lazy { OverviewPodsSingleItemBinding.bind(itemView) }
|
||||||
|
|
||||||
|
override val onBindData = binding(payload = true) { item: Item ->
|
||||||
|
val device = item.device
|
||||||
|
|
||||||
|
name.apply {
|
||||||
|
text = device.getLabel(context)
|
||||||
|
if (item.isMainPod) setTypeface(typeface, Typeface.BOLD)
|
||||||
|
else setTypeface(typeface, Typeface.NORMAL)
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceIcon.setImageResource(device.iconRes)
|
||||||
|
|
||||||
|
lastSeen.text = device.lastSeenFormatted(item.now)
|
||||||
|
|
||||||
|
reception.text = item.getReceptionText()
|
||||||
|
|
||||||
|
// Battery level
|
||||||
|
device.apply {
|
||||||
|
batteryLabel.text = getBatteryLevelHeadset(context)
|
||||||
|
batteryIcon.setImageResource(getBatteryDrawable(batteryHeadsetPercent))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Charge state
|
||||||
|
device.apply {
|
||||||
|
if (this is HasChargeDetection) {
|
||||||
|
chargingIcon.isInvisible = isHeadsetBeingCharged
|
||||||
|
chargingLabel.isInvisible = isHeadsetBeingCharged
|
||||||
|
} else {
|
||||||
|
chargingIcon.isGone = true
|
||||||
|
chargingLabel.isGone = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has ear detection
|
||||||
|
device.apply {
|
||||||
|
if (this is HasEarDetection) {
|
||||||
|
wearIcon.isInvisible = isBeingWorn
|
||||||
|
wearLabel.isInvisible = isBeingWorn
|
||||||
|
} else {
|
||||||
|
wearIcon.isGone = true
|
||||||
|
wearLabel.isGone = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status.apply {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
if (item.showDebug) {
|
||||||
|
sb.append("--- Debug ---")
|
||||||
|
sb.append("\n").append(device.rawDataHex)
|
||||||
|
}
|
||||||
|
text = sb
|
||||||
|
isGone = !item.showDebug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Item(
|
||||||
|
override val now: Instant,
|
||||||
|
override val device: SinglePodDevice,
|
||||||
|
override val showDebug: Boolean,
|
||||||
|
override val isMainPod: Boolean,
|
||||||
|
) : PodDeviceVH.Item
|
||||||
|
}
|
||||||
@@ -4,11 +4,11 @@ import android.os.Bundle
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import eu.darken.androidstarter.common.preferences.Settings
|
|
||||||
import eu.darken.capod.R
|
import eu.darken.capod.R
|
||||||
import eu.darken.capod.common.BuildConfigWrap
|
import eu.darken.capod.common.BuildConfigWrap
|
||||||
import eu.darken.capod.common.PrivacyPolicy
|
import eu.darken.capod.common.PrivacyPolicy
|
||||||
import eu.darken.capod.common.WebpageTool
|
import eu.darken.capod.common.WebpageTool
|
||||||
|
import eu.darken.capod.common.preferences.Settings
|
||||||
import eu.darken.capod.common.uix.PreferenceFragment2
|
import eu.darken.capod.common.uix.PreferenceFragment2
|
||||||
import eu.darken.capod.main.core.GeneralSettings
|
import eu.darken.capod.main.core.GeneralSettings
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import eu.darken.capod.main.core.GeneralSettings
|
|||||||
import eu.darken.capod.main.core.ScannerMode
|
import eu.darken.capod.main.core.ScannerMode
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.PodFactory
|
import eu.darken.capod.pods.core.PodFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ContinuityProtocol
|
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -62,19 +61,23 @@ class PodMonitor @Inject constructor(
|
|||||||
log(TAG) { "Bluetooth is enabled" }
|
log(TAG) { "Bluetooth is enabled" }
|
||||||
combine(
|
combine(
|
||||||
generalSettings.scannerMode.flow,
|
generalSettings.scannerMode.flow,
|
||||||
|
generalSettings.compatibilityMode.flow,
|
||||||
debugSettings.showUnfiltered.flow
|
debugSettings.showUnfiltered.flow
|
||||||
) { mode, unfiltered -> mode to unfiltered }
|
) { scannerMode, compatMode, unfiltered ->
|
||||||
.flatMapLatest { (mode, unfiltered) ->
|
Triple(scannerMode, compatMode, unfiltered)
|
||||||
val filters = if (unfiltered) {
|
}.flatMapLatest { (mode, compat, unfiltered) ->
|
||||||
setOf(getUnfilteredFilter())
|
log(TAG, VERBOSE) { "Starting BLEScanner mode=$mode, compat=$compat, unfiltered=$unfiltered" }
|
||||||
} else {
|
val filters = if (unfiltered) {
|
||||||
ProximityPairing.getBleScanFilter()
|
setOf(getUnfilteredFilter())
|
||||||
}
|
} else {
|
||||||
bleScanner.scan(
|
ProximityPairing.getBleScanFilter()
|
||||||
filters = filters,
|
|
||||||
scannerMode = mode
|
|
||||||
).map { it.preFilterAndMap(mode) }
|
|
||||||
}
|
}
|
||||||
|
bleScanner.scan(
|
||||||
|
filters = filters,
|
||||||
|
scannerMode = mode,
|
||||||
|
compatMode = compat,
|
||||||
|
).map { it.preFilterAndMap(mode) }
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log(TAG, WARN) { "Bluetooth is currently disabled" }
|
log(TAG, WARN) { "Bluetooth is currently disabled" }
|
||||||
flowOf(null)
|
flowOf(null)
|
||||||
@@ -160,23 +163,7 @@ class PodMonitor @Inject constructor(
|
|||||||
|
|
||||||
|
|
||||||
private fun getUnfilteredFilter(): ScanFilter {
|
private fun getUnfilteredFilter(): ScanFilter {
|
||||||
val manufacturerData = ByteArray(2).apply {
|
return ScanFilter.Builder().build()
|
||||||
this[0] = 0
|
|
||||||
this[1] = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
val manufacturerDataMask = ByteArray(2).apply {
|
|
||||||
this[0] = 0
|
|
||||||
this[1] = 0
|
|
||||||
}
|
|
||||||
val builder = ScanFilter.Builder().apply {
|
|
||||||
setManufacturerData(
|
|
||||||
ContinuityProtocol.APPLE_COMPANY_IDENTIFIER,
|
|
||||||
manufacturerData,
|
|
||||||
manufacturerDataMask
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return builder.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import android.widget.RemoteViews
|
|||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import eu.darken.capod.R
|
import eu.darken.capod.R
|
||||||
import eu.darken.capod.pods.core.*
|
import eu.darken.capod.pods.core.*
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePods
|
import eu.darken.capod.pods.core.apple.DualAirPods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
|
||||||
import eu.darken.capod.pods.core.apple.SingleApplePods
|
import eu.darken.capod.pods.core.apple.SingleApplePods
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -17,13 +16,12 @@ class MonitorNotificationViewFactory @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
fun createContentView(device: PodDevice): RemoteViews = when (device) {
|
fun createContentView(device: PodDevice): RemoteViews = when (device) {
|
||||||
is DualApplePods -> createDualApplePods(device)
|
is DualAirPods -> createDualApplePods(device)
|
||||||
is SingleApplePods -> createSingleApplePods(device)
|
is SingleApplePods -> createSingleApplePods(device)
|
||||||
is BasicSingleApplePods -> createSingleBasicApplePods(device)
|
|
||||||
else -> createUnknownDevice(device)
|
else -> createUnknownDevice(device)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDualApplePods(device: DualApplePods): RemoteViews = RemoteViews(
|
private fun createDualApplePods(device: DualAirPods): RemoteViews = RemoteViews(
|
||||||
context.packageName,
|
context.packageName,
|
||||||
R.layout.monitor_notification_dual_pods_small
|
R.layout.monitor_notification_dual_pods_small
|
||||||
).apply {
|
).apply {
|
||||||
@@ -52,19 +50,12 @@ class MonitorNotificationViewFactory @Inject constructor(
|
|||||||
setTextViewText(R.id.headphones_label, getLabel(context))
|
setTextViewText(R.id.headphones_label, getLabel(context))
|
||||||
setImageViewResource(R.id.headphones_battery_icon, getBatteryDrawable(batteryHeadsetPercent))
|
setImageViewResource(R.id.headphones_battery_icon, getBatteryDrawable(batteryHeadsetPercent))
|
||||||
setTextViewText(R.id.headphones_battery_label, getBatteryLevelHeadset(context))
|
setTextViewText(R.id.headphones_battery_label, getBatteryLevelHeadset(context))
|
||||||
setViewVisibility(R.id.headphones_charging, if (isHeadsetBeingCharged) View.VISIBLE else View.GONE)
|
if (this is HasEarDetection) {
|
||||||
setViewVisibility(R.id.headphones_worn, if (isHeadphonesBeingWorn) View.VISIBLE else View.GONE)
|
setViewVisibility(R.id.headphones_worn, if (isBeingWorn) View.VISIBLE else View.GONE)
|
||||||
}
|
}
|
||||||
}
|
if (this is HasChargeDetectionDual) {
|
||||||
|
setViewVisibility(R.id.headphones_charging, if (isHeadsetBeingCharged) View.VISIBLE else View.GONE)
|
||||||
private fun createSingleBasicApplePods(device: BasicSingleApplePods): RemoteViews = RemoteViews(
|
}
|
||||||
context.packageName,
|
|
||||||
R.layout.monitor_notification_single_pods_basic_small
|
|
||||||
).apply {
|
|
||||||
device.apply {
|
|
||||||
setTextViewText(R.id.headphones_label, getLabel(context))
|
|
||||||
setImageViewResource(R.id.headphones_battery_icon, getBatteryDrawable(batteryHeadsetPercent))
|
|
||||||
setTextViewText(R.id.headphones_battery_label, getBatteryLevelHeadset(context))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package eu.darken.capod.pods.core
|
package eu.darken.capod.pods.core
|
||||||
|
|
||||||
interface HasDualPods {
|
interface DualPodDevice : PodDevice {
|
||||||
|
|
||||||
enum class Pod {
|
enum class Pod {
|
||||||
LEFT,
|
LEFT,
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package eu.darken.capod.pods.core
|
||||||
|
|
||||||
|
interface HasChargeDetection {
|
||||||
|
|
||||||
|
val isHeadsetBeingCharged: Boolean
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package eu.darken.capod.pods.core
|
||||||
|
|
||||||
|
interface HasChargeDetectionDual : HasChargeDetection {
|
||||||
|
|
||||||
|
val isLeftPodCharging: Boolean
|
||||||
|
|
||||||
|
val isRightPodCharging: Boolean
|
||||||
|
|
||||||
|
val isEitherPodCharging: Boolean
|
||||||
|
get() = isLeftPodCharging || isRightPodCharging
|
||||||
|
|
||||||
|
override val isHeadsetBeingCharged: Boolean
|
||||||
|
get() = isEitherPodCharging
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package eu.darken.capod.pods.core
|
||||||
|
|
||||||
|
interface HasDualMicrophone {
|
||||||
|
|
||||||
|
val isLeftPodMicrophone: Boolean
|
||||||
|
|
||||||
|
val isRightPodMicrophone: Boolean
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package eu.darken.capod.pods.core
|
package eu.darken.capod.pods.core
|
||||||
|
|
||||||
interface HasEarDetection : PodDevice {
|
interface HasEarDetection {
|
||||||
|
|
||||||
val isBeingWorn: Boolean
|
val isBeingWorn: Boolean
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package eu.darken.capod.pods.core
|
package eu.darken.capod.pods.core
|
||||||
|
|
||||||
interface HasDualEarDetection : HasEarDetection {
|
interface HasEarDetectionDual : HasEarDetection {
|
||||||
|
|
||||||
val isLeftPodInEar: Boolean
|
val isLeftPodInEar: Boolean
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package eu.darken.capod.pods.core
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.annotation.ColorRes
|
||||||
|
|
||||||
|
interface HasPodStyle {
|
||||||
|
|
||||||
|
val podStyle: PodStyle
|
||||||
|
|
||||||
|
interface PodStyle {
|
||||||
|
fun getLabel(context: Context): String
|
||||||
|
|
||||||
|
@ColorRes
|
||||||
|
fun getColor(context: Context): Int
|
||||||
|
|
||||||
|
val identifier: String
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package eu.darken.capod.pods.core
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
|
||||||
|
interface HasStateDetection {
|
||||||
|
|
||||||
|
val state: State
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
fun getLabel(context: Context): String
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -100,6 +100,9 @@ interface PodDevice {
|
|||||||
@Json(name = "beats.powerbeats.pro") POWERBEATS_PRO(
|
@Json(name = "beats.powerbeats.pro") POWERBEATS_PRO(
|
||||||
"Power Beats Pro"
|
"Power Beats Pro"
|
||||||
),
|
),
|
||||||
|
@Json(name = "fakes.tws.i99999") TWS_I99999(
|
||||||
|
"TWS i99999"
|
||||||
|
),
|
||||||
@Json(name = "unknown") UNKNOWN(
|
@Json(name = "unknown") UNKNOWN(
|
||||||
"Unknown"
|
"Unknown"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import java.time.Duration
|
|||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
fun HasDualPods.getBatteryLevelLeftPod(context: Context): String =
|
fun DualPodDevice.getBatteryLevelLeftPod(context: Context): String =
|
||||||
batteryLeftPodPercent?.let { "${(it * 100).roundToInt()}%" }
|
batteryLeftPodPercent?.let { "${(it * 100).roundToInt()}%" }
|
||||||
?: context.getString(R.string.general_value_not_available_label)
|
?: context.getString(R.string.general_value_not_available_label)
|
||||||
|
|
||||||
fun HasDualPods.getBatteryLevelRightPod(context: Context): String =
|
fun DualPodDevice.getBatteryLevelRightPod(context: Context): String =
|
||||||
batteryRightPodPercent?.let { "${(it * 100).roundToInt()}%" }
|
batteryRightPodPercent?.let { "${(it * 100).roundToInt()}%" }
|
||||||
?: context.getString(R.string.general_value_not_available_label)
|
?: context.getString(R.string.general_value_not_available_label)
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ fun HasCase.getBatteryLevelCase(context: Context): String =
|
|||||||
batteryCasePercent?.let { "${(it * 100).roundToInt()}%" }
|
batteryCasePercent?.let { "${(it * 100).roundToInt()}%" }
|
||||||
?: context.getString(R.string.general_value_not_available_label)
|
?: context.getString(R.string.general_value_not_available_label)
|
||||||
|
|
||||||
fun HasSinglePod.getBatteryLevelHeadset(context: Context): String =
|
fun SinglePodDevice.getBatteryLevelHeadset(context: Context): String =
|
||||||
batteryHeadsetPercent?.let { "${(it * 100).roundToInt()}%" }
|
batteryHeadsetPercent?.let { "${(it * 100).roundToInt()}%" }
|
||||||
?: context.getString(R.string.general_value_not_available_label)
|
?: context.getString(R.string.general_value_not_available_label)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package eu.darken.capod.pods.core
|
package eu.darken.capod.pods.core
|
||||||
|
|
||||||
interface HasSinglePod {
|
interface SinglePodDevice : PodDevice {
|
||||||
|
|
||||||
val batteryHeadsetPercent: Float?
|
val batteryHeadsetPercent: Float?
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package eu.darken.capod.pods.core.apple
|
package eu.darken.capod.pods.core.apple
|
||||||
|
|
||||||
import eu.darken.capod.common.bluetooth.BleScanResult
|
import eu.darken.capod.common.bluetooth.BleScanResult
|
||||||
import eu.darken.capod.common.debug.Bugs
|
|
||||||
import eu.darken.capod.common.debug.logging.Logging.Priority.WARN
|
import eu.darken.capod.common.debug.logging.Logging.Priority.WARN
|
||||||
import eu.darken.capod.common.debug.logging.asLog
|
import eu.darken.capod.common.debug.logging.asLog
|
||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
|
import eu.darken.capod.pods.core.apple.misc.UnknownAppleDevice
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ContinuityProtocol
|
import eu.darken.capod.pods.core.apple.protocol.ContinuityProtocol
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
@@ -54,25 +54,13 @@ class AppleFactory @Inject constructor(
|
|||||||
|
|
||||||
val factory = podFactories.firstOrNull { it.isResponsible(pm) }
|
val factory = podFactories.firstOrNull { it.isResponsible(pm) }
|
||||||
|
|
||||||
val device = (factory ?: unknownAppleFactory).create(
|
return@withLock (factory ?: unknownAppleFactory).create(
|
||||||
scanResult = scanResult,
|
scanResult = scanResult,
|
||||||
proximityMessage = pm,
|
message = pm,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (factory == null && !SILENCED_PMS.contains(device.rawDeviceModel) && scanResult.address != "6E:9E:D1:49:D2:6D") {
|
|
||||||
SILENCED_PMS.add(device.rawDeviceModel)
|
|
||||||
Bugs.report(
|
|
||||||
tag = TAG,
|
|
||||||
message = "Unknown proximity message type",
|
|
||||||
exception = IllegalArgumentException("Unknown ProximityMessage: $pm")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return@withLock device
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val SILENCED_PMS = mutableSetOf<UShort>()
|
|
||||||
private val TAG = logTag("Pod", "Apple", "Factory")
|
private val TAG = logTag("Pod", "Apple", "Factory")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import dagger.hilt.components.SingletonComponent
|
|||||||
import dagger.multibindings.IntoSet
|
import dagger.multibindings.IntoSet
|
||||||
import eu.darken.capod.pods.core.apple.airpods.*
|
import eu.darken.capod.pods.core.apple.airpods.*
|
||||||
import eu.darken.capod.pods.core.apple.beats.*
|
import eu.darken.capod.pods.core.apple.beats.*
|
||||||
|
import eu.darken.capod.pods.core.apple.misc.Twsi99999
|
||||||
|
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
@Module
|
@Module
|
||||||
@@ -25,4 +26,6 @@ abstract class AppleFactoryModule {
|
|||||||
@Binds @IntoSet abstract fun beatsX(factory: BeatsX.Factory): ApplePodsFactory<out ApplePods>
|
@Binds @IntoSet abstract fun beatsX(factory: BeatsX.Factory): ApplePodsFactory<out ApplePods>
|
||||||
@Binds @IntoSet abstract fun powerBeats3(factory: PowerBeats3.Factory): ApplePodsFactory<out ApplePods>
|
@Binds @IntoSet abstract fun powerBeats3(factory: PowerBeats3.Factory): ApplePodsFactory<out ApplePods>
|
||||||
@Binds @IntoSet abstract fun powerBeatsPro(factory: PowerBeatsPro.Factory): ApplePodsFactory<out ApplePods>
|
@Binds @IntoSet abstract fun powerBeatsPro(factory: PowerBeatsPro.Factory): ApplePodsFactory<out ApplePods>
|
||||||
|
|
||||||
|
@Binds @IntoSet abstract fun fakesTwsi999999(factory: Twsi99999.Factory): ApplePodsFactory<out ApplePods>
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,9 @@ import eu.darken.capod.common.debug.logging.Logging.Priority.VERBOSE
|
|||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import eu.darken.capod.common.lowerNibble
|
import eu.darken.capod.common.lowerNibble
|
||||||
import eu.darken.capod.common.upperNibble
|
import eu.darken.capod.common.upperNibble
|
||||||
|
import eu.darken.capod.pods.core.HasCase
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
|
import eu.darken.capod.pods.core.apple.airpods.AirPodsPro
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -21,9 +23,9 @@ abstract class ApplePodsFactory<PodType : ApplePods>(private val tag: String) {
|
|||||||
val deviceColor: UByte,
|
val deviceColor: UByte,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun ProximityPairing.Message.getApplePodsMarkings(): Markings = Markings(
|
private fun ProximityPairing.Message.getApplePodsMarkings(): Markings = Markings(
|
||||||
vendor = ProximityPairing.CONTINUITY_PROTOCOL_MESSAGE_TYPE_PROXIMITY_PAIRING,
|
vendor = ProximityPairing.CONTINUITY_PROTOCOL_MESSAGE_TYPE_PROXIMITY_PAIRING,
|
||||||
length = ProximityPairing.PROXIMITY_PAIRING_MESSAGE_LENGTH.toUByte(),
|
length = ProximityPairing.PAIRING_MESSAGE_LENGTH.toUByte(),
|
||||||
device = (((data[1].toInt() and 255) shl 8) or (data[2].toInt() and 255)).toUShort(),
|
device = (((data[1].toInt() and 255) shl 8) or (data[2].toInt() and 255)).toUShort(),
|
||||||
// Make comparison order independent
|
// Make comparison order independent
|
||||||
podBatteryData = setOf(data[4].upperNibble, data[4].lowerNibble),
|
podBatteryData = setOf(data[4].upperNibble, data[4].lowerNibble),
|
||||||
@@ -70,6 +72,22 @@ abstract class ApplePodsFactory<PodType : ApplePods>(private val tag: String) {
|
|||||||
|
|
||||||
internal val knownDevices = mutableMapOf<PodDevice.Id, KnownDevice>()
|
internal val knownDevices = mutableMapOf<PodDevice.Id, KnownDevice>()
|
||||||
|
|
||||||
|
|
||||||
|
fun KnownDevice.getLatestCaseBattery(): Float? = history
|
||||||
|
.filterIsInstance<HasCase>()
|
||||||
|
.mapNotNull { it.batteryCasePercent }
|
||||||
|
.lastOrNull()
|
||||||
|
|
||||||
|
fun KnownDevice.getLatestCaseLidState(basic: DualAirPods): DualAirPods.LidState? {
|
||||||
|
val definitive = setOf(DualAirPods.LidState.OPEN, DualAirPods.LidState.CLOSED)
|
||||||
|
if (definitive.contains(basic.caseLidState)) return null
|
||||||
|
|
||||||
|
return history
|
||||||
|
.filterIsInstance<AirPodsPro>()
|
||||||
|
.lastOrNull { it.caseLidState != DualAirPods.LidState.NOT_IN_CASE }
|
||||||
|
?.caseLidState
|
||||||
|
}
|
||||||
|
|
||||||
internal open fun searchHistory(current: PodType): KnownDevice? {
|
internal open fun searchHistory(current: PodType): KnownDevice? {
|
||||||
val scanResult = current.scanResult
|
val scanResult = current.scanResult
|
||||||
val message = current.proximityMessage
|
val message = current.proximityMessage
|
||||||
@@ -138,10 +156,10 @@ abstract class ApplePodsFactory<PodType : ApplePods>(private val tag: String) {
|
|||||||
dirty = data[1]
|
dirty = data[1]
|
||||||
)
|
)
|
||||||
|
|
||||||
abstract fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean
|
abstract fun isResponsible(message: ProximityPairing.Message): Boolean
|
||||||
|
|
||||||
abstract fun create(
|
abstract fun create(
|
||||||
scanResult: BleScanResult,
|
scanResult: BleScanResult,
|
||||||
proximityMessage: ProximityPairing.Message,
|
message: ProximityPairing.Message,
|
||||||
): ApplePods
|
): ApplePods
|
||||||
}
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package eu.darken.capod.pods.core.apple
|
|
||||||
|
|
||||||
import eu.darken.capod.common.debug.logging.log
|
|
||||||
import eu.darken.capod.common.lowerNibble
|
|
||||||
import eu.darken.capod.pods.core.HasSinglePod
|
|
||||||
|
|
||||||
interface BasicSingleApplePods : ApplePods, HasSinglePod {
|
|
||||||
|
|
||||||
override val batteryHeadsetPercent: Float?
|
|
||||||
get() = when (val value = rawPodsBattery.lowerNibble.toInt()) {
|
|
||||||
15 -> null
|
|
||||||
else -> if (value > 10) {
|
|
||||||
log { "Left pod: Above 100% battery: $value" }
|
|
||||||
1.0f
|
|
||||||
} else {
|
|
||||||
(value / 10f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
package eu.darken.capod.pods.core.apple
|
|
||||||
|
|
||||||
abstract class BasicSingleApplePodsFactory(private val tag: String) : ApplePodsFactory<BasicSingleApplePods>(tag)
|
|
||||||
+13
-37
@@ -7,12 +7,11 @@ import eu.darken.capod.common.debug.logging.log
|
|||||||
import eu.darken.capod.common.isBitSet
|
import eu.darken.capod.common.isBitSet
|
||||||
import eu.darken.capod.common.lowerNibble
|
import eu.darken.capod.common.lowerNibble
|
||||||
import eu.darken.capod.common.upperNibble
|
import eu.darken.capod.common.upperNibble
|
||||||
import eu.darken.capod.pods.core.HasCase
|
import eu.darken.capod.pods.core.*
|
||||||
import eu.darken.capod.pods.core.HasDualEarDetection
|
import eu.darken.capod.pods.core.DualPodDevice.Pod
|
||||||
import eu.darken.capod.pods.core.HasDualPods
|
|
||||||
import eu.darken.capod.pods.core.HasDualPods.Pod
|
|
||||||
|
|
||||||
interface DualApplePods : ApplePods, HasDualPods, HasDualEarDetection, HasCase {
|
interface DualAirPods : ApplePods, HasChargeDetectionDual, DualPodDevice, HasEarDetectionDual, HasCase,
|
||||||
|
HasStateDetection, HasDualMicrophone, HasAppleColor {
|
||||||
|
|
||||||
val primaryPod: Pod
|
val primaryPod: Pod
|
||||||
get() = when (rawStatus.isBitSet(5)) {
|
get() = when (rawStatus.isBitSet(5)) {
|
||||||
@@ -86,23 +85,23 @@ interface DualApplePods : ApplePods, HasDualPods, HasDualEarDetection, HasCase {
|
|||||||
* The data flip bit is set if the left pod is primary.
|
* The data flip bit is set if the left pod is primary.
|
||||||
* For the pod that is in the case, this is flipped again though.
|
* For the pod that is in the case, this is flipped again though.
|
||||||
*/
|
*/
|
||||||
val isLeftPodMicrophone: Boolean
|
override val isLeftPodMicrophone: Boolean
|
||||||
get() = rawStatus.isBitSet(5) xor isThisPodInThecase
|
get() = rawStatus.isBitSet(5) xor isThisPodInThecase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data flip bit is UNset if the right pod is primary.
|
* The data flip bit is UNset if the right pod is primary.
|
||||||
* For the pod that is in the case, this is flipped again though.
|
* For the pod that is in the case, this is flipped again though.
|
||||||
*/
|
*/
|
||||||
val isRightPodMicrophone: Boolean
|
override val isRightPodMicrophone: Boolean
|
||||||
get() = !rawStatus.isBitSet(5) xor isThisPodInThecase
|
get() = !rawStatus.isBitSet(5) xor isThisPodInThecase
|
||||||
|
|
||||||
val isLeftPodCharging: Boolean
|
override val isLeftPodCharging: Boolean
|
||||||
get() = when (areValuesFlipped) {
|
get() = when (areValuesFlipped) {
|
||||||
false -> rawFlags.isBitSet(0)
|
false -> rawFlags.isBitSet(0)
|
||||||
true -> rawFlags.isBitSet(1)
|
true -> rawFlags.isBitSet(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val isRightPodCharging: Boolean
|
override val isRightPodCharging: Boolean
|
||||||
get() = when (areValuesFlipped) {
|
get() = when (areValuesFlipped) {
|
||||||
false -> rawFlags.isBitSet(1)
|
false -> rawFlags.isBitSet(1)
|
||||||
true -> rawFlags.isBitSet(0)
|
true -> rawFlags.isBitSet(0)
|
||||||
@@ -143,42 +142,19 @@ interface DualApplePods : ApplePods, HasDualPods, HasDualEarDetection, HasCase {
|
|||||||
UNKNOWN(0xFF..0xFF);
|
UNKNOWN(0xFF..0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
val deviceColor: DeviceColor
|
override val state: ConnectionState
|
||||||
get() = DeviceColor.values().firstOrNull { it.raw == rawDeviceColor } ?: DeviceColor.UNKNOWN
|
|
||||||
|
|
||||||
enum class DeviceColor(val raw: UByte?) {
|
|
||||||
|
|
||||||
WHITE(0x00),
|
|
||||||
BLACK(0x01),
|
|
||||||
RED(0x02),
|
|
||||||
BLUE(0x03),
|
|
||||||
PINK(0x04),
|
|
||||||
GRAY(0x05),
|
|
||||||
SILVER(0x06),
|
|
||||||
GOLD(0x07),
|
|
||||||
ROSE_GOLD(0x08),
|
|
||||||
SPACE_GRAY(0x09),
|
|
||||||
DARK_BLUE(0x0a),
|
|
||||||
LIGHT_BLUE(0x0b),
|
|
||||||
YELLOW(0x0c),
|
|
||||||
UNKNOWN(null);
|
|
||||||
|
|
||||||
constructor(raw: Int) : this(raw.toUByte())
|
|
||||||
}
|
|
||||||
|
|
||||||
val connectionState: ConnectionState
|
|
||||||
get() = ConnectionState.values().firstOrNull { rawSuffix == it.raw } ?: ConnectionState.UNKNOWN
|
get() = ConnectionState.values().firstOrNull { rawSuffix == it.raw } ?: ConnectionState.UNKNOWN
|
||||||
|
|
||||||
fun getConnectionStateLabel(context: Context): String = context.getString(connectionState.labelRes)
|
enum class ConnectionState(val raw: UByte?, @StringRes val labelRes: Int) : HasStateDetection.State {
|
||||||
|
|
||||||
enum class ConnectionState(val raw: UByte?, @StringRes val labelRes: Int) {
|
|
||||||
DISCONNECTED(0x00, R.string.pods_connection_state_disconnected_label),
|
DISCONNECTED(0x00, R.string.pods_connection_state_disconnected_label),
|
||||||
IDLE(0x04, R.string.pods_connection_state_idle_label),
|
IDLE(0x04, R.string.pods_connection_state_idle_label),
|
||||||
MUSIC(0x05, R.string.pods_connection_state_music_label),
|
MUSIC(0x05, R.string.pods_connection_state_music_label),
|
||||||
CALL(0x06, R.string.pods_connection_state_call_label),
|
CALL(0x06, R.string.pods_connection_state_call_label),
|
||||||
RINGING(0x07, R.string.pods_connection_state_ringing_label),
|
RINGING(0x07, R.string.pods_connection_state_ringing_label),
|
||||||
HANGING_UP(0x09, R.string.pods_connection_state_hanging_up_label),
|
HANGING_UP(0x09, R.string.pods_connection_state_hanging_up_label),
|
||||||
UNKNOWN(null, R.string.general_value_unknown_label);
|
UNKNOWN(null, R.string.pods_connection_state_unknown_label);
|
||||||
|
|
||||||
|
override fun getLabel(context: Context): String = context.getString(labelRes)
|
||||||
|
|
||||||
constructor(raw: Int, @StringRes labelRes: Int) : this(raw.toUByte(), labelRes)
|
constructor(raw: Int, @StringRes labelRes: Int) : this(raw.toUByte(), labelRes)
|
||||||
}
|
}
|
||||||
@@ -3,18 +3,17 @@ package eu.darken.capod.pods.core.apple
|
|||||||
import eu.darken.capod.common.debug.logging.Logging.Priority.DEBUG
|
import eu.darken.capod.common.debug.logging.Logging.Priority.DEBUG
|
||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.airpods.AirPodsPro
|
|
||||||
|
|
||||||
abstract class DualApplePodsFactory(private val tag: String) : ApplePodsFactory<DualApplePods>(tag) {
|
abstract class DualApplePodsFactory(private val tag: String) : ApplePodsFactory<DualAirPods>(tag) {
|
||||||
|
|
||||||
fun DualApplePods.getCaseMatchMarkings() = SplitPodsMarkings(
|
fun DualAirPods.getCaseMatchMarkings() = SplitPodsMarkings(
|
||||||
leftPodBattery = batteryLeftPodPercent,
|
leftPodBattery = batteryLeftPodPercent,
|
||||||
rightPodBattery = batteryRightPodPercent,
|
rightPodBattery = batteryRightPodPercent,
|
||||||
microPhoneLeft = isLeftPodMicrophone,
|
microPhoneLeft = isLeftPodMicrophone,
|
||||||
microPhoneRight = isRightPodMicrophone,
|
microPhoneRight = isRightPodMicrophone,
|
||||||
chargingLeft = isLeftPodCharging,
|
chargingLeft = isLeftPodCharging,
|
||||||
chargingRight = isRightPodCharging,
|
chargingRight = isRightPodCharging,
|
||||||
color = deviceColor,
|
color = rawDeviceColor,
|
||||||
model = model
|
model = model
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -28,36 +27,21 @@ abstract class DualApplePodsFactory(private val tag: String) : ApplePodsFactory<
|
|||||||
val microPhoneRight: Boolean,
|
val microPhoneRight: Boolean,
|
||||||
val chargingLeft: Boolean,
|
val chargingLeft: Boolean,
|
||||||
val chargingRight: Boolean,
|
val chargingRight: Boolean,
|
||||||
val color: DualApplePods.DeviceColor,
|
val color: UByte,
|
||||||
val model: PodDevice.Model,
|
val model: PodDevice.Model,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun Collection<KnownDevice>.findSplitPodsMatch(device: DualApplePods): Collection<KnownDevice> {
|
private fun Collection<KnownDevice>.findSplitPodsMatch(device: DualAirPods): Collection<KnownDevice> {
|
||||||
val target = device.getCaseMatchMarkings()
|
val target = device.getCaseMatchMarkings()
|
||||||
|
|
||||||
return filter { known ->
|
return filter { known ->
|
||||||
known.history
|
known.history
|
||||||
.filterIsInstance<DualApplePods>()
|
.filterIsInstance<DualAirPods>()
|
||||||
.any { it.getCaseMatchMarkings() == target }
|
.any { it.getCaseMatchMarkings() == target }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KnownDevice.getLatestCaseBattery(): Float? = history
|
override fun searchHistory(current: DualAirPods): KnownDevice? {
|
||||||
.filterIsInstance<DualApplePods>()
|
|
||||||
.mapNotNull { it.batteryCasePercent }
|
|
||||||
.lastOrNull()
|
|
||||||
|
|
||||||
fun KnownDevice.getLatestCaseLidState(basic: DualApplePods): DualApplePods.LidState? {
|
|
||||||
val definitive = setOf(DualApplePods.LidState.OPEN, DualApplePods.LidState.CLOSED)
|
|
||||||
if (definitive.contains(basic.caseLidState)) return null
|
|
||||||
|
|
||||||
return history
|
|
||||||
.filterIsInstance<AirPodsPro>()
|
|
||||||
.lastOrNull { it.caseLidState != DualApplePods.LidState.NOT_IN_CASE }
|
|
||||||
?.caseLidState
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun searchHistory(current: DualApplePods): KnownDevice? {
|
|
||||||
val basicResult = super.searchHistory(current)
|
val basicResult = super.searchHistory(current)
|
||||||
|
|
||||||
val caseIgnored = knownDevices.values.findSplitPodsMatch(current)
|
val caseIgnored = knownDevices.values.findSplitPodsMatch(current)
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package eu.darken.capod.pods.core.apple
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import eu.darken.capod.pods.core.HasPodStyle
|
||||||
|
|
||||||
|
interface HasAppleColor : ApplePods, HasPodStyle {
|
||||||
|
|
||||||
|
override val podStyle: HasPodStyle.PodStyle
|
||||||
|
get() = DeviceColor.values()
|
||||||
|
.firstOrNull { it.raw == rawDeviceColor }
|
||||||
|
?: DeviceColor.UNKNOWN
|
||||||
|
|
||||||
|
enum class DeviceColor(val raw: UByte?) : HasPodStyle.PodStyle {
|
||||||
|
WHITE(0x00),
|
||||||
|
BLACK(0x01),
|
||||||
|
RED(0x02),
|
||||||
|
BLUE(0x03),
|
||||||
|
PINK(0x04),
|
||||||
|
GRAY(0x05),
|
||||||
|
SILVER(0x06),
|
||||||
|
GOLD(0x07),
|
||||||
|
ROSE_GOLD(0x08),
|
||||||
|
SPACE_GRAY(0x09),
|
||||||
|
DARK_BLUE(0x0a),
|
||||||
|
LIGHT_BLUE(0x0b),
|
||||||
|
YELLOW(0x0c),
|
||||||
|
UNKNOWN(null);
|
||||||
|
|
||||||
|
override fun getLabel(context: Context): String = this.name
|
||||||
|
|
||||||
|
override fun getColor(context: Context): Int = android.R.color.white
|
||||||
|
|
||||||
|
override val identifier: String
|
||||||
|
get() = name
|
||||||
|
|
||||||
|
constructor(raw: Int) : this(raw.toUByte())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,22 @@
|
|||||||
package eu.darken.capod.pods.core.apple
|
package eu.darken.capod.pods.core.apple
|
||||||
|
|
||||||
import eu.darken.capod.common.isBitSet
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import eu.darken.capod.pods.core.HasEarDetection
|
import eu.darken.capod.common.lowerNibble
|
||||||
import eu.darken.capod.pods.core.HasSinglePod
|
import eu.darken.capod.pods.core.SinglePodDevice
|
||||||
|
|
||||||
interface SingleApplePods : BasicSingleApplePods, HasEarDetection, HasSinglePod {
|
/**
|
||||||
|
* Devices that only present a single charge level, e.g. most Beats devices
|
||||||
|
*/
|
||||||
|
interface SingleApplePods : ApplePods, SinglePodDevice, HasAppleColor {
|
||||||
|
|
||||||
val isHeadphonesBeingWorn: Boolean
|
override val batteryHeadsetPercent: Float?
|
||||||
get() = rawStatus.isBitSet(1)
|
get() = when (val value = rawPodsBattery.lowerNibble.toInt()) {
|
||||||
|
15 -> null
|
||||||
val isHeadsetBeingCharged: Boolean
|
else -> if (value > 10) {
|
||||||
get() = rawFlags.isBitSet(0)
|
log { "Headset above 100% battery: $value" }
|
||||||
|
1.0f
|
||||||
override val isBeingWorn: Boolean
|
} else {
|
||||||
get() = isHeadphonesBeingWorn
|
(value / 10f)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
import eu.darken.capod.pods.core.apple.DualAirPods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -20,15 +20,15 @@ data class AirPodsGen1 constructor(
|
|||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
private val cachedBatteryPercentage: Float? = null,
|
private val cachedBatteryPercentage: Float? = null,
|
||||||
private val cachedCaseState: DualApplePods.LidState? = null
|
private val cachedCaseState: DualAirPods.LidState? = null
|
||||||
) : DualApplePods {
|
) : DualAirPods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN1
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN1
|
||||||
|
|
||||||
override val batteryCasePercent: Float?
|
override val batteryCasePercent: Float?
|
||||||
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
||||||
|
|
||||||
override val caseLidState: DualApplePods.LidState
|
override val caseLidState: DualAirPods.LidState
|
||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
@@ -36,11 +36,13 @@ data class AirPodsGen1 constructor(
|
|||||||
|
|
||||||
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
getModelInfo().full == DEVICE_CODE && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
|
||||||
var basic = AirPodsGen1(scanResult = scanResult, proximityMessage = proximityMessage)
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
|
var basic = AirPodsGen1(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
import eu.darken.capod.pods.core.apple.DualAirPods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -20,15 +20,15 @@ data class AirPodsGen2 constructor(
|
|||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
private val cachedBatteryPercentage: Float? = null,
|
private val cachedBatteryPercentage: Float? = null,
|
||||||
private val cachedCaseState: DualApplePods.LidState? = null
|
private val cachedCaseState: DualAirPods.LidState? = null
|
||||||
) : DualApplePods {
|
) : DualAirPods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN2
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN2
|
||||||
|
|
||||||
override val batteryCasePercent: Float?
|
override val batteryCasePercent: Float?
|
||||||
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
||||||
|
|
||||||
override val caseLidState: DualApplePods.LidState
|
override val caseLidState: DualAirPods.LidState
|
||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
@@ -36,11 +36,12 @@ data class AirPodsGen2 constructor(
|
|||||||
|
|
||||||
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
getModelInfo().full == DEVICE_CODE && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
var basic = AirPodsGen2(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = AirPodsGen2(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
import eu.darken.capod.pods.core.apple.DualAirPods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -20,14 +20,14 @@ data class AirPodsGen3 constructor(
|
|||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
private val cachedBatteryPercentage: Float? = null,
|
private val cachedBatteryPercentage: Float? = null,
|
||||||
private val cachedCaseState: DualApplePods.LidState? = null
|
private val cachedCaseState: DualAirPods.LidState? = null
|
||||||
) : DualApplePods {
|
) : DualAirPods {
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN3
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN3
|
||||||
|
|
||||||
override val batteryCasePercent: Float?
|
override val batteryCasePercent: Float?
|
||||||
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
||||||
|
|
||||||
override val caseLidState: DualApplePods.LidState
|
override val caseLidState: DualAirPods.LidState
|
||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
@@ -35,11 +35,12 @@ data class AirPodsGen3 constructor(
|
|||||||
|
|
||||||
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
getModelInfo().full == DEVICE_CODE && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
var basic = AirPodsGen3(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = AirPodsGen3(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package eu.darken.capod.pods.core.apple.airpods
|
|||||||
|
|
||||||
import eu.darken.capod.common.bluetooth.BleScanResult
|
import eu.darken.capod.common.bluetooth.BleScanResult
|
||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
|
import eu.darken.capod.common.isBitSet
|
||||||
|
import eu.darken.capod.pods.core.HasEarDetection
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.SingleApplePods
|
import eu.darken.capod.pods.core.apple.SingleApplePods
|
||||||
@@ -19,20 +21,30 @@ data class AirPodsMax(
|
|||||||
override val proximityMessage: ProximityPairing.Message,
|
override val proximityMessage: ProximityPairing.Message,
|
||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
) : SingleApplePods {
|
) : SingleApplePods, HasEarDetection {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_MAX
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_MAX
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super.rssi
|
||||||
|
|
||||||
|
val isHeadphonesBeingWorn: Boolean
|
||||||
|
get() = rawStatus.isBitSet(1)
|
||||||
|
|
||||||
|
val isHeadsetBeingCharged: Boolean
|
||||||
|
get() = rawFlags.isBitSet(0)
|
||||||
|
|
||||||
|
override val isBeingWorn: Boolean
|
||||||
|
get() = isHeadphonesBeingWorn
|
||||||
|
|
||||||
class Factory @Inject constructor() : SingleApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : SingleApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().dirty == DEVICE_CODE_DIRTY
|
getModelInfo().dirty == DEVICE_CODE_DIRTY && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
var basic = AirPodsMax(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = AirPodsMax(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
@@ -48,7 +60,6 @@ data class AirPodsMax(
|
|||||||
rssiAverage = result.averageRssi(basic.rssi),
|
rssiAverage = result.averageRssi(basic.rssi),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
import eu.darken.capod.pods.core.apple.DualAirPods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods.LidState
|
import eu.darken.capod.pods.core.apple.DualAirPods.LidState
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -22,7 +22,7 @@ data class AirPodsPro(
|
|||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
private val cachedBatteryPercentage: Float? = null,
|
private val cachedBatteryPercentage: Float? = null,
|
||||||
private val cachedCaseState: LidState? = null
|
private val cachedCaseState: LidState? = null
|
||||||
) : DualApplePods {
|
) : DualAirPods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_PRO
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_PRO
|
||||||
|
|
||||||
@@ -37,11 +37,12 @@ data class AirPodsPro(
|
|||||||
|
|
||||||
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
getModelInfo().full == DEVICE_CODE && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
var basic = AirPodsPro(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = AirPodsPro(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePods
|
import eu.darken.capod.pods.core.apple.SingleApplePods
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePodsFactory
|
import eu.darken.capod.pods.core.apple.SingleApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -19,20 +19,21 @@ data class BeatsFlex(
|
|||||||
override val proximityMessage: ProximityPairing.Message,
|
override val proximityMessage: ProximityPairing.Message,
|
||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
) : BasicSingleApplePods {
|
) : SingleApplePods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.BEATS_FLEX
|
override val model: PodDevice.Model = PodDevice.Model.BEATS_FLEX
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super.rssi
|
||||||
|
|
||||||
class Factory @Inject constructor() : BasicSingleApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : SingleApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
getModelInfo().full == DEVICE_CODE && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
var basic = BeatsFlex(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = BeatsFlex(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePods
|
import eu.darken.capod.pods.core.apple.SingleApplePods
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePodsFactory
|
import eu.darken.capod.pods.core.apple.SingleApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -19,19 +19,20 @@ data class BeatsSolo3(
|
|||||||
override val proximityMessage: ProximityPairing.Message,
|
override val proximityMessage: ProximityPairing.Message,
|
||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
) : BasicSingleApplePods {
|
) : SingleApplePods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.BEATS_SOLO_3
|
override val model: PodDevice.Model = PodDevice.Model.BEATS_SOLO_3
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super.rssi
|
||||||
|
|
||||||
class Factory @Inject constructor() : BasicSingleApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : SingleApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
getModelInfo().full == DEVICE_CODE && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
var basic = BeatsSolo3(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = BeatsSolo3(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePods
|
import eu.darken.capod.pods.core.apple.SingleApplePods
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePodsFactory
|
import eu.darken.capod.pods.core.apple.SingleApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -19,17 +19,18 @@ data class BeatsStudio3(
|
|||||||
override val proximityMessage: ProximityPairing.Message,
|
override val proximityMessage: ProximityPairing.Message,
|
||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
) : BasicSingleApplePods {
|
) : SingleApplePods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.BEATS_STUDIO_3
|
override val model: PodDevice.Model = PodDevice.Model.BEATS_STUDIO_3
|
||||||
|
|
||||||
class Factory @Inject constructor() : BasicSingleApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : SingleApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().dirty == DEVICE_CODE_DIRTY
|
getModelInfo().dirty == DEVICE_CODE_DIRTY && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
var basic = BeatsStudio3(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = BeatsStudio3(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
@@ -45,7 +46,6 @@ data class BeatsStudio3(
|
|||||||
rssiAverage = result.averageRssi(basic.rssi),
|
rssiAverage = result.averageRssi(basic.rssi),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePods
|
import eu.darken.capod.pods.core.apple.SingleApplePods
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePodsFactory
|
import eu.darken.capod.pods.core.apple.SingleApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -19,20 +19,21 @@ data class BeatsX(
|
|||||||
override val proximityMessage: ProximityPairing.Message,
|
override val proximityMessage: ProximityPairing.Message,
|
||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
) : BasicSingleApplePods {
|
) : SingleApplePods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.BEATS_X
|
override val model: PodDevice.Model = PodDevice.Model.BEATS_X
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super.rssi
|
||||||
|
|
||||||
class Factory @Inject constructor() : BasicSingleApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : SingleApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
getModelInfo().full == DEVICE_CODE && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
var basic = BeatsX(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = BeatsX(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePods
|
import eu.darken.capod.pods.core.apple.SingleApplePods
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePodsFactory
|
import eu.darken.capod.pods.core.apple.SingleApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -19,19 +19,21 @@ data class PowerBeats3(
|
|||||||
override val proximityMessage: ProximityPairing.Message,
|
override val proximityMessage: ProximityPairing.Message,
|
||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
) : BasicSingleApplePods {
|
) : SingleApplePods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.POWERBEATS_3
|
override val model: PodDevice.Model = PodDevice.Model.POWERBEATS_3
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super.rssi
|
||||||
|
|
||||||
class Factory @Inject constructor() : BasicSingleApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : SingleApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
getModelInfo().full == DEVICE_CODE && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
var basic = PowerBeats3(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = PowerBeats3(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
import eu.darken.capod.pods.core.apple.DualAirPods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -20,15 +20,15 @@ data class PowerBeatsPro(
|
|||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
private val cachedBatteryPercentage: Float? = null,
|
private val cachedBatteryPercentage: Float? = null,
|
||||||
private val cachedCaseState: DualApplePods.LidState? = null
|
private val cachedCaseState: DualAirPods.LidState? = null
|
||||||
) : DualApplePods {
|
) : DualAirPods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.POWERBEATS_PRO
|
override val model: PodDevice.Model = PodDevice.Model.POWERBEATS_PRO
|
||||||
|
|
||||||
override val batteryCasePercent: Float?
|
override val batteryCasePercent: Float?
|
||||||
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
||||||
|
|
||||||
override val caseLidState: DualApplePods.LidState
|
override val caseLidState: DualAirPods.LidState
|
||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
@@ -36,11 +36,12 @@ data class PowerBeatsPro(
|
|||||||
|
|
||||||
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
||||||
|
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean =
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
proximityMessage.getModelInfo().dirty == DEVICE_CODE_DIRTY
|
getModelInfo().dirty == DEVICE_CODE_DIRTY && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
|
||||||
|
}
|
||||||
|
|
||||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
var basic = PowerBeatsPro(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = PowerBeatsPro(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
package eu.darken.capod.pods.core.apple.misc
|
||||||
|
|
||||||
|
import eu.darken.capod.common.bluetooth.BleScanResult
|
||||||
|
import eu.darken.capod.common.debug.logging.log
|
||||||
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
|
import eu.darken.capod.common.isBitSet
|
||||||
|
import eu.darken.capod.common.lowerNibble
|
||||||
|
import eu.darken.capod.common.upperNibble
|
||||||
|
import eu.darken.capod.pods.core.DualPodDevice
|
||||||
|
import eu.darken.capod.pods.core.HasCase
|
||||||
|
import eu.darken.capod.pods.core.HasDualMicrophone
|
||||||
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
|
import eu.darken.capod.pods.core.apple.ApplePodsFactory
|
||||||
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
|
import java.time.Instant
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basically an AirPods GEN1 clone
|
||||||
|
* Similar data structure but a lot of placeholder values or hardcoded values
|
||||||
|
*/
|
||||||
|
data class Twsi99999 constructor(
|
||||||
|
override val identifier: PodDevice.Id = PodDevice.Id(),
|
||||||
|
override val seenLastAt: Instant = Instant.now(),
|
||||||
|
override val seenFirstAt: Instant = Instant.now(),
|
||||||
|
override val seenCounter: Int = 1,
|
||||||
|
override val scanResult: BleScanResult,
|
||||||
|
override val proximityMessage: ProximityPairing.Message,
|
||||||
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
|
private val rssiAverage: Int? = null,
|
||||||
|
private val cachedBatteryPercentage: Float? = null,
|
||||||
|
) : ApplePods, DualPodDevice, HasDualMicrophone, HasCase {
|
||||||
|
|
||||||
|
override val model: PodDevice.Model = PodDevice.Model.TWS_I99999
|
||||||
|
|
||||||
|
override val rssi: Int
|
||||||
|
get() = rssiAverage ?: super<ApplePods>.rssi
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normally values for the left pod are in the lower nibbles, if the left pod is primary (microphone)
|
||||||
|
* If the right pod is the primary, the values are flipped.
|
||||||
|
*/
|
||||||
|
val areValuesFlipped: Boolean
|
||||||
|
get() = !rawStatus.isBitSet(5)
|
||||||
|
|
||||||
|
override val batteryLeftPodPercent: Float?
|
||||||
|
get() {
|
||||||
|
val value = when (areValuesFlipped) {
|
||||||
|
true -> rawPodsBattery.upperNibble.toInt()
|
||||||
|
false -> rawPodsBattery.lowerNibble.toInt()
|
||||||
|
}
|
||||||
|
return when (value) {
|
||||||
|
15 -> null
|
||||||
|
else -> if (value > 10) {
|
||||||
|
log { "Left pod: Above 100% battery: $value" }
|
||||||
|
1.0f
|
||||||
|
} else {
|
||||||
|
(value / 10f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val batteryRightPodPercent: Float?
|
||||||
|
get() {
|
||||||
|
val value = when (areValuesFlipped) {
|
||||||
|
true -> rawPodsBattery.lowerNibble.toInt()
|
||||||
|
false -> rawPodsBattery.upperNibble.toInt()
|
||||||
|
}
|
||||||
|
return when (value) {
|
||||||
|
15 -> null
|
||||||
|
else -> if (value > 10) {
|
||||||
|
log { "Right pod: Above 100% battery: $value" }
|
||||||
|
1.0f
|
||||||
|
} else {
|
||||||
|
value / 10f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val isThisPodInThecase: Boolean
|
||||||
|
get() = rawStatus.isBitSet(6)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data flip bit is set if the left pod is primary.
|
||||||
|
* For the pod that is in the case, this is flipped again though.
|
||||||
|
*/
|
||||||
|
override val isLeftPodMicrophone: Boolean
|
||||||
|
get() = rawStatus.isBitSet(5) xor isThisPodInThecase
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data flip bit is UNset if the right pod is primary.
|
||||||
|
* For the pod that is in the case, this is flipped again though.
|
||||||
|
*/
|
||||||
|
override val isRightPodMicrophone: Boolean
|
||||||
|
get() = !rawStatus.isBitSet(5) xor isThisPodInThecase
|
||||||
|
|
||||||
|
override val batteryCasePercent: Float?
|
||||||
|
get() = when (val value = rawCaseBattery.toInt()) {
|
||||||
|
15 -> cachedBatteryPercentage
|
||||||
|
else -> if (value > 10) {
|
||||||
|
log { "Case: Above 100% battery: $value" }
|
||||||
|
1.0f
|
||||||
|
} else {
|
||||||
|
value / 10f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val isCaseCharging: Boolean
|
||||||
|
get() = rawFlags.isBitSet(2)
|
||||||
|
|
||||||
|
class Factory @Inject constructor() : ApplePodsFactory<Twsi99999>(TAG) {
|
||||||
|
|
||||||
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
|
||||||
|
// Official message length is 19HEX, i.e. binary 25, did they copy this wrong?
|
||||||
|
getModelInfo().full == DEVICE_CODE && length == 19
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
|
||||||
|
var basic = Twsi99999(scanResult = scanResult, proximityMessage = message)
|
||||||
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
|
updateHistory(basic)
|
||||||
|
|
||||||
|
if (result == null) return basic
|
||||||
|
|
||||||
|
return basic.copy(
|
||||||
|
identifier = result.id,
|
||||||
|
seenFirstAt = result.seenFirstAt,
|
||||||
|
seenCounter = result.seenCounter,
|
||||||
|
confidence = result.confidence,
|
||||||
|
cachedBatteryPercentage = result.getLatestCaseBattery(),
|
||||||
|
rssiAverage = result.averageRssi(basic.rssi),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val DEVICE_CODE = 0x0220.toUShort()
|
||||||
|
private val TAG = logTag("PodDevice", "Apple", "TWS", "i99999")
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-4
@@ -1,10 +1,12 @@
|
|||||||
package eu.darken.capod.pods.core.apple
|
package eu.darken.capod.pods.core.apple.misc
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.darken.capod.R
|
import eu.darken.capod.R
|
||||||
import eu.darken.capod.common.bluetooth.BleScanResult
|
import eu.darken.capod.common.bluetooth.BleScanResult
|
||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
|
import eu.darken.capod.pods.core.apple.ApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -28,13 +30,13 @@ data class UnknownAppleDevice(
|
|||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super.rssi
|
||||||
|
|
||||||
class Factory @Inject constructor() : ApplePodsFactory<ApplePods>(TAG) {
|
class Factory @Inject constructor() : ApplePodsFactory<ApplePods>(TAG) {
|
||||||
override fun isResponsible(proximityMessage: ProximityPairing.Message): Boolean = true
|
override fun isResponsible(message: ProximityPairing.Message): Boolean = true
|
||||||
|
|
||||||
override fun create(
|
override fun create(
|
||||||
scanResult: BleScanResult,
|
scanResult: BleScanResult,
|
||||||
proximityMessage: ProximityPairing.Message,
|
message: ProximityPairing.Message,
|
||||||
): ApplePods {
|
): ApplePods {
|
||||||
var basic = UnknownAppleDevice(scanResult = scanResult, proximityMessage = proximityMessage)
|
var basic = UnknownAppleDevice(scanResult = scanResult, proximityMessage = message)
|
||||||
val result = searchHistory(basic)
|
val result = searchHistory(basic)
|
||||||
|
|
||||||
if (result != null) basic = basic.copy(identifier = result.id)
|
if (result != null) basic = basic.copy(identifier = result.id)
|
||||||
@@ -27,10 +27,6 @@ object ProximityPairing {
|
|||||||
log { "Not a proximity pairing message: $this" }
|
log { "Not a proximity pairing message: $this" }
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
if (message.length != PROXIMITY_PAIRING_MESSAGE_LENGTH) {
|
|
||||||
log { "Proximity pairing message has invalid length." }
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return Message(
|
return Message(
|
||||||
type = message.type,
|
type = message.type,
|
||||||
@@ -43,7 +39,7 @@ object ProximityPairing {
|
|||||||
fun getBleScanFilter(): Set<ScanFilter> {
|
fun getBleScanFilter(): Set<ScanFilter> {
|
||||||
val manufacturerData = ByteArray(CONTINUITY_PROTOCOL_MESSAGE_LENGTH).apply {
|
val manufacturerData = ByteArray(CONTINUITY_PROTOCOL_MESSAGE_LENGTH).apply {
|
||||||
this[0] = CONTINUITY_PROTOCOL_MESSAGE_TYPE_PROXIMITY_PAIRING.toByte()
|
this[0] = CONTINUITY_PROTOCOL_MESSAGE_TYPE_PROXIMITY_PAIRING.toByte()
|
||||||
this[1] = PROXIMITY_PAIRING_MESSAGE_LENGTH.toByte()
|
this[1] = PAIRING_MESSAGE_LENGTH.toByte()
|
||||||
}
|
}
|
||||||
|
|
||||||
val manufacturerDataMask = ByteArray(CONTINUITY_PROTOCOL_MESSAGE_LENGTH).apply {
|
val manufacturerDataMask = ByteArray(CONTINUITY_PROTOCOL_MESSAGE_LENGTH).apply {
|
||||||
@@ -62,5 +58,7 @@ object ProximityPairing {
|
|||||||
|
|
||||||
private const val CONTINUITY_PROTOCOL_MESSAGE_LENGTH = 27
|
private const val CONTINUITY_PROTOCOL_MESSAGE_LENGTH = 27
|
||||||
internal val CONTINUITY_PROTOCOL_MESSAGE_TYPE_PROXIMITY_PAIRING = 0x07.toUByte()
|
internal val CONTINUITY_PROTOCOL_MESSAGE_TYPE_PROXIMITY_PAIRING = 0x07.toUByte()
|
||||||
internal const val PROXIMITY_PAIRING_MESSAGE_LENGTH = 25
|
|
||||||
|
// This is the default message length among official Apple devices, clones may have different length
|
||||||
|
internal const val PAIRING_MESSAGE_LENGTH = 25
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import eu.darken.capod.common.debug.logging.logTag
|
|||||||
import eu.darken.capod.common.flow.setupCommonEventHandlers
|
import eu.darken.capod.common.flow.setupCommonEventHandlers
|
||||||
import eu.darken.capod.main.core.GeneralSettings
|
import eu.darken.capod.main.core.GeneralSettings
|
||||||
import eu.darken.capod.monitor.core.PodMonitor
|
import eu.darken.capod.monitor.core.PodMonitor
|
||||||
import eu.darken.capod.pods.core.HasDualEarDetection
|
|
||||||
import eu.darken.capod.pods.core.HasEarDetection
|
import eu.darken.capod.pods.core.HasEarDetection
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
import eu.darken.capod.pods.core.HasEarDetectionDual
|
||||||
|
import eu.darken.capod.pods.core.apple.DualAirPods
|
||||||
import eu.darken.capod.reaction.settings.ReactionSettings
|
import eu.darken.capod.reaction.settings.ReactionSettings
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -68,12 +68,12 @@ class AutoConnect @Inject constructor(
|
|||||||
val conditionFulfilled = when (condition) {
|
val conditionFulfilled = when (condition) {
|
||||||
AutoConnectCondition.WHEN_SEEN -> true
|
AutoConnectCondition.WHEN_SEEN -> true
|
||||||
AutoConnectCondition.CASE_OPEN -> when (mainDevice) {
|
AutoConnectCondition.CASE_OPEN -> when (mainDevice) {
|
||||||
is DualApplePods -> mainDevice.caseLidState == DualApplePods.LidState.OPEN
|
is DualAirPods -> mainDevice.caseLidState == DualAirPods.LidState.OPEN
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
AutoConnectCondition.IN_EAR -> when (mainDevice) {
|
AutoConnectCondition.IN_EAR -> when (mainDevice) {
|
||||||
is HasEarDetection -> {
|
is HasEarDetection -> {
|
||||||
if (mainDevice is HasDualEarDetection && reactionSettings.onePodMode.value) {
|
if (mainDevice is HasEarDetectionDual && reactionSettings.onePodMode.value) {
|
||||||
mainDevice.isEitherPodInEar
|
mainDevice.isEitherPodInEar
|
||||||
} else {
|
} else {
|
||||||
mainDevice.isBeingWorn
|
mainDevice.isBeingWorn
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import eu.darken.capod.common.debug.logging.logTag
|
|||||||
import eu.darken.capod.common.flow.setupCommonEventHandlers
|
import eu.darken.capod.common.flow.setupCommonEventHandlers
|
||||||
import eu.darken.capod.common.flow.withPrevious
|
import eu.darken.capod.common.flow.withPrevious
|
||||||
import eu.darken.capod.monitor.core.PodMonitor
|
import eu.darken.capod.monitor.core.PodMonitor
|
||||||
import eu.darken.capod.pods.core.HasDualEarDetection
|
|
||||||
import eu.darken.capod.pods.core.HasEarDetection
|
import eu.darken.capod.pods.core.HasEarDetection
|
||||||
|
import eu.darken.capod.pods.core.HasEarDetectionDual
|
||||||
import eu.darken.capod.reaction.settings.ReactionSettings
|
import eu.darken.capod.reaction.settings.ReactionSettings
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -48,7 +48,7 @@ class PlayPause @Inject constructor(
|
|||||||
return@onEach
|
return@onEach
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previous is HasDualEarDetection && current is HasDualEarDetection && reactionSettings.onePodMode.value) {
|
if (previous is HasEarDetectionDual && current is HasEarDetectionDual && reactionSettings.onePodMode.value) {
|
||||||
log(TAG) { "Ear status changed for dual pod device in single pod mode." }
|
log(TAG) { "Ear status changed for dual pod device in single pod mode." }
|
||||||
val previousWorn = previous.isEitherPodInEar
|
val previousWorn = previous.isEitherPodInEar
|
||||||
val currentWorn = current.isEitherPodInEar
|
val currentWorn = current.isEitherPodInEar
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import eu.darken.capod.common.flow.setupCommonEventHandlers
|
|||||||
import eu.darken.capod.common.flow.withPrevious
|
import eu.darken.capod.common.flow.withPrevious
|
||||||
import eu.darken.capod.monitor.core.PodMonitor
|
import eu.darken.capod.monitor.core.PodMonitor
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
import eu.darken.capod.pods.core.apple.DualAirPods
|
||||||
import eu.darken.capod.reaction.popup.ui.PopUpWindow
|
import eu.darken.capod.reaction.popup.ui.PopUpWindow
|
||||||
import eu.darken.capod.reaction.settings.ReactionSettings
|
import eu.darken.capod.reaction.settings.ReactionSettings
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
@@ -39,7 +39,7 @@ class PopUpReaction @Inject constructor(
|
|||||||
.withPrevious()
|
.withPrevious()
|
||||||
.setupCommonEventHandlers(TAG) { "monitor" }
|
.setupCommonEventHandlers(TAG) { "monitor" }
|
||||||
.map { (previous, current) ->
|
.map { (previous, current) ->
|
||||||
if (previous is DualApplePods? && current is DualApplePods) {
|
if (previous is DualAirPods? && current is DualAirPods) {
|
||||||
log(TAG, VERBOSE) {
|
log(TAG, VERBOSE) {
|
||||||
val prev = previous?.rawCaseLidState?.let { String.format("%02X", it.toByte()) }
|
val prev = previous?.rawCaseLidState?.let { String.format("%02X", it.toByte()) }
|
||||||
val cur = current.rawCaseLidState.let { String.format("%02X", it.toByte()) }
|
val cur = current.rawCaseLidState.let { String.format("%02X", it.toByte()) }
|
||||||
@@ -60,8 +60,8 @@ class PopUpReaction @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun tryPopWindow(current: DualApplePods) {
|
private suspend fun tryPopWindow(current: DualAirPods) {
|
||||||
if (current.caseLidState == DualApplePods.LidState.OPEN) {
|
if (current.caseLidState == DualAirPods.LidState.OPEN) {
|
||||||
log(TAG, INFO) { "Show popup" }
|
log(TAG, INFO) { "Show popup" }
|
||||||
|
|
||||||
val now = Instant.now()
|
val now = Instant.now()
|
||||||
@@ -78,9 +78,9 @@ class PopUpReaction @Inject constructor(
|
|||||||
withContext(dispatcherProvider.Main) {
|
withContext(dispatcherProvider.Main) {
|
||||||
popupWindow.show(current)
|
popupWindow.show(current)
|
||||||
}
|
}
|
||||||
} else if (current.caseLidState != DualApplePods.LidState.OPEN) {
|
} else if (current.caseLidState != DualAirPods.LidState.OPEN) {
|
||||||
when (current.caseLidState) {
|
when (current.caseLidState) {
|
||||||
DualApplePods.LidState.CLOSED -> {
|
DualAirPods.LidState.CLOSED -> {
|
||||||
log(TAG, INFO) { "Lid was actively closed, resetting cooldown." }
|
log(TAG, INFO) { "Lid was actively closed, resetting cooldown." }
|
||||||
coolDowns.remove(current.identifier)
|
coolDowns.remove(current.identifier)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,9 @@ import dagger.hilt.android.qualifiers.ApplicationContext
|
|||||||
import eu.darken.capod.R
|
import eu.darken.capod.R
|
||||||
import eu.darken.capod.common.debug.autoreport.DebugSettings
|
import eu.darken.capod.common.debug.autoreport.DebugSettings
|
||||||
import eu.darken.capod.databinding.PopupNotificationDualPodsBinding
|
import eu.darken.capod.databinding.PopupNotificationDualPodsBinding
|
||||||
import eu.darken.capod.databinding.PopupNotificationSinglePodsBasicBinding
|
|
||||||
import eu.darken.capod.databinding.PopupNotificationSinglePodsBinding
|
import eu.darken.capod.databinding.PopupNotificationSinglePodsBinding
|
||||||
import eu.darken.capod.pods.core.*
|
import eu.darken.capod.pods.core.*
|
||||||
import eu.darken.capod.pods.core.apple.BasicSingleApplePods
|
import eu.darken.capod.pods.core.apple.DualAirPods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
|
||||||
import eu.darken.capod.pods.core.apple.SingleApplePods
|
import eu.darken.capod.pods.core.apple.SingleApplePods
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -28,16 +26,13 @@ class PopUpPodViewFactory @Inject constructor(
|
|||||||
private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||||
|
|
||||||
fun createContentView(parent: ViewGroup, device: PodDevice): View = when (device) {
|
fun createContentView(parent: ViewGroup, device: PodDevice): View = when (device) {
|
||||||
is DualApplePods -> createDualApplePods(parent, device)
|
is DualAirPods -> createDualApplePods(parent, device)
|
||||||
is SingleApplePods -> createSingleApplePods(parent, device) // Unused, has no case to trigger reaction?
|
// Unused, has no case to trigger reaction?
|
||||||
is BasicSingleApplePods -> createSingleBasicApplePods(
|
is SingleApplePods -> createSingleApplePods(parent, device)
|
||||||
parent,
|
|
||||||
device
|
|
||||||
) // Unused, has no case to trigger reaction?
|
|
||||||
else -> throw IllegalArgumentException("Unexpected device: $device")
|
else -> throw IllegalArgumentException("Unexpected device: $device")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDualApplePods(parent: ViewGroup, device: DualApplePods): View =
|
private fun createDualApplePods(parent: ViewGroup, device: DualAirPods): View =
|
||||||
PopupNotificationDualPodsBinding.inflate(layoutInflater, parent, false).apply {
|
PopupNotificationDualPodsBinding.inflate(layoutInflater, parent, false).apply {
|
||||||
device.apply {
|
device.apply {
|
||||||
podIcon.setImageResource(iconRes)
|
podIcon.setImageResource(iconRes)
|
||||||
@@ -72,17 +67,4 @@ class PopUpPodViewFactory @Inject constructor(
|
|||||||
}
|
}
|
||||||
}.root
|
}.root
|
||||||
|
|
||||||
private fun createSingleBasicApplePods(parent: ViewGroup, device: BasicSingleApplePods): View =
|
|
||||||
PopupNotificationSinglePodsBasicBinding.inflate(layoutInflater, parent, false).apply {
|
|
||||||
device.apply {
|
|
||||||
headphonesIcon.setImageResource(iconRes)
|
|
||||||
headphonesLabel.text = getLabel(context)
|
|
||||||
signal.text = getSignalQuality(context)
|
|
||||||
signal.isInvisible = debugSettings.isDebugModeEnabled.value
|
|
||||||
|
|
||||||
headphonesBatteryIcon.setImageResource(getBatteryDrawable(batteryHeadsetPercent))
|
|
||||||
headphonesBatteryLabel.text = getBatteryLevelHeadset(context)
|
|
||||||
}
|
|
||||||
}.root
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,8 @@ import android.content.SharedPreferences
|
|||||||
import androidx.preference.PreferenceDataStore
|
import androidx.preference.PreferenceDataStore
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import eu.darken.androidstarter.common.preferences.Settings
|
|
||||||
import eu.darken.capod.common.preferences.PreferenceStoreMapper
|
import eu.darken.capod.common.preferences.PreferenceStoreMapper
|
||||||
|
import eu.darken.capod.common.preferences.Settings
|
||||||
import eu.darken.capod.common.preferences.createFlowPreference
|
import eu.darken.capod.common.preferences.createFlowPreference
|
||||||
import eu.darken.capod.reaction.autoconnect.AutoConnectCondition
|
import eu.darken.capod.reaction.autoconnect.AutoConnectCondition
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,2A9,9 0 0,0 3,11V22L6,19L9,22L12,19L15,22L18,19L21,22V11A9,9 0 0,0 12,2M9,8A2,2 0 0,1 11,10A2,2 0 0,1 9,12A2,2 0 0,1 7,10A2,2 0 0,1 9,8M15,8A2,2 0 0,1 17,10A2,2 0 0,1 15,12A2,2 0 0,1 13,10A2,2 0 0,1 15,8Z" />
|
||||||
|
</vector>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
tools:listitem="@layout/overview_pods_apple_dual_item"
|
tools:listitem="@layout/overview_pods_dual_item"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_horizontal">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/headphones_label"
|
|
||||||
style="@style/TextAppearance.Compat.Notification.Title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
tools:text="Beats Solo 3" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="8dp"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/headphones_battery_icon"
|
|
||||||
style="@style/PodInfoItemIcon"
|
|
||||||
android:src="@drawable/ic_baseline_battery_unknown_24" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/headphones_battery_label"
|
|
||||||
style="@style/TextAppearance.Compat.Notification.Title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_marginHorizontal="8dp"
|
|
||||||
tools:text="100%" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/card"
|
|
||||||
style="@style/MyCardView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginVertical="8dp"
|
|
||||||
tools:context=".main.ui.MainActivity">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:id="@+id/card_content"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/device_icon"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/name"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/name"
|
|
||||||
app:srcCompat="@drawable/ic_device_generic_headphones" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/name"
|
|
||||||
style="@style/TextAppearance.MaterialComponents.Body2"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="16dp"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/last_seen"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/reception"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/device_icon"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:text="Power Beats 3" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/last_seen"
|
|
||||||
style="@style/TextAppearance.MaterialComponents.Caption"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/barrier_top"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/name"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/name"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/name"
|
|
||||||
tools:text="3s ago" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/reception"
|
|
||||||
style="@style/TextAppearance.MaterialComponents.Caption"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="16dp"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:gravity="center"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/name"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/reception_icon"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/name"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/name"
|
|
||||||
tools:text="Yours (RSSI -61)" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/reception_icon"
|
|
||||||
style="@style/TextAppearance.MaterialComponents.Caption"
|
|
||||||
android:layout_width="16dp"
|
|
||||||
android:layout_height="16dp"
|
|
||||||
android:layout_marginHorizontal="16dp"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:gravity="center"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/reception"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/reception"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/reception"
|
|
||||||
app:srcCompat="@drawable/ic_baseline_settings_input_antenna_24"
|
|
||||||
tools:text="Yours (RSSI -61)" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Barrier
|
|
||||||
android:id="@+id/barrier_top"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:barrierDirection="top"
|
|
||||||
app:constraint_referenced_ids="headphones"
|
|
||||||
tools:layout_editor_absoluteY="60dp" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:id="@+id/headphones"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/barrier_bottom"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/barrier_top"
|
|
||||||
app:layout_constraintVertical_bias="0.0"
|
|
||||||
app:layout_goneMarginBottom="16dp">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/battery_icon"
|
|
||||||
style="@style/PodInfoItemIcon"
|
|
||||||
android:src="@drawable/ic_baseline_battery_unknown_24"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/battery_label"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/battery_label" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/battery_label"
|
|
||||||
style="@style/PodInfoItemText"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="2dp"
|
|
||||||
android:text="@string/general_value_unknown_label"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/battery_icon"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Barrier
|
|
||||||
android:id="@+id/barrier_bottom"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:barrierDirection="bottom"
|
|
||||||
app:constraint_referenced_ids="headphones" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/status"
|
|
||||||
style="@style/TextAppearance.MaterialComponents.Body2"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="16dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/barrier_bottom"
|
|
||||||
tools:text="Music Active, Case Closed" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
+7
-7
@@ -12,7 +12,8 @@
|
|||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/card_content"
|
android:id="@+id/card_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="16dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/device_icon"
|
android:id="@+id/device_icon"
|
||||||
@@ -107,7 +108,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginEnd="4dp"
|
android:layout_marginEnd="4dp"
|
||||||
android:minHeight="108dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/barrier_bottom"
|
app:layout_constraintBottom_toTopOf="@id/barrier_bottom"
|
||||||
app:layout_constraintEnd_toStartOf="@id/pod_case_container"
|
app:layout_constraintEnd_toStartOf="@id/pod_case_container"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
@@ -117,6 +117,7 @@
|
|||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/pod_left_icon"
|
android:id="@+id/pod_left_icon"
|
||||||
style="@style/PodInfoItemIcon"
|
style="@style/PodInfoItemIcon"
|
||||||
|
android:contentDescription="@string/pods_dual_left_label"
|
||||||
android:src="@drawable/ic_airpod_left_24"
|
android:src="@drawable/ic_airpod_left_24"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/pod_left_label"
|
app:layout_constraintBottom_toBottomOf="@id/pod_left_label"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
@@ -148,7 +149,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:text="@string/general_value_unknown_label"
|
android:text="@string/general_value_not_available_label"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/pod_left_battery_icon"
|
app:layout_constraintStart_toEndOf="@id/pod_left_battery_icon"
|
||||||
app:layout_constraintTop_toBottomOf="@id/pod_left_label" />
|
app:layout_constraintTop_toBottomOf="@id/pod_left_label" />
|
||||||
@@ -260,7 +261,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:text="@string/general_value_unknown_label"
|
android:text="@string/general_value_not_available_label"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/pod_case_battery_icon"
|
app:layout_constraintStart_toEndOf="@id/pod_case_battery_icon"
|
||||||
app:layout_constraintTop_toBottomOf="@id/pod_case_label" />
|
app:layout_constraintTop_toBottomOf="@id/pod_case_label" />
|
||||||
@@ -322,6 +323,7 @@
|
|||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/pod_right_icon"
|
android:id="@+id/pod_right_icon"
|
||||||
style="@style/PodInfoItemIcon"
|
style="@style/PodInfoItemIcon"
|
||||||
|
android:contentDescription="@string/pods_dual_right_label"
|
||||||
android:src="@drawable/ic_airpod_right_24"
|
android:src="@drawable/ic_airpod_right_24"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/pod_right_label"
|
app:layout_constraintBottom_toBottomOf="@id/pod_right_label"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
@@ -353,7 +355,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:text="@string/general_value_unknown_label"
|
android:text="@string/general_value_not_available_label"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/pod_right_battery_icon"
|
app:layout_constraintStart_toEndOf="@id/pod_right_battery_icon"
|
||||||
app:layout_constraintTop_toBottomOf="@id/pod_right_label" />
|
app:layout_constraintTop_toBottomOf="@id/pod_right_label" />
|
||||||
@@ -420,7 +422,6 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@id/pod_right_microphone_label" />
|
app:layout_constraintTop_toBottomOf="@id/pod_right_microphone_label" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Barrier
|
<androidx.constraintlayout.widget.Barrier
|
||||||
android:id="@+id/barrier_bottom"
|
android:id="@+id/barrier_bottom"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -435,7 +436,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="16dp"
|
android:layout_marginHorizontal="16dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
+4
-6
@@ -12,7 +12,8 @@
|
|||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/card_content"
|
android:id="@+id/card_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="16dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/device_icon"
|
android:id="@+id/device_icon"
|
||||||
@@ -96,13 +97,11 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:minHeight="64dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/barrier_bottom"
|
app:layout_constraintBottom_toTopOf="@id/barrier_bottom"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/barrier_top"
|
app:layout_constraintTop_toBottomOf="@id/barrier_top"
|
||||||
app:layout_constraintVertical_bias="0.0"
|
app:layout_constraintVertical_bias="0.0">
|
||||||
app:layout_goneMarginBottom="16dp">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/battery_icon"
|
android:id="@+id/battery_icon"
|
||||||
@@ -119,7 +118,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:text="@string/general_value_unknown_label"
|
android:text="@string/general_value_not_available_label"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/battery_icon"
|
app:layout_constraintStart_toEndOf="@id/battery_icon"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
@@ -180,7 +179,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="16dp"
|
android:layout_marginHorizontal="16dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/headphones_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/ic_device_generic_earbuds"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/headphones_label"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/headphones_label"
|
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/headphones_label" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/headphones_label"
|
|
||||||
style="@style/TextAppearance.MaterialComponents.Body1"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_marginHorizontal="8dp"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/signal"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/headphones_icon"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:text="Beats Solo 3" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/signal"
|
|
||||||
style="@style/TextAppearance.MaterialComponents.Caption"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:drawableEnd="@drawable/ic_baseline_signal_cellular_alt_24"
|
|
||||||
android:gravity="center"
|
|
||||||
android:minWidth="44dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/headphones_label"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/headphones_label"
|
|
||||||
tools:text="-90%" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:id="@+id/headphones_container"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_chainStyle="spread"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/headphones_label">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@id/headphones_battery_icon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/ic_baseline_battery_unknown_24"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/headphones_battery_label"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/headphones_battery_label"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/headphones_battery_label" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/headphones_battery_label"
|
|
||||||
style="@style/TextAppearance.MaterialComponents.Body1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/headphones_battery_icon"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:text="100%" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@@ -8,7 +8,6 @@
|
|||||||
<string name="general_share_action">مشاركة</string>
|
<string name="general_share_action">مشاركة</string>
|
||||||
<string name="general_done_action">تم</string>
|
<string name="general_done_action">تم</string>
|
||||||
<string name="general_copy_action">نسخ</string>
|
<string name="general_copy_action">نسخ</string>
|
||||||
<string name="general_value_unknown_label">مجهول</string>
|
|
||||||
<string name="general_thank_you_label">شكراً لك</string>
|
<string name="general_thank_you_label">شكراً لك</string>
|
||||||
<string name="general_value_not_available_label">غير متوفر</string>
|
<string name="general_value_not_available_label">غير متوفر</string>
|
||||||
<string name="general_grant_permission_action">منح الإذن</string>
|
<string name="general_grant_permission_action">منح الإذن</string>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
<string name="general_share_action">Paylaş</string>
|
<string name="general_share_action">Paylaş</string>
|
||||||
<string name="general_done_action">Bitdi</string>
|
<string name="general_done_action">Bitdi</string>
|
||||||
<string name="general_copy_action">Kopyala</string>
|
<string name="general_copy_action">Kopyala</string>
|
||||||
<string name="general_value_unknown_label">Bilinmir</string>
|
|
||||||
<string name="general_thank_you_label">Təşəkkürlər</string>
|
<string name="general_thank_you_label">Təşəkkürlər</string>
|
||||||
<string name="general_value_not_available_label">Mövcud deyil</string>
|
<string name="general_value_not_available_label">Mövcud deyil</string>
|
||||||
<string name="general_grant_permission_action">İcazə ver</string>
|
<string name="general_grant_permission_action">İcazə ver</string>
|
||||||
@@ -25,5 +24,107 @@
|
|||||||
<string name="permission_bluetooth_scan_label">Bluetooth skan etmə</string>
|
<string name="permission_bluetooth_scan_label">Bluetooth skan etmə</string>
|
||||||
<string name="permission_bluetooth_scan_description">\"Bluetooth skan etmə\" icazəsi, tətbiqə AirPods kimi yaxınlıqda olan cihazlardan Bluetooth verilənlərini almağa və kəşf etməyə icazə verir.</string>
|
<string name="permission_bluetooth_scan_description">\"Bluetooth skan etmə\" icazəsi, tətbiqə AirPods kimi yaxınlıqda olan cihazlardan Bluetooth verilənlərini almağa və kəşf etməyə icazə verir.</string>
|
||||||
<string name="permission_bluetooth_label">Bluetooth</string>
|
<string name="permission_bluetooth_label">Bluetooth</string>
|
||||||
|
<string name="permission_bluetooth_description">Bu tətbiq, cütləşdirilmiş bluetooth cihazlarına bağlanmaq üçün \"Bluetooth\" icazəsini tələb edir.</string>
|
||||||
<string name="permission_access_fine_location_label">Həssas yerləşməyə müraciət</string>
|
<string name="permission_access_fine_location_label">Həssas yerləşməyə müraciət</string>
|
||||||
|
<string name="permission_access_fine_location_description">CAPod, Bluetooth Zəif Enerji verilənlərini almaq üçün \"dəqiq yerləşmə\" icazəsini istifadə edir. Qulaqlıqlarınız, öz vəziyyətlərini (qalan batereya faizini) yayımlamaq Bluetooth Zəif Enerji texnologiyasını istifadə edir. Bu tətbiq, Bluetooth verilənlərini yerləşmənizi müəyyənləşdirmək üçün İSTİFADƏ ETMİR.</string>
|
||||||
|
<string name="permission_background_location_label">Arxaplanda yerləşmə müraciəti</string>
|
||||||
|
<string name="permission_background_location_description">CAPod, tətbiq bağlı ikən \"Açılan pəncərəni göstər\" və \"Avto-bağlantı qurma\" kimi özəllikləri fəallaşdırmaq üçün \"arxaplanda yerləşmə müraciəti\"ni istifadə edir. Arxaplanda yerləşmə müraciəti tətbiqin arxaplanda olarkən Bluetooth Zəif Enerji verilənlərini almasına icazə verir. Bu tətbiq, Bluetooth verilənlərini yerləşmənizi müəyyənləşdirmək üçün İSTİFADƏ ETMİR.</string>
|
||||||
|
<string name="permission_ignore_battery_optimizations_label">Batereya optimallaşdırmasını sıradan çıxart</string>
|
||||||
|
<string name="permission_ignore_battery_optimizations_description">Batereya optimallaşdırması, bu tətbiqin, tətbiq arxaplanda olarkən güvənli şəkildə Bluetooth verilənlərini almasına mane olur.</string>
|
||||||
|
<string name="pods_dual_left_label">Sol tərəf</string>
|
||||||
|
<string name="pods_dual_right_label">Sağ tərəf</string>
|
||||||
|
<string name="pods_case_label">Qutu</string>
|
||||||
|
<string name="pods_case_status_open_label">Aç</string>
|
||||||
|
<string name="pods_case_status_closed_label">Bağlı</string>
|
||||||
|
<string name="pods_connection_state_disconnected_label">Heç bir cihazla bağlantı qurulmayıb</string>
|
||||||
|
<string name="pods_connection_state_idle_label">Bir cihazla bağlantı qurulub, ancaq boşdadır</string>
|
||||||
|
<string name="pods_connection_state_music_label">Musiqi rejimində</string>
|
||||||
|
<string name="pods_connection_state_call_label">Zəng rejimində</string>
|
||||||
|
<string name="pods_connection_state_ringing_label">Çağırır</string>
|
||||||
|
<string name="pods_connection_state_hanging_up_label">Dəstək asılır</string>
|
||||||
|
<string name="pods_connection_state_unknown_label">Bilinməyən bağlantı vəziyyəti</string>
|
||||||
|
<string name="pods_unknown_raw_data_label">Xam verilənlər</string>
|
||||||
|
<string name="pods_unknown_label">Bilinməyən cihaz</string>
|
||||||
|
<string name="pods_unknown_contact_dev">Bu bir bilinməyən cihazdır, ancaq oxşar mesaj formatı istifadə edir. Bunun üçün dəstək əlavə edək, mənimlə əlaqə saxlayın :)</string>
|
||||||
|
<string name="pods_none_label_short">Cihaz yoxdur</string>
|
||||||
|
<string name="pods_charging_label">Enerji yığır</string>
|
||||||
|
<string name="pods_inear_label">Qulaqda</string>
|
||||||
|
<string name="pods_microphone_label">Mikrofon</string>
|
||||||
|
<string name="pods_yours">Sizin</string>
|
||||||
|
<string name="headset_being_worn_label">Taxılır</string>
|
||||||
|
<string name="pods_case_unknown_state">Bilinməyən vəziyyət</string>
|
||||||
|
<string name="overview_nomaindevice_label">Əsas cihaz yoxdur</string>
|
||||||
|
<string name="overview_nomaindevice_description">Aşkarlanan bütün cihazların sizin olma ehtimalı azdır. Cihazınızı açın, bağlantını qurun və ya tənzimləmələri edin.</string>
|
||||||
|
<string name="settings_label">Tənzimləmələr</string>
|
||||||
|
<string name="settings_privacy_policy_label">Gizlilik siyasəti</string>
|
||||||
|
<string name="settings_privacy_policy_desc">Verilənlərin idarə edilməsi məsuliyyəti.</string>
|
||||||
|
<string name="settings_licenses_label">Lisenziyalar</string>
|
||||||
|
<string name="settings_category_other_label">Digər</string>
|
||||||
|
<string name="settings_general_label">Tənzimləmələr</string>
|
||||||
|
<string name="settings_general_description">Bütün tətbiqə təsir edən ümumi incə tənzimləmələr.</string>
|
||||||
|
<string name="settings_acknowledgements_label">Təşəkkürlər</string>
|
||||||
|
<string name="changelog_label">Dəyişiklik jurnalı</string>
|
||||||
|
<string name="settings_support_email_developer_label">Tərtibatçıya e-poçt göndər</string>
|
||||||
|
<string name="settings_support_installid_label">Quraşdırma kimliyi</string>
|
||||||
|
<string name="settings_support_installid_desc">Avtomatik xəta hesabatları anonimdir. Tərtibatçının xəta hesabatlarınızı tapmasına ehtiyacı varsa quraşdırma kimliyinizi paylaşın.</string>
|
||||||
|
<string name="settings_support_label">Dəstək</string>
|
||||||
|
<string name="settings_support_description">Köməyə ehtiyacınız olarsa.</string>
|
||||||
|
<string name="issue_tracker_label">Problem izləyici</string>
|
||||||
|
<string name="issue_tracker_description">Xəta hesabatları və özəllik tələbləri üçün ictimai bir problem izləyici (yalnız ingiliscə).</string>
|
||||||
|
<string name="discord_label">Discord</string>
|
||||||
|
<string name="discord_description">Suallarınızı vermək üçün yer.</string>
|
||||||
|
<string name="settings_support_email_developer_description">Unutmayın, yalnız almanca və ya ingiliscə cavablandıra bilirəm.</string>
|
||||||
|
<string name="settings_debug_autoreports_label">Avtomatik xəta hesabatları</string>
|
||||||
|
<string name="settings_debug_autoreports_description">Xətaları avtomatik bildirir, məs. tətbiq çökməsi ilə bağlı təfsilatlar daxildir, beləcə onu necə düzəldə biləcəyimi bilirəm.</string>
|
||||||
|
<string name="settings_debug_mode_label">Sazlama rejimi</string>
|
||||||
|
<string name="settings_debug_mode_description">Problemləri aradan qaldırmaq üçün əlavə məlumatları göstər.</string>
|
||||||
|
<string name="settings_monitor_mode_label">Müşahidə rejimi</string>
|
||||||
|
<string name="settings_monitor_mode_description">Bu tətbiq hansı şərtlər altında Bluetooth verilənlərini müşahidə edir.</string>
|
||||||
|
<string name="settings_scanner_mode_label">Skaner rejimi</string>
|
||||||
|
<string name="settings_monitor_mode_manual_label">Tətbiq açılanda</string>
|
||||||
|
<string name="settings_monitor_mode_automatic_label">Cihazla bağlantı qurulanda</string>
|
||||||
|
<string name="settings_monitor_mode_always_label">Həmişə</string>
|
||||||
|
<string name="settings_scanner_mode_lowpower_label">Zəif enerji</string>
|
||||||
|
<string name="settings_scanner_mode_balanced_label">Tarazlı</string>
|
||||||
|
<string name="settings_scanner_mode_lowlatency_label">Aşağı gecikmə</string>
|
||||||
|
<string name="settings_autopause_label">Avto-fasilə</string>
|
||||||
|
<string name="settings_showall_label">Bütün cihazları göstər</string>
|
||||||
|
<string name="settings_showall_description">Sizə yaxın olan digər insanların cihazlarını göstər.</string>
|
||||||
|
<string name="settings_autopplay_label">Avto-oynatma</string>
|
||||||
|
<string name="settings_fake_data_label">Saxta verilənlər</string>
|
||||||
|
<string name="settings_debug_label">Sazlama tənzimləmələri</string>
|
||||||
|
<string name="settings_debug_description">Tətbiqlə əlaqəli problemləri aradan qaldırmağa kömək edəcək əlavə tənzimləmələr.</string>
|
||||||
|
<string name="settings_signal_minimum_label">Minimum siqnal keyfiyyəti</string>
|
||||||
|
<string name="settings_signal_minimum_description">Bir cihazın sahib olması lazım olan minimum siqnal keyfiyyəti sizə aid olaraq qəbul edilməlidir.</string>
|
||||||
|
<string name="settings_autoconnect_label">Avto-bağlanma</string>
|
||||||
|
<string name="settings_autoconnect_description">Android, avtomatik olaraq bağlantı qurmasa, biz də soruşa bilərik. Bu, müşahidə rejimini \"Həmişə\" olaraq tənzimləyəcək.</string>
|
||||||
|
<string name="settings_autoconnect_condition_label">Avto-bağlanma şərti</string>
|
||||||
|
<string name="settings_autoconnect_condition_description">Cihazınızla nə vaxt bağlantı qurmağa çalışacağıq?</string>
|
||||||
|
<string name="settings_reaction_label">Reaksiyalar</string>
|
||||||
|
<string name="settings_reaction_description">Tədbirlərə və davranışlara reaksiya verin.</string>
|
||||||
|
<string name="settings_category_yourdevice_label">Cihazınız</string>
|
||||||
|
<string name="settings_maindevice_address_label">Cihaz ünvanınız</string>
|
||||||
|
<string name="settings_maindevice_address_description">Cütləşdirilmiş cihazınızın ünvanı. Tətbiq, telefonunuzla nə vaxt bağlantı qurulacağını müəyyənləşdirmək üçün bunu istifadə edir.</string>
|
||||||
|
<string name="settings_maindevice_address_none">Heç biri</string>
|
||||||
|
<string name="settings_maindevice_model_label">Cihazınızın modeli</string>
|
||||||
|
<string name="settings_maindevice_model_description">Əsas cihazının modeli. Bu, telefonunuzla bağlantı qurulmadığı vaxtlarda tətbiqin cihazınızı tanımasına kömək edir.</string>
|
||||||
|
<string name="settings_reaction_autoconnect_whenseen_label">Görünəndə</string>
|
||||||
|
<string name="settings_reaction_autoconnect_caseopen_label">Qutu açıqdır</string>
|
||||||
|
<string name="settings_reaction_autoconnect_inear_label">Qulaqda</string>
|
||||||
|
<string name="upgrade_capod_label">CAPod-u yüksəlt</string>
|
||||||
|
<string name="upgrade_capod_description">Əlavə özəllikləri əldə edin və tərtibatçını dəstəkləyin.</string>
|
||||||
|
<string name="settings_popup_caseopen_label">Açılan pəncərəni göstər</string>
|
||||||
|
<string name="settings_popup_caseopen_description">Cihazın qutusu açılanda bir açılan pəncərə göstər (təcrübi).</string>
|
||||||
|
<string name="overview_bluetooth_disabled_label">Bluetooth sıradan çıxarıldı</string>
|
||||||
|
<string name="overview_bluetooth_disabled_description">Bluetooth sıradan çıxarıldı, fəallaşdırın ;)</string>
|
||||||
|
<string name="help_translate_label">Tərcümə</string>
|
||||||
|
<string name="settings_onepod_mode_label">Tək tərəf rejimi</string>
|
||||||
|
<string name="settings_onepod_mode_description">Hər iki tərəfi də taxmağa ehtiyac yoxdur, reaksiyaları tətikləmək üçün tək tərəfi taxmaq yetərlidir.</string>
|
||||||
|
<string name="permission_system_alert_window_label">Sistem xəbərdarlıq pəncərəsi</string>
|
||||||
|
<string name="permission_system_alert_window_description">\"Açılan pəncərəni göstər\" özəlliyini fəal etmək üçün CAPod-a digər tətbiqlərin üzərində göstərmə icazəsi verin.</string>
|
||||||
|
<string name="last_seen_x">Son görünmə: %s</string>
|
||||||
|
<string name="first_seen_x">İlk görünmə: %s</string>
|
||||||
|
<string name="settings_blescanner_unfiltered_label">Filtrlənməmiş BLE verilənləri</string>
|
||||||
|
<string name="settings_blescanner_unfiltered_description">Bütün yayımlanan BLE verilənlərini göstərmək üçün BLE skanerindən bütün filtrləri silin. Yeni qulaqlıq növləri üçün dəstək əlavə etmək üçün faydalıdır.</string>
|
||||||
|
<string name="permission_required_title">Aşağıdakı icazə verilməlidir:</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="general_done_action">সম্পন্ন</string>
|
||||||
|
<string name="general_thank_you_label">ধন্যবাদ</string>
|
||||||
|
<string name="debug_debuglog_size_label">আকার</string>
|
||||||
|
<string name="settings_general_label">সেটিংস</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -8,11 +8,10 @@
|
|||||||
<string name="general_share_action">Comparteix</string>
|
<string name="general_share_action">Comparteix</string>
|
||||||
<string name="general_done_action">Fet</string>
|
<string name="general_done_action">Fet</string>
|
||||||
<string name="general_copy_action">Copia</string>
|
<string name="general_copy_action">Copia</string>
|
||||||
<string name="general_value_unknown_label">Desconegut</string>
|
|
||||||
<string name="general_thank_you_label">Gràcies</string>
|
<string name="general_thank_you_label">Gràcies</string>
|
||||||
<string name="general_value_not_available_label">N/D</string>
|
<string name="general_value_not_available_label">N/D</string>
|
||||||
<string name="general_grant_permission_action">Concedeix el permís</string>
|
<string name="general_grant_permission_action">Concedeix el permís</string>
|
||||||
<string name="general_upgrade_action" comment="general_upgrade_action, Used as label for dialog buttons, i.e. the dialog is about upgrading the app to "Pro" and the positive confirmation button is labeled "Upgrade"">Actualitza</string>
|
<string name="general_upgrade_action">Actualitza</string>
|
||||||
<string name="general_check_action">Comprova</string>
|
<string name="general_check_action">Comprova</string>
|
||||||
<string name="general_close_action">Tanca</string>
|
<string name="general_close_action">Tanca</string>
|
||||||
<string name="debug_debuglog_size_label">Mida</string>
|
<string name="debug_debuglog_size_label">Mida</string>
|
||||||
@@ -43,6 +42,7 @@
|
|||||||
<string name="pods_connection_state_call_label">En mode trucada</string>
|
<string name="pods_connection_state_call_label">En mode trucada</string>
|
||||||
<string name="pods_connection_state_ringing_label">Sonant</string>
|
<string name="pods_connection_state_ringing_label">Sonant</string>
|
||||||
<string name="pods_connection_state_hanging_up_label">Penjant</string>
|
<string name="pods_connection_state_hanging_up_label">Penjant</string>
|
||||||
|
<string name="pods_connection_state_unknown_label">Estat de connexió desconegut</string>
|
||||||
<string name="pods_unknown_raw_data_label">Dades en brut</string>
|
<string name="pods_unknown_raw_data_label">Dades en brut</string>
|
||||||
<string name="pods_unknown_label">Dispositiu desconegut</string>
|
<string name="pods_unknown_label">Dispositiu desconegut</string>
|
||||||
<string name="pods_unknown_contact_dev">Aquest és un dispositiu desconegut, però utilitza un format de missatge similar. Anem a fer-lo compatible, contacteu amb mi :)</string>
|
<string name="pods_unknown_contact_dev">Aquest és un dispositiu desconegut, però utilitza un format de missatge similar. Anem a fer-lo compatible, contacteu amb mi :)</string>
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
<string name="pods_microphone_label">Micròfon</string>
|
<string name="pods_microphone_label">Micròfon</string>
|
||||||
<string name="pods_yours">Vostres</string>
|
<string name="pods_yours">Vostres</string>
|
||||||
<string name="headset_being_worn_label">En ús</string>
|
<string name="headset_being_worn_label">En ús</string>
|
||||||
|
<string name="pods_case_unknown_state">Estat desconegut</string>
|
||||||
<string name="overview_nomaindevice_label">Cap dispositiu principal</string>
|
<string name="overview_nomaindevice_label">Cap dispositiu principal</string>
|
||||||
<string name="overview_nomaindevice_description">És poc probable que tots els dispositius detectats siguin vostres. Enceneu i connecteu el dispositiu o ajusteu la configuració.</string>
|
<string name="overview_nomaindevice_description">És poc probable que tots els dispositius detectats siguin vostres. Enceneu i connecteu el dispositiu o ajusteu la configuració.</string>
|
||||||
<string name="settings_label">Configuració</string>
|
<string name="settings_label">Configuració</string>
|
||||||
@@ -80,7 +81,7 @@
|
|||||||
<string name="settings_monitor_mode_label">Mode monitor</string>
|
<string name="settings_monitor_mode_label">Mode monitor</string>
|
||||||
<string name="settings_monitor_mode_description">En quines circumstàncies aquesta aplicació supervisa les dades Bluetooth.</string>
|
<string name="settings_monitor_mode_description">En quines circumstàncies aquesta aplicació supervisa les dades Bluetooth.</string>
|
||||||
<string name="settings_scanner_mode_label">Mode escàner</string>
|
<string name="settings_scanner_mode_label">Mode escàner</string>
|
||||||
<string name="settings_scanner_mode_description">L\'escàner Bluetooth Low Energy hauria de prioritzar el rendiment o estalviar energia?</string>
|
<string name="settings_scanner_mode_description">L\'escàner de dades Bluetooth Low Energy hauria de prioritzar el rendiment o estalviar energia?</string>
|
||||||
<string name="settings_monitor_mode_manual_label">Quan l\'aplicació està oberta</string>
|
<string name="settings_monitor_mode_manual_label">Quan l\'aplicació està oberta</string>
|
||||||
<string name="settings_monitor_mode_automatic_label">Quan el dispositiu està connectat</string>
|
<string name="settings_monitor_mode_automatic_label">Quan el dispositiu està connectat</string>
|
||||||
<string name="settings_monitor_mode_always_label">Sempre</string>
|
<string name="settings_monitor_mode_always_label">Sempre</string>
|
||||||
@@ -88,13 +89,13 @@
|
|||||||
<string name="settings_scanner_mode_balanced_label">Equilibrat</string>
|
<string name="settings_scanner_mode_balanced_label">Equilibrat</string>
|
||||||
<string name="settings_scanner_mode_lowlatency_label">Baixa latència</string>
|
<string name="settings_scanner_mode_lowlatency_label">Baixa latència</string>
|
||||||
<string name="settings_autopause_label">Pausa automàtica</string>
|
<string name="settings_autopause_label">Pausa automàtica</string>
|
||||||
<string name="settings_autopause_description">Pausa la música quan ús tragueu el dispositiu de l\'orella.</string>
|
<string name="settings_autopause_description">Pausa l\'àudio quan ús tragueu el dispositiu de l\'orella.</string>
|
||||||
<string name="settings_showall_label">Mostra tots els dispositius</string>
|
<string name="settings_showall_label">Mostra tots els dispositius</string>
|
||||||
<string name="settings_showall_description">Mostra els dispositius d\'altres persones que estan a prop vostre.</string>
|
<string name="settings_showall_description">Mostra els dispositius d\'altres persones que estan a prop vostre.</string>
|
||||||
<string name="settings_autopplay_label">Reproducció automàtica</string>
|
<string name="settings_autopplay_label">Reproducció automàtica</string>
|
||||||
<string name="settings_autoplay_description">Inicia la reproducció de música quan ús poseu el dispositiu.</string>
|
<string name="settings_autoplay_description">Inicia la reproducció d\'àudio en utilitzar el dispositiu.</string>
|
||||||
<string name="settings_fake_data_label">Dades falses</string>
|
<string name="settings_fake_data_label">Dades falses</string>
|
||||||
<string name="settings_fake_data_description">Mostra dades falses. Per exemple: simula un dispositiu que no existeix.</string>
|
<string name="settings_fake_data_description">Mostra dades falses. Per exemple: simula dispositius que no existeixen.</string>
|
||||||
<string name="settings_debug_label">Configuració de depuració</string>
|
<string name="settings_debug_label">Configuració de depuració</string>
|
||||||
<string name="settings_debug_description">Configuració addicional per ajudar a resoldre problemes amb l\'aplicació.</string>
|
<string name="settings_debug_description">Configuració addicional per ajudar a resoldre problemes amb l\'aplicació.</string>
|
||||||
<string name="settings_signal_minimum_label">Qualitat de senyal mínima</string>
|
<string name="settings_signal_minimum_label">Qualitat de senyal mínima</string>
|
||||||
@@ -118,7 +119,6 @@
|
|||||||
<string name="upgrade_capod_description">Obteniu característiques addicionals i doneu suport al desenvolupador.</string>
|
<string name="upgrade_capod_description">Obteniu característiques addicionals i doneu suport al desenvolupador.</string>
|
||||||
<string name="settings_popup_caseopen_label">Mostra la finestra emergent</string>
|
<string name="settings_popup_caseopen_label">Mostra la finestra emergent</string>
|
||||||
<string name="settings_popup_caseopen_description">Mostra una finestra emergent quan s\'obre la funda del dispositiu (experimental).</string>
|
<string name="settings_popup_caseopen_description">Mostra una finestra emergent quan s\'obre la funda del dispositiu (experimental).</string>
|
||||||
<string name="notification_channel_reaction_popup_label">Reaccions emergents del dispositiu</string>
|
|
||||||
<string name="overview_bluetooth_disabled_label">El Bluetooth està desactivat</string>
|
<string name="overview_bluetooth_disabled_label">El Bluetooth està desactivat</string>
|
||||||
<string name="overview_bluetooth_disabled_description">El Bluetooth està desactivat, activeu-lo ;)</string>
|
<string name="overview_bluetooth_disabled_description">El Bluetooth està desactivat, activeu-lo ;)</string>
|
||||||
<string name="help_translate_label">Traducció</string>
|
<string name="help_translate_label">Traducció</string>
|
||||||
@@ -131,4 +131,7 @@
|
|||||||
<string name="first_seen_x">Primera vegada vist: %s</string>
|
<string name="first_seen_x">Primera vegada vist: %s</string>
|
||||||
<string name="settings_blescanner_unfiltered_label">Dades BLE sense filtrar</string>
|
<string name="settings_blescanner_unfiltered_label">Dades BLE sense filtrar</string>
|
||||||
<string name="settings_blescanner_unfiltered_description">Elimina els filtres de l\'escàner BLE per mostrar totes les dades BLE emeses. Útil per afegir suport a nous tipus d\'auriculars.</string>
|
<string name="settings_blescanner_unfiltered_description">Elimina els filtres de l\'escàner BLE per mostrar totes les dades BLE emeses. Útil per afegir suport a nous tipus d\'auriculars.</string>
|
||||||
|
<string name="permission_required_title">Cal el permís següent:</string>
|
||||||
|
<string name="settings_compatibility_mode_label">Mode de compatibilitat</string>
|
||||||
|
<string name="settings_compatibility_mode_description">Desactiva les optimitzacions per millorar la compatibilitat. Proveu això si no veieu cap dada.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -8,11 +8,10 @@
|
|||||||
<string name="general_share_action">Sdílet</string>
|
<string name="general_share_action">Sdílet</string>
|
||||||
<string name="general_done_action">Hotovo</string>
|
<string name="general_done_action">Hotovo</string>
|
||||||
<string name="general_copy_action">Kopírovat</string>
|
<string name="general_copy_action">Kopírovat</string>
|
||||||
<string name="general_value_unknown_label">Neznámé</string>
|
|
||||||
<string name="general_thank_you_label">Děkuji Vám</string>
|
<string name="general_thank_you_label">Děkuji Vám</string>
|
||||||
<string name="general_value_not_available_label">N/A</string>
|
<string name="general_value_not_available_label">N/A</string>
|
||||||
<string name="general_grant_permission_action">Udělit oprávnění</string>
|
<string name="general_grant_permission_action">Udělit oprávnění</string>
|
||||||
<string name="general_upgrade_action" comment="general_upgrade_action, Used as label for dialog buttons, i.e. the dialog is about upgrading the app to "Pro" and the positive confirmation button is labeled "Upgrade"">Upgradovat</string>
|
<string name="general_upgrade_action">Upgradovat</string>
|
||||||
<string name="general_check_action">Ověřit</string>
|
<string name="general_check_action">Ověřit</string>
|
||||||
<string name="general_close_action">Zavřít</string>
|
<string name="general_close_action">Zavřít</string>
|
||||||
<string name="debug_debuglog_size_label">Velikost</string>
|
<string name="debug_debuglog_size_label">Velikost</string>
|
||||||
@@ -43,6 +42,7 @@
|
|||||||
<string name="pods_connection_state_call_label">V režimu hovoru</string>
|
<string name="pods_connection_state_call_label">V režimu hovoru</string>
|
||||||
<string name="pods_connection_state_ringing_label">Vyzvánění</string>
|
<string name="pods_connection_state_ringing_label">Vyzvánění</string>
|
||||||
<string name="pods_connection_state_hanging_up_label">Zavěšování</string>
|
<string name="pods_connection_state_hanging_up_label">Zavěšování</string>
|
||||||
|
<string name="pods_connection_state_unknown_label">Neznámý stav připojení</string>
|
||||||
<string name="pods_unknown_raw_data_label">Nezpracovaná data</string>
|
<string name="pods_unknown_raw_data_label">Nezpracovaná data</string>
|
||||||
<string name="pods_unknown_label">Neznámé zařízení</string>
|
<string name="pods_unknown_label">Neznámé zařízení</string>
|
||||||
<string name="pods_unknown_contact_dev">Jedná se o neznámé zařízení, ale používá podobný formát zprávy. Přidejme pro něj podporu. Kontaktujte mě :)</string>
|
<string name="pods_unknown_contact_dev">Jedná se o neznámé zařízení, ale používá podobný formát zprávy. Přidejme pro něj podporu. Kontaktujte mě :)</string>
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
<string name="pods_microphone_label">Mikrofon</string>
|
<string name="pods_microphone_label">Mikrofon</string>
|
||||||
<string name="pods_yours">Vaše</string>
|
<string name="pods_yours">Vaše</string>
|
||||||
<string name="headset_being_worn_label">Používá se</string>
|
<string name="headset_being_worn_label">Používá se</string>
|
||||||
|
<string name="pods_case_unknown_state">Neznámý stav</string>
|
||||||
<string name="overview_nomaindevice_label">Žádné hlavní zařízení</string>
|
<string name="overview_nomaindevice_label">Žádné hlavní zařízení</string>
|
||||||
<string name="overview_nomaindevice_description">Je nepravděpodobné, že by všechna zjištěná zařízení patřila vám. Zapněte a připojte zařízení nebo upravte nastavení.</string>
|
<string name="overview_nomaindevice_description">Je nepravděpodobné, že by všechna zjištěná zařízení patřila vám. Zapněte a připojte zařízení nebo upravte nastavení.</string>
|
||||||
<string name="settings_label">Nastavení</string>
|
<string name="settings_label">Nastavení</string>
|
||||||
@@ -88,11 +89,11 @@
|
|||||||
<string name="settings_scanner_mode_balanced_label">Vyvážený</string>
|
<string name="settings_scanner_mode_balanced_label">Vyvážený</string>
|
||||||
<string name="settings_scanner_mode_lowlatency_label">Nízká latence</string>
|
<string name="settings_scanner_mode_lowlatency_label">Nízká latence</string>
|
||||||
<string name="settings_autopause_label">Autom. pozastavení</string>
|
<string name="settings_autopause_label">Autom. pozastavení</string>
|
||||||
<string name="settings_autopause_description">Při vyjmutí zařízení z ucha pozastavit přehrávání hudby.</string>
|
<string name="settings_autopause_description">Pozastavení zvuku při vyjmutí zařízení z ucha.</string>
|
||||||
<string name="settings_showall_label">Zobrazit všechna zařízení</string>
|
<string name="settings_showall_label">Zobrazit všechna zařízení</string>
|
||||||
<string name="settings_showall_description">Zobrazit zařízení ostatních osob, které se nacházejí ve vaší blízkosti.</string>
|
<string name="settings_showall_description">Zobrazit zařízení ostatních osob, které se nacházejí ve vaší blízkosti.</string>
|
||||||
<string name="settings_autopplay_label">Autom. přehrávání</string>
|
<string name="settings_autopplay_label">Autom. přehrávání</string>
|
||||||
<string name="settings_autoplay_description">Spustit přehrávání hudby při použití zařízení.</string>
|
<string name="settings_autoplay_description">Spuštění přehrávání zvuku při nošení zařízení.</string>
|
||||||
<string name="settings_fake_data_label">Falešná data</string>
|
<string name="settings_fake_data_label">Falešná data</string>
|
||||||
<string name="settings_fake_data_description">Zobrazit falešná data např. simulovat zařízení, které neexistuje.</string>
|
<string name="settings_fake_data_description">Zobrazit falešná data např. simulovat zařízení, které neexistuje.</string>
|
||||||
<string name="settings_debug_label">Nastavení ladění</string>
|
<string name="settings_debug_label">Nastavení ladění</string>
|
||||||
@@ -118,7 +119,6 @@
|
|||||||
<string name="upgrade_capod_description">Získat další funkce a podpořit vývojáře.</string>
|
<string name="upgrade_capod_description">Získat další funkce a podpořit vývojáře.</string>
|
||||||
<string name="settings_popup_caseopen_label">Zobrazit vyskakovací okno</string>
|
<string name="settings_popup_caseopen_label">Zobrazit vyskakovací okno</string>
|
||||||
<string name="settings_popup_caseopen_description">Zobrazit vyskakovací okno, pokud je pouzdro zařízení otevřeno (experimentální).</string>
|
<string name="settings_popup_caseopen_description">Zobrazit vyskakovací okno, pokud je pouzdro zařízení otevřeno (experimentální).</string>
|
||||||
<string name="notification_channel_reaction_popup_label">Vyskakovací okno reakcí zařízení</string>
|
|
||||||
<string name="overview_bluetooth_disabled_label">Bluetooth je vypnuto</string>
|
<string name="overview_bluetooth_disabled_label">Bluetooth je vypnuto</string>
|
||||||
<string name="overview_bluetooth_disabled_description">Bluetooth je vypnuto, zapněte jej ;)</string>
|
<string name="overview_bluetooth_disabled_description">Bluetooth je vypnuto, zapněte jej ;)</string>
|
||||||
<string name="help_translate_label">Překlad</string>
|
<string name="help_translate_label">Překlad</string>
|
||||||
@@ -131,4 +131,7 @@
|
|||||||
<string name="first_seen_x">Poprvé spatřeno: %s</string>
|
<string name="first_seen_x">Poprvé spatřeno: %s</string>
|
||||||
<string name="settings_blescanner_unfiltered_label">Nefiltrovaná data BLE</string>
|
<string name="settings_blescanner_unfiltered_label">Nefiltrovaná data BLE</string>
|
||||||
<string name="settings_blescanner_unfiltered_description">Aby se zobrazovala všechna vysílaná data BLE, odstraňte ze skenování BLE všechny filtry. Užitečné pro přidání podpory nových typů sluchátek.</string>
|
<string name="settings_blescanner_unfiltered_description">Aby se zobrazovala všechna vysílaná data BLE, odstraňte ze skenování BLE všechny filtry. Užitečné pro přidání podpory nových typů sluchátek.</string>
|
||||||
|
<string name="permission_required_title">Je vyžadováno následující oprávnění:</string>
|
||||||
|
<string name="settings_compatibility_mode_label">Režim kompatibility</string>
|
||||||
|
<string name="settings_compatibility_mode_description">Vypnutí optimalizace pro zlepšení kompatibility. Zkuste to, pokud se vám nezobrazují žádná data.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -8,11 +8,10 @@
|
|||||||
<string name="general_share_action">Teilen</string>
|
<string name="general_share_action">Teilen</string>
|
||||||
<string name="general_done_action">Fertig</string>
|
<string name="general_done_action">Fertig</string>
|
||||||
<string name="general_copy_action">Kopieren</string>
|
<string name="general_copy_action">Kopieren</string>
|
||||||
<string name="general_value_unknown_label">Unbekannt</string>
|
|
||||||
<string name="general_thank_you_label">Danke</string>
|
<string name="general_thank_you_label">Danke</string>
|
||||||
<string name="general_value_not_available_label">k.A.</string>
|
<string name="general_value_not_available_label">k.A.</string>
|
||||||
<string name="general_grant_permission_action">Berechtigung erteilen</string>
|
<string name="general_grant_permission_action">Berechtigung erteilen</string>
|
||||||
<string name="general_upgrade_action" comment="general_upgrade_action, Used as label for dialog buttons, i.e. the dialog is about upgrading the app to "Pro" and the positive confirmation button is labeled "Upgrade"">Aktualisierung</string>
|
<string name="general_upgrade_action">Aktualisierung</string>
|
||||||
<string name="general_check_action">Überprüfen</string>
|
<string name="general_check_action">Überprüfen</string>
|
||||||
<string name="general_close_action">Schließen</string>
|
<string name="general_close_action">Schließen</string>
|
||||||
<string name="debug_debuglog_size_label">Größe</string>
|
<string name="debug_debuglog_size_label">Größe</string>
|
||||||
@@ -43,6 +42,7 @@
|
|||||||
<string name="pods_connection_state_call_label">Im Anruf Modus</string>
|
<string name="pods_connection_state_call_label">Im Anruf Modus</string>
|
||||||
<string name="pods_connection_state_ringing_label">Klingelt</string>
|
<string name="pods_connection_state_ringing_label">Klingelt</string>
|
||||||
<string name="pods_connection_state_hanging_up_label">Legt auf</string>
|
<string name="pods_connection_state_hanging_up_label">Legt auf</string>
|
||||||
|
<string name="pods_connection_state_unknown_label">Unbekannter Verbindungsstatus</string>
|
||||||
<string name="pods_unknown_raw_data_label">Rohe Daten</string>
|
<string name="pods_unknown_raw_data_label">Rohe Daten</string>
|
||||||
<string name="pods_unknown_label">Unbekanntes Gerät</string>
|
<string name="pods_unknown_label">Unbekanntes Gerät</string>
|
||||||
<string name="pods_unknown_contact_dev">Dies ist ein unbekanntes Gerät, aber es verwendet ein ähnliches Nachrichtenformat. Lassen Sie uns Unterstützung dafür hinzufügen, kontaktieren Sie mich :)</string>
|
<string name="pods_unknown_contact_dev">Dies ist ein unbekanntes Gerät, aber es verwendet ein ähnliches Nachrichtenformat. Lassen Sie uns Unterstützung dafür hinzufügen, kontaktieren Sie mich :)</string>
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
<string name="pods_microphone_label">Mikrofon</string>
|
<string name="pods_microphone_label">Mikrofon</string>
|
||||||
<string name="pods_yours">Dein</string>
|
<string name="pods_yours">Dein</string>
|
||||||
<string name="headset_being_worn_label">Wird getragen</string>
|
<string name="headset_being_worn_label">Wird getragen</string>
|
||||||
|
<string name="pods_case_unknown_state">Unbekannter Zustand</string>
|
||||||
<string name="overview_nomaindevice_label">Kein primäres Gerät</string>
|
<string name="overview_nomaindevice_label">Kein primäres Gerät</string>
|
||||||
<string name="overview_nomaindevice_description">Alle gefundenen Geräte sind unwahrscheinlich ihnen zu gehören. Verbinden sie ihr Gerät oder passen sie die Einstellungen an.</string>
|
<string name="overview_nomaindevice_description">Alle gefundenen Geräte sind unwahrscheinlich ihnen zu gehören. Verbinden sie ihr Gerät oder passen sie die Einstellungen an.</string>
|
||||||
<string name="settings_label">Einstellungen</string>
|
<string name="settings_label">Einstellungen</string>
|
||||||
@@ -80,7 +81,7 @@
|
|||||||
<string name="settings_monitor_mode_label">Überwachungsmodus</string>
|
<string name="settings_monitor_mode_label">Überwachungsmodus</string>
|
||||||
<string name="settings_monitor_mode_description">Unter welchen Umständen überwacht diese App Bluetooth-Daten.</string>
|
<string name="settings_monitor_mode_description">Unter welchen Umständen überwacht diese App Bluetooth-Daten.</string>
|
||||||
<string name="settings_scanner_mode_label">Scannermodus</string>
|
<string name="settings_scanner_mode_label">Scannermodus</string>
|
||||||
<string name="settings_scanner_mode_description">Soll der Bluetooth Low Energie-Scanner Leistung priorisieren oder Energie sparen?</string>
|
<string name="settings_scanner_mode_description">Soll der Bluetooth Low Energy Datenscanner Leistung priorisieren oder Energie sparen?</string>
|
||||||
<string name="settings_monitor_mode_manual_label">Wenn die App geöffnet ist</string>
|
<string name="settings_monitor_mode_manual_label">Wenn die App geöffnet ist</string>
|
||||||
<string name="settings_monitor_mode_automatic_label">Wenn das Gerät verbunden ist</string>
|
<string name="settings_monitor_mode_automatic_label">Wenn das Gerät verbunden ist</string>
|
||||||
<string name="settings_monitor_mode_always_label">Stets</string>
|
<string name="settings_monitor_mode_always_label">Stets</string>
|
||||||
@@ -88,13 +89,13 @@
|
|||||||
<string name="settings_scanner_mode_balanced_label">Ausgewogen</string>
|
<string name="settings_scanner_mode_balanced_label">Ausgewogen</string>
|
||||||
<string name="settings_scanner_mode_lowlatency_label">Geringe Latenz</string>
|
<string name="settings_scanner_mode_lowlatency_label">Geringe Latenz</string>
|
||||||
<string name="settings_autopause_label">Automatische Pause</string>
|
<string name="settings_autopause_label">Automatische Pause</string>
|
||||||
<string name="settings_autopause_description">Halten Sie die Musik an, wenn Sie das Gerät von Ihrem Ohr entfernen.</string>
|
<string name="settings_autopause_description">Halten Sie den Ton an, wenn Sie das Gerät von Ihrem Ohr entfernen.</string>
|
||||||
<string name="settings_showall_label">Alle Geräte anzeigen</string>
|
<string name="settings_showall_label">Alle Geräte anzeigen</string>
|
||||||
<string name="settings_showall_description">Zeigen Sie die Geräte anderer Personen in Ihrer Nähe an.</string>
|
<string name="settings_showall_description">Zeigen Sie die Geräte anderer Personen in Ihrer Nähe an.</string>
|
||||||
<string name="settings_autopplay_label">Automatisches Abspielen</string>
|
<string name="settings_autopplay_label">Automatisches Abspielen</string>
|
||||||
<string name="settings_autoplay_description">Starten Sie die Musikwiedergabe, wenn Sie das Gerät tragen.</string>
|
<string name="settings_autoplay_description">Starten Sie die Audiowiedergabe, wenn das Gerät getragen wird.</string>
|
||||||
<string name="settings_fake_data_label">Gefälschte Daten</string>
|
<string name="settings_fake_data_label">Gefälschte Daten</string>
|
||||||
<string name="settings_fake_data_description">Gefälschte Daten anzeigen, Geräte simulieren, die nicht existieren.</string>
|
<string name="settings_fake_data_description">Falsche Daten anzeigen, also nicht existierende Geräte simulieren.</string>
|
||||||
<string name="settings_debug_label">Debug-Einstellungen</string>
|
<string name="settings_debug_label">Debug-Einstellungen</string>
|
||||||
<string name="settings_debug_description">Zusätzliche Einstellungen zur Behebung von Problemen mit der App.</string>
|
<string name="settings_debug_description">Zusätzliche Einstellungen zur Behebung von Problemen mit der App.</string>
|
||||||
<string name="settings_signal_minimum_label">Minimale Signalqualität</string>
|
<string name="settings_signal_minimum_label">Minimale Signalqualität</string>
|
||||||
@@ -118,17 +119,19 @@
|
|||||||
<string name="upgrade_capod_description">Erhalten Sie zusätzliche Funktionen und unterstützen Sie den Entwickler.</string>
|
<string name="upgrade_capod_description">Erhalten Sie zusätzliche Funktionen und unterstützen Sie den Entwickler.</string>
|
||||||
<string name="settings_popup_caseopen_label">Popup zeigen</string>
|
<string name="settings_popup_caseopen_label">Popup zeigen</string>
|
||||||
<string name="settings_popup_caseopen_description">Ein Popup anzeigen, wenn das Gerätegehäuse geöffnet wird (experimentell).</string>
|
<string name="settings_popup_caseopen_description">Ein Popup anzeigen, wenn das Gerätegehäuse geöffnet wird (experimentell).</string>
|
||||||
<string name="notification_channel_reaction_popup_label">Popup-Gerätereaktionen</string>
|
|
||||||
<string name="overview_bluetooth_disabled_label">Bluetooth ist deaktiviert</string>
|
<string name="overview_bluetooth_disabled_label">Bluetooth ist deaktiviert</string>
|
||||||
<string name="overview_bluetooth_disabled_description">Bluetooth ist deaktiviert, aktiviere es ;)</string>
|
<string name="overview_bluetooth_disabled_description">Bluetooth ist deaktiviert, aktiviere es ;)</string>
|
||||||
<string name="help_translate_label">Übersetzung</string>
|
<string name="help_translate_label">Übersetzung</string>
|
||||||
<string name="help_translate_description">Helfen Sie mit, dies in Ihre Lieblingssprache zu übersetzen.</string>
|
<string name="help_translate_description">Helfen Sie mit, diese App in Ihre Lieblingssprache zu übersetzen.</string>
|
||||||
<string name="settings_onepod_mode_label">Ein-Pod-Modus</string>
|
<string name="settings_onepod_mode_label">Ein-Pod-Modus</string>
|
||||||
<string name="settings_onepod_mode_description">Das Tragen beider Pods ist nicht erforderlich, das Tragen eines einzigen Pods reicht aus, um Reaktionen auszulösen.</string>
|
<string name="settings_onepod_mode_description">Das Tragen beider Pods ist nicht erforderlich, das Tragen eines einzigen Pods reicht aus, um Reaktionen auszulösen.</string>
|
||||||
<string name="permission_system_alert_window_label">Systemwarnungsfenster</string>
|
<string name="permission_system_alert_window_label">Systemwarnungsfenster</string>
|
||||||
<string name="permission_system_alert_window_description">Erlauben Sie CAPod, über andere Apps zu zeichnen, um die Funktion \"PopUp anzeigen\" zu ermöglichen.</string>
|
<string name="permission_system_alert_window_description">Erlauben Sie CAPod, über andere Apps zu zeichnen, um die Funktion \"PopUp anzeigen\" zu ermöglichen.</string>
|
||||||
<string name="last_seen_x">Zuletzt gesehen</string>
|
<string name="last_seen_x">Zuletzt gesehen: %s</string>
|
||||||
<string name="first_seen_x">Zum ersten Mal gesehen</string>
|
<string name="first_seen_x">Zum ersten Mal gesehen: %s</string>
|
||||||
<string name="settings_blescanner_unfiltered_label">Ungefilterte BLE-Daten</string>
|
<string name="settings_blescanner_unfiltered_label">Ungefilterte BLE-Daten</string>
|
||||||
<string name="settings_blescanner_unfiltered_description">Entfernen Sie alle Filter aus dem BLE-Scanner, um alle übertragenen BLE-Daten anzuzeigen. Nützlich, um Unterstützung für neue Kopfhörertypen hinzuzufügen.</string>
|
<string name="settings_blescanner_unfiltered_description">Entfernen Sie alle Filter aus dem BLE-Scanner, um alle übertragenen BLE-Daten anzuzeigen. Nützlich, um Unterstützung für neue Kopfhörertypen hinzuzufügen.</string>
|
||||||
|
<string name="permission_required_title">Die folgende Genehmigung ist erforderlich:</string>
|
||||||
|
<string name="settings_compatibility_mode_label">Kompatibilitätsmodus</string>
|
||||||
|
<string name="settings_compatibility_mode_description">Deaktivieren Sie Optimierungen, um die Kompatibilität zu verbessern. Versuchen Sie dies, wenn Sie keine Daten sehen.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -8,40 +8,42 @@
|
|||||||
<string name="general_share_action">Κοινοποίηση</string>
|
<string name="general_share_action">Κοινοποίηση</string>
|
||||||
<string name="general_done_action">Τέλος</string>
|
<string name="general_done_action">Τέλος</string>
|
||||||
<string name="general_copy_action">Αντιγραφή</string>
|
<string name="general_copy_action">Αντιγραφή</string>
|
||||||
<string name="general_value_unknown_label">Άγνωστο</string>
|
|
||||||
<string name="general_thank_you_label">Σας ευχαριστώ</string>
|
<string name="general_thank_you_label">Σας ευχαριστώ</string>
|
||||||
<string name="general_value_not_available_label">Μη διαθέσιμο</string>
|
<string name="general_value_not_available_label">Δε διατίθεται</string>
|
||||||
<string name="general_grant_permission_action">Παραχώρηση άδειας</string>
|
<string name="general_grant_permission_action">Παραχώρηση άδειας</string>
|
||||||
<string name="general_upgrade_action" comment="general_upgrade_action, Used as label for dialog buttons, i.e. the dialog is about upgrading the app to "Pro" and the positive confirmation button is labeled "Upgrade"">Αναβάθμιση</string>
|
<string name="general_upgrade_action">Αναβάθμιση</string>
|
||||||
<string name="general_check_action">Έλεγχος</string>
|
<string name="general_check_action">Έλεγχος</string>
|
||||||
<string name="general_close_action">Κλείσιμο</string>
|
<string name="general_close_action">Κλείσιμο</string>
|
||||||
<string name="debug_debuglog_size_label">Μέγεθος</string>
|
<string name="debug_debuglog_size_label">Μέγεθος</string>
|
||||||
<string name="debug_debuglog_size_compressed_label">Συμπιεσμένο μέγεθος</string>
|
<string name="debug_debuglog_size_compressed_label">Συμπιεσμένο μέγεθος</string>
|
||||||
<string name="debug_notification_channel_label">Ειδοποιήσεις εντοπισμού σφαλμάτων</string>
|
<string name="debug_notification_channel_label">Ειδοποιήσεις εντοπισμού σφαλμάτων</string>
|
||||||
|
<string name="debug_debuglog_file_label">Εγγεγραμμένο αρχείο καταγραφής</string>
|
||||||
|
<string name="debug_debuglog_record_action">Εγγραφή καταγραφής εντοπισμού σφαλμάτων</string>
|
||||||
<string name="permission_bluetooth_connect_label">Σύνδεση Bluetooth</string>
|
<string name="permission_bluetooth_connect_label">Σύνδεση Bluetooth</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_label">Σάρωση Bluetooth</string>
|
||||||
<string name="permission_bluetooth_scan_description">Η άδεια \"Σάρωση Bluetooth\" επιτρέπει σε αυτή την εφαρμογή να ανακαλύπτει και να λάβει δεδομένα Bluetooth από κοντινές συσκευές όπως τα AirPods σας.</string>
|
<string name="permission_bluetooth_scan_description">Η άδεια \"Σάρωση Bluetooth\" επιτρέπει σε αυτήν την εφαρμογή να εντοπίζει και να λαμβάνει δεδομένα Bluetooth από κοντινές συσκευές, όπως τα AirPods σας.</string>
|
||||||
<string name="permission_bluetooth_label">Bluetooth</string>
|
<string name="permission_bluetooth_label">Bluetooth</string>
|
||||||
<string name="permission_bluetooth_description">Αυτή η εφαρμογή απαιτεί την άδεια \"Bluetooth\" για να συνδεθεί σε αντιστοιχισμένες συσκευές Bluetooth.</string>
|
<string name="permission_bluetooth_description">Αυτή η εφαρμογή απαιτεί την άδεια \"Bluetooth\" για να συνδέεται σε αντιστοιχισμένες συσκευές Bluetooth.</string>
|
||||||
<string name="permission_access_fine_location_label">Πρόσβαση ακριβείς τοποθεσίας</string>
|
<string name="permission_access_fine_location_label">Πρόσβαση ακριβούς τοποθεσίας</string>
|
||||||
<string name="permission_access_fine_location_description">Το CAPod χρησιμοποιεί την άδεια \"Ακριβής τοποθεσία\" για να λαμβάνει δεδομένα χαμηλής ενέργειας Bluetooth. Τα ακουστικά σας χρησιμοποιούν τεχνολογία χαμηλής ενέργειας Bluetooth για να μεταδίδουν την κατάστασή τους. Αυτή η εφαρμογή ΔΕΝ θα χρησιμοποιεί δεδομένα Bluetooth για να προσδιορίσει την τοποθεσία σας.</string>
|
<string name="permission_access_fine_location_description">Το CAPod χρησιμοποιεί την άδεια \"Ακριβής τοποθεσία\" για να λαμβάνει δεδομένα χαμηλής ενέργειας Bluetooth. Τα ακουστικά σας χρησιμοποιούν τεχνολογία χαμηλής ενέργειας Bluetooth για να μεταδίδουν την κατάστασή τους. Αυτή η εφαρμογή ΔΕΝ θα χρησιμοποιεί δεδομένα Bluetooth για να προσδιορίσει την τοποθεσία σας.</string>
|
||||||
<string name="permission_background_location_label">Πρόσβαση τοποθεσίας παρασκηνίου</string>
|
<string name="permission_background_location_label">Πρόσβαση τοποθεσίας στο παρασκήνιο</string>
|
||||||
<string name="permission_background_location_description">Το CAPod χρησιμοποιεί \"Πρόσβαση τοποθεσίας στο παρασκήνιο\" για να ενεργοποιεί λειτουργίες όπως \"Εμφάνιση αναδυόμενου\" και \"Αυτόματη σύνδεση\" ενώ η εφαρμογή είναι κλειστή. Η πρόσβαση τοποθεσίας στο παρασκήνιο επιτρέπει στην εφαρμογή να λαμβάνει δεδομένα χαμηλής ενέργειας Bluetooth ενώ βρίσκεται στο παρασκήνιο. Αυτή η εφαρμογή ΔΕΝ θα χρησιμοποιεί δεδομένα Bluetooth για τον προσδιορισμό της τοποθεσία σας.</string>
|
<string name="permission_background_location_description">Το CAPod χρησιμοποιεί \"Πρόσβαση τοποθεσίας στο παρασκήνιο\" για να ενεργοποιεί λειτουργίες όπως \"Εμφάνιση αναδυόμενου\" και \"Αυτόματη σύνδεση\" ενώ η εφαρμογή είναι κλειστή. Η πρόσβαση τοποθεσίας στο παρασκήνιο επιτρέπει στην εφαρμογή να λαμβάνει δεδομένα χαμηλής ενέργειας Bluetooth ενώ βρίσκεται στο παρασκήνιο. Αυτή η εφαρμογή ΔΕΝ θα χρησιμοποιεί δεδομένα Bluetooth για τον προσδιορισμό της τοποθεσία σας.</string>
|
||||||
<string name="permission_ignore_battery_optimizations_label">Απενεργοποίηση βελτιστοποιήσεων μπαταρίας</string>
|
<string name="permission_ignore_battery_optimizations_label">Απενεργοποίηση βελτιστοποιήσεων μπαταρίας</string>
|
||||||
<string name="permission_ignore_battery_optimizations_description">Οι βελτιστοποιήσεις μπαταρίας εμποδίζουν αυτή την εφαρμογή να λαμβάνει αξιόπιστα δεδομένα Bluetooth ενώ η εφαρμογή βρίσκεται στο παρασκήνιο.</string>
|
<string name="permission_ignore_battery_optimizations_description">Οι βελτιστοποιήσεις μπαταρίας εμποδίζουν αυτήν την εφαρμογή να λαμβάνει αξιόπιστα δεδομένα Bluetooth ενώ η εφαρμογή βρίσκεται στο παρασκήνιο.</string>
|
||||||
<string name="pods_dual_left_label">Αριστερό pod</string>
|
<string name="pods_dual_left_label">Αριστερό pod</string>
|
||||||
<string name="pods_dual_right_label">Δεξιό pod</string>
|
<string name="pods_dual_right_label">Δεξί pod</string>
|
||||||
<string name="pods_case_label">Θήκη</string>
|
<string name="pods_case_label">Θήκη</string>
|
||||||
<string name="pods_case_status_open_label">Ανοιχτή</string>
|
<string name="pods_case_status_open_label">Ανοιχτή</string>
|
||||||
<string name="pods_case_status_closed_label">Κλειστή</string>
|
<string name="pods_case_status_closed_label">Κλειστή</string>
|
||||||
<string name="pods_connection_state_disconnected_label">Μη συνδεδεμένο σε κάποια συσκευή</string>
|
<string name="pods_connection_state_disconnected_label">Δεν είναι συνδεδεμένο σε συσκευή</string>
|
||||||
<string name="pods_connection_state_idle_label">Συνδεδεμένο σε κάποια συσκευή, αλλά αδρανές</string>
|
<string name="pods_connection_state_idle_label">Συνδεδεμένο σε συσκευή, αλλά αδρανές</string>
|
||||||
<string name="pods_connection_state_music_label">Σε λειτουργία μουσικής</string>
|
<string name="pods_connection_state_music_label">Σε λειτουργία μουσικής</string>
|
||||||
<string name="pods_connection_state_call_label">Σε λειτουργία κλήσης</string>
|
<string name="pods_connection_state_call_label">Σε λειτουργία κλήσης</string>
|
||||||
<string name="pods_connection_state_ringing_label">Κουδούνισμα</string>
|
<string name="pods_connection_state_ringing_label">Κουδούνισμα</string>
|
||||||
<string name="pods_connection_state_hanging_up_label">Κλείσιμο</string>
|
<string name="pods_connection_state_hanging_up_label">Τερματισμός κλήσης</string>
|
||||||
<string name="pods_unknown_raw_data_label">Δεδομένα raw</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_label">Άγνωστη συσκευή</string>
|
||||||
<string name="pods_unknown_contact_dev">Αυτή είναι μια άγνωστη συσκευή, αλλά χρησιμοποιεί παρόμοια μορφή μηνυμάτων. Ας προσθέσουμε υποστήριξη για αυτήν, επικοινωνήστε μαζί μου :)</string>
|
<string name="pods_unknown_contact_dev">Αυτή είναι μια άγνωστη συσκευή, αλλά χρησιμοποιεί παρόμοια μορφή μηνυμάτων. Ας προσθέσουμε υποστήριξη για αυτήν, επικοινωνήστε μαζί μου :)</string>
|
||||||
<string name="pods_none_label_short">Καμία συσκευή</string>
|
<string name="pods_none_label_short">Καμία συσκευή</string>
|
||||||
@@ -50,6 +52,7 @@
|
|||||||
<string name="pods_microphone_label">Μικρόφωνο</string>
|
<string name="pods_microphone_label">Μικρόφωνο</string>
|
||||||
<string name="pods_yours">Δικό σας</string>
|
<string name="pods_yours">Δικό σας</string>
|
||||||
<string name="headset_being_worn_label">Φοριέται</string>
|
<string name="headset_being_worn_label">Φοριέται</string>
|
||||||
|
<string name="pods_case_unknown_state">Άγνωστη κατάσταση</string>
|
||||||
<string name="overview_nomaindevice_label">Καμία κύρια συσκευή</string>
|
<string name="overview_nomaindevice_label">Καμία κύρια συσκευή</string>
|
||||||
<string name="overview_nomaindevice_description">Όλες οι συσκευές που εντοπίστηκαν είναι απίθανο να είναι δικές σας. Ενεργοποιήστε και συνδέστε τη συσκευή σας ή προσαρμόστε τις ρυθμίσεις.</string>
|
<string name="overview_nomaindevice_description">Όλες οι συσκευές που εντοπίστηκαν είναι απίθανο να είναι δικές σας. Ενεργοποιήστε και συνδέστε τη συσκευή σας ή προσαρμόστε τις ρυθμίσεις.</string>
|
||||||
<string name="settings_label">Ρυθμίσεις</string>
|
<string name="settings_label">Ρυθμίσεις</string>
|
||||||
@@ -62,37 +65,37 @@
|
|||||||
<string name="settings_acknowledgements_label">Ευχαριστίες</string>
|
<string name="settings_acknowledgements_label">Ευχαριστίες</string>
|
||||||
<string name="changelog_label">Αρχείο αλλαγών</string>
|
<string name="changelog_label">Αρχείο αλλαγών</string>
|
||||||
<string name="settings_support_email_developer_label">Email στον προγραμματιστή</string>
|
<string name="settings_support_email_developer_label">Email στον προγραμματιστή</string>
|
||||||
<string name="settings_support_installid_label">ID εγκατάστασης</string>
|
<string name="settings_support_installid_label">Αναγνωριστικό εγκατάστασης</string>
|
||||||
<string name="settings_support_installid_desc">Οι αυτόματες αναφορές σφαλμάτων είναι ανώνυμες. Κοινοποιήστε την ID εγκατάστασης αν ο προγραμματιστής χρειαστεί να βρει τις αναφορές σφαλμάτων σας.</string>
|
<string name="settings_support_installid_desc">Οι αυτόματες αναφορές σφαλμάτων είναι ανώνυμες. Κοινοποιήστε το αναγνωριστικό εγκατάστασης εάν ο προγραμματιστής πρέπει να βρει τις αναφορές σας σφαλμάτων.</string>
|
||||||
<string name="settings_support_label">Υποστήριξη</string>
|
<string name="settings_support_label">Υποστήριξη</string>
|
||||||
<string name="settings_support_description">Εάν χρειάζεστε κάποια βοήθεια.</string>
|
<string name="settings_support_description">Εάν χρειάζεστε κάποια βοήθεια.</string>
|
||||||
<string name="issue_tracker_label">Εντοπισμός προβλημάτων</string>
|
<string name="issue_tracker_label">Εργαλείο παρακολούθησης θεμάτων</string>
|
||||||
<string name="issue_tracker_description">Ένας δημόσιος εντοπισμός προβλημάτων για αναφορές σφαλμάτων και αιτήματα λειτουργιών (μόνο αγγλικά).</string>
|
<string name="issue_tracker_description">Δημόσιο εργαλείο παρακολούθησης θεμάτων για αναφορές σφαλμάτων και αιτήματα για δυνατότητες (μόνο αγγλικά).</string>
|
||||||
<string name="discord_label">Discord</string>
|
<string name="discord_label">Discord</string>
|
||||||
<string name="discord_description">Ένα μέρος για να αράξετε και να κάνετε ερωτήσεις.</string>
|
<string name="discord_description">Ένα μέρος για να αράξετε και να κάνετε ερωτήσεις.</string>
|
||||||
<string name="settings_support_email_developer_description">Σημειώστε ότι μπορώ να απαντήσω μόνο στα γερμανικά ή στα αγγλικά.</string>
|
<string name="settings_support_email_developer_description">Σημειώστε ότι μπορώ να απαντήσω μόνο στα γερμανικά ή στα αγγλικά.</string>
|
||||||
<string name="settings_debug_autoreports_label">Αυτόματες αναφορές σφαλμάτων</string>
|
<string name="settings_debug_autoreports_label">Αυτόματες αναφορές σφαλμάτων</string>
|
||||||
<string name="settings_debug_autoreports_description">Αναφέρει προβλήματα αυτόματα, π.χ. λεπτομέρειες σχετικά με μια αιφνίδια διακοπή λειτουργίας της εφαρμογής, ώστε να μπορώ να καταλάβω πώς να το διορθώσω.</string>
|
<string name="settings_debug_autoreports_description">Αυτόματες αναφορές προβλημάτων, π.χ. πληροφορίες για αιφνίδια διακοπή λειτουργίας της εφαρμογής, ώστε να μπορώ να καταλάβω πώς να το διορθώσω.</string>
|
||||||
<string name="settings_debug_mode_label">Λειτουργία εντοπισμού σφαλμάτων</string>
|
<string name="settings_debug_mode_label">Λειτουργία εντοπισμού σφαλμάτων</string>
|
||||||
<string name="settings_debug_mode_description">Εμφάνιση επιπλέον πληροφοριών για την αντιμετώπιση προβλημάτων.</string>
|
<string name="settings_debug_mode_description">Εμφάνιση επιπλέον πληροφοριών για την αντιμετώπιση προβλημάτων.</string>
|
||||||
<string name="settings_monitor_mode_label">Λειτουργία παρακολούθησης</string>
|
<string name="settings_monitor_mode_label">Λειτουργία παρακολούθησης</string>
|
||||||
<string name="settings_monitor_mode_description">Κάτω από ποιες συνθήκες αυτή η εφαρμογή παρακολουθεί τα δεδομένα Bluetooth.</string>
|
<string name="settings_monitor_mode_description">Κάτω από ποιες συνθήκες αυτή η εφαρμογή παρακολουθεί τα δεδομένα Bluetooth.</string>
|
||||||
<string name="settings_scanner_mode_label">Λειτουργία σάρωσης</string>
|
<string name="settings_scanner_mode_label">Λειτουργία σάρωσης</string>
|
||||||
<string name="settings_scanner_mode_description">Ο σαρωτής Bluetooth Low Energy να δώσει προτεραιότητα στην απόδοση ή στη διατήρηση ενέργειας;</string>
|
<string name="settings_scanner_mode_description">Θα πρέπει η σάρωση δεδομένων χαμηλής ενέργειας Bluetooth να δίνει προτεραιότητα στην απόδοση ή να εξοικονομεί ενέργεια;</string>
|
||||||
<string name="settings_monitor_mode_manual_label">Όταν η εφαρμογή είναι ανοιχτή</string>
|
<string name="settings_monitor_mode_manual_label">Όταν η εφαρμογή είναι ανοιχτή</string>
|
||||||
<string name="settings_monitor_mode_automatic_label">Όταν η συσκευή είναι συνδεδεμένη</string>
|
<string name="settings_monitor_mode_automatic_label">Όταν η συσκευή είναι συνδεδεμένη</string>
|
||||||
<string name="settings_monitor_mode_always_label">Πάντα</string>
|
<string name="settings_monitor_mode_always_label">Πάντα</string>
|
||||||
<string name="settings_scanner_mode_lowpower_label">Χαμηλή ισχύς</string>
|
<string name="settings_scanner_mode_lowpower_label">Χαμηλή ισχύς</string>
|
||||||
<string name="settings_scanner_mode_balanced_label">Ισορροπημένο</string>
|
<string name="settings_scanner_mode_balanced_label">Εξισορρόπηση</string>
|
||||||
<string name="settings_scanner_mode_lowlatency_label">Χαμηλή καθυστέρηση</string>
|
<string name="settings_scanner_mode_lowlatency_label">Χαμηλή καθυστέρηση</string>
|
||||||
<string name="settings_autopause_label">Αυτόματη παύση</string>
|
<string name="settings_autopause_label">Αυτόματη παύση</string>
|
||||||
<string name="settings_autopause_description">Παύση μουσικής όταν αφαιρείται τη συσκευή από το αυτί σας.</string>
|
<string name="settings_autopause_description">Παύση ήχου όταν αφαιρείται τη συσκευή από το αυτί σας.</string>
|
||||||
<string name="settings_showall_label">Εμφάνιση όλων των συσκευών</string>
|
<string name="settings_showall_label">Εμφάνιση όλων των συσκευών</string>
|
||||||
<string name="settings_showall_description">Εμφάνιση συσκευών άλλων ανθρώπων που είναι κοντά σας.</string>
|
<string name="settings_showall_description">Εμφάνιση συσκευών άλλων ανθρώπων που είναι κοντά σας.</string>
|
||||||
<string name="settings_autopplay_label">Αυτόματη αναπαραγωγή</string>
|
<string name="settings_autopplay_label">Αυτόματη αναπαραγωγή</string>
|
||||||
<string name="settings_autoplay_description">Αναπαραγωγή μουσικής όταν φοριέται η συσκευή.</string>
|
<string name="settings_autoplay_description">Έναρξη αναπαραγωγής ήχου όταν φορεθεί η συσκευή.</string>
|
||||||
<string name="settings_fake_data_label">Ψευδή δεδομένα</string>
|
<string name="settings_fake_data_label">Ψευδή δεδομένα</string>
|
||||||
<string name="settings_fake_data_description">Εμφάνιση ψευδών δεδομένων, π.χ. προσομοίωση συσκευής που δεν υπάρχει.</string>
|
<string name="settings_fake_data_description">Εμφάνιση ψευδών δεδομένων, π.χ., προσομοίωση συσκευών που δεν υπάρχουν.</string>
|
||||||
<string name="settings_debug_label">Ρυθμίσεις αντιμετώπισης σφαλμάτων</string>
|
<string name="settings_debug_label">Ρυθμίσεις αντιμετώπισης σφαλμάτων</string>
|
||||||
<string name="settings_debug_description">Πρόσθετες ρυθμίσεις που βοηθούν στην αντιμετώπιση προβλημάτων με την εφαρμογή.</string>
|
<string name="settings_debug_description">Πρόσθετες ρυθμίσεις που βοηθούν στην αντιμετώπιση προβλημάτων με την εφαρμογή.</string>
|
||||||
<string name="settings_signal_minimum_label">Ελάχιστη ποιότητα σήματος</string>
|
<string name="settings_signal_minimum_label">Ελάχιστη ποιότητα σήματος</string>
|
||||||
@@ -105,7 +108,7 @@
|
|||||||
<string name="settings_reaction_description">Αντίδραση σε συμβάντα και συμπεριφορές.</string>
|
<string name="settings_reaction_description">Αντίδραση σε συμβάντα και συμπεριφορές.</string>
|
||||||
<string name="settings_category_yourdevice_label">Η συσκευή σας</string>
|
<string name="settings_category_yourdevice_label">Η συσκευή σας</string>
|
||||||
<string name="settings_maindevice_address_label">Διεύθυνση της συσκευής σας</string>
|
<string name="settings_maindevice_address_label">Διεύθυνση της συσκευής σας</string>
|
||||||
<string name="settings_maindevice_address_description">Η διεύθυνση της συζευγμένης συσκευής σας. Η εφαρμογή τη χρησιμοποιεί για να προσδιορίσει αν η συσκευή σας είναι συνδεδεμένη στο τηλέφωνό σας.</string>
|
<string name="settings_maindevice_address_description">Η διεύθυνση της αντιστοιχισμένης συσκευής σας. Η εφαρμογή τη χρησιμοποιεί για να προσδιορίσει εάν η συσκευή σας είναι συνδεδεμένη στο τηλέφωνό σας.</string>
|
||||||
<string name="settings_maindevice_address_none">Καμία</string>
|
<string name="settings_maindevice_address_none">Καμία</string>
|
||||||
<string name="settings_maindevice_model_label">Μοντέλο της συσκευής σας</string>
|
<string name="settings_maindevice_model_label">Μοντέλο της συσκευής σας</string>
|
||||||
<string name="settings_maindevice_model_description">Το μοντέλο της κύριας συσκευής σας. Αυτό βοηθά την εφαρμογή να αναγνωρίσει τη συσκευή σας όταν δεν είναι συνδεδεμένη στο τηλέφωνό σας.</string>
|
<string name="settings_maindevice_model_description">Το μοντέλο της κύριας συσκευής σας. Αυτό βοηθά την εφαρμογή να αναγνωρίσει τη συσκευή σας όταν δεν είναι συνδεδεμένη στο τηλέφωνό σας.</string>
|
||||||
@@ -119,8 +122,16 @@
|
|||||||
<string name="overview_bluetooth_disabled_label">Το Bluetooth είναι απενεργοποιημένο</string>
|
<string name="overview_bluetooth_disabled_label">Το Bluetooth είναι απενεργοποιημένο</string>
|
||||||
<string name="overview_bluetooth_disabled_description">Το Bluetooth είναι απενεργοποιημένο, ενεργοποιήστε το ;)</string>
|
<string name="overview_bluetooth_disabled_description">Το Bluetooth είναι απενεργοποιημένο, ενεργοποιήστε το ;)</string>
|
||||||
<string name="help_translate_label">Μετάφραση</string>
|
<string name="help_translate_label">Μετάφραση</string>
|
||||||
<string name="help_translate_description">Βοηθήστε να μεταφραστεί αυτό στην αγαπημένη σας γλώσσα.</string>
|
<string name="help_translate_description">Βοηθήστε να μεταφραστεί αυτή η εφαρμογή στην αγαπημένη σας γλώσσα.</string>
|
||||||
<string name="settings_onepod_mode_label">Λειτουργία ενός pod</string>
|
<string name="settings_onepod_mode_label">Λειτουργία ενός pod</string>
|
||||||
|
<string name="settings_onepod_mode_description">Δεν απαιτείται να φοράτε και τα δύο pods, αρκεί να φοράτε ένα μόνο pod για να ενεργοποιούνται αντιδράσεις.</string>
|
||||||
|
<string name="permission_system_alert_window_label">Παράθυρο ειδοποίησης συστήματος</string>
|
||||||
|
<string name="permission_system_alert_window_description">Επιτρέψτε στο CAPod να εμφανίζεται πάνω από άλλες εφαρμογές για να είναι δυνατή η λειτουργία \"Εμφάνιση αναδυόμενου\".</string>
|
||||||
|
<string name="last_seen_x">Τελευταία εμφάνιση: %s</string>
|
||||||
<string name="first_seen_x">Πρώτη εμφάνιση: %s</string>
|
<string name="first_seen_x">Πρώτη εμφάνιση: %s</string>
|
||||||
<string name="settings_blescanner_unfiltered_label">Μη φιλτραρισμένα δεδομένα BLE</string>
|
<string name="settings_blescanner_unfiltered_label">Μη φιλτραρισμένα δεδομένα BLE</string>
|
||||||
|
<string name="settings_blescanner_unfiltered_description">Αφαιρέστε τυχόν φίλτρα από τη σάρωση BLE για να εμφανίσετε όλα τα δεδομένα BLE που μεταδίδονται. Χρήσιμο για την προσθήκη υποστήριξης για νέους τύπους ακουστικών.</string>
|
||||||
|
<string name="permission_required_title">Η ακόλουθη άδεια είναι απαραίτητη:</string>
|
||||||
|
<string name="settings_compatibility_mode_label">Λειτουργία συμβατότητας</string>
|
||||||
|
<string name="settings_compatibility_mode_description">Απενεργοποίηση βελτιστοποιήσεων για βελτίωση συμβατότητας. Δοκιμάστε αυτό εάν δε βλέπετε δεδομένα.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -8,11 +8,10 @@
|
|||||||
<string name="general_share_action">Compartir</string>
|
<string name="general_share_action">Compartir</string>
|
||||||
<string name="general_done_action">Hecho</string>
|
<string name="general_done_action">Hecho</string>
|
||||||
<string name="general_copy_action">Copiar</string>
|
<string name="general_copy_action">Copiar</string>
|
||||||
<string name="general_value_unknown_label">Desconocido</string>
|
|
||||||
<string name="general_thank_you_label">Gracias</string>
|
<string name="general_thank_you_label">Gracias</string>
|
||||||
<string name="general_value_not_available_label">N/A</string>
|
<string name="general_value_not_available_label">N/A</string>
|
||||||
<string name="general_grant_permission_action">Conceder permiso</string>
|
<string name="general_grant_permission_action">Conceder permiso</string>
|
||||||
<string name="general_upgrade_action" comment="general_upgrade_action, Used as label for dialog buttons, i.e. the dialog is about upgrading the app to "Pro" and the positive confirmation button is labeled "Upgrade"">Mejorar</string>
|
<string name="general_upgrade_action">Mejorar</string>
|
||||||
<string name="general_check_action">Verificar</string>
|
<string name="general_check_action">Verificar</string>
|
||||||
<string name="general_close_action">Cerrar</string>
|
<string name="general_close_action">Cerrar</string>
|
||||||
<string name="debug_debuglog_size_label">Tamaño</string>
|
<string name="debug_debuglog_size_label">Tamaño</string>
|
||||||
|
|||||||
@@ -8,11 +8,10 @@
|
|||||||
<string name="general_share_action">Compartir</string>
|
<string name="general_share_action">Compartir</string>
|
||||||
<string name="general_done_action">Hecho</string>
|
<string name="general_done_action">Hecho</string>
|
||||||
<string name="general_copy_action">Copiar</string>
|
<string name="general_copy_action">Copiar</string>
|
||||||
<string name="general_value_unknown_label">Desconocido</string>
|
|
||||||
<string name="general_thank_you_label">Gracias</string>
|
<string name="general_thank_you_label">Gracias</string>
|
||||||
<string name="general_value_not_available_label">N/D</string>
|
<string name="general_value_not_available_label">N/D</string>
|
||||||
<string name="general_grant_permission_action">Conceder permiso</string>
|
<string name="general_grant_permission_action">Conceder permiso</string>
|
||||||
<string name="general_upgrade_action" comment="general_upgrade_action, Used as label for dialog buttons, i.e. the dialog is about upgrading the app to "Pro" and the positive confirmation button is labeled "Upgrade"">Actualizar</string>
|
<string name="general_upgrade_action">Actualizar</string>
|
||||||
<string name="general_check_action">Verificar</string>
|
<string name="general_check_action">Verificar</string>
|
||||||
<string name="general_close_action">Cerrar</string>
|
<string name="general_close_action">Cerrar</string>
|
||||||
<string name="debug_debuglog_size_label">Tamaño</string>
|
<string name="debug_debuglog_size_label">Tamaño</string>
|
||||||
@@ -20,8 +19,8 @@
|
|||||||
<string name="debug_notification_channel_label">Notificaciones depuradas</string>
|
<string name="debug_notification_channel_label">Notificaciones depuradas</string>
|
||||||
<string name="debug_debuglog_file_label">Registro guardado</string>
|
<string name="debug_debuglog_file_label">Registro guardado</string>
|
||||||
<string name="debug_debuglog_record_action">Grabar registro de depuracion</string>
|
<string name="debug_debuglog_record_action">Grabar registro de depuracion</string>
|
||||||
<string name="permission_bluetooth_connect_label">Conexion Bluetooth</string>
|
<string name="permission_bluetooth_connect_label">Conexión Bluetooth</string>
|
||||||
<string name="permission_bluetooth_connect_description">Esta aplicacion requiere el permiso \"conexion Bluetooth\" para interactuar con los dispositivos pareados, e iniciar las conexiones.</string>
|
<string name="permission_bluetooth_connect_description">Esta aplicación requiere el permiso \"conexión Bluetooth\" para interactuar con los dispositivos pareados, e iniciar las conexiones.</string>
|
||||||
<string name="permission_bluetooth_scan_label">Buscando Bluetooth</string>
|
<string name="permission_bluetooth_scan_label">Buscando Bluetooth</string>
|
||||||
<string name="permission_bluetooth_scan_description">El permiso \"Escaneo Bluetooth\" permite que esta aplicación descubra y reciba datos de Bluetooth de dispositivos cercanos, como sus AirPods.</string>
|
<string name="permission_bluetooth_scan_description">El permiso \"Escaneo Bluetooth\" permite que esta aplicación descubra y reciba datos de Bluetooth de dispositivos cercanos, como sus AirPods.</string>
|
||||||
<string name="permission_bluetooth_label">Bluetooth</string>
|
<string name="permission_bluetooth_label">Bluetooth</string>
|
||||||
@@ -43,6 +42,7 @@
|
|||||||
<string name="pods_connection_state_call_label">En modo llamada</string>
|
<string name="pods_connection_state_call_label">En modo llamada</string>
|
||||||
<string name="pods_connection_state_ringing_label">Sonando</string>
|
<string name="pods_connection_state_ringing_label">Sonando</string>
|
||||||
<string name="pods_connection_state_hanging_up_label">Colgar</string>
|
<string name="pods_connection_state_hanging_up_label">Colgar</string>
|
||||||
|
<string name="pods_connection_state_unknown_label">Estado de la conexion desconocido</string>
|
||||||
<string name="pods_unknown_raw_data_label">Datos sin procesar</string>
|
<string name="pods_unknown_raw_data_label">Datos sin procesar</string>
|
||||||
<string name="pods_unknown_label">Dispositivo desconocido</string>
|
<string name="pods_unknown_label">Dispositivo desconocido</string>
|
||||||
<string name="pods_unknown_contact_dev">Este es un dispositivo desconocido, pero está usando un formato de mensaje similar. Agreguemos soporte para ello, contácteme :)</string>
|
<string name="pods_unknown_contact_dev">Este es un dispositivo desconocido, pero está usando un formato de mensaje similar. Agreguemos soporte para ello, contácteme :)</string>
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
<string name="pods_microphone_label">Micrófono</string>
|
<string name="pods_microphone_label">Micrófono</string>
|
||||||
<string name="pods_yours">Tuyos</string>
|
<string name="pods_yours">Tuyos</string>
|
||||||
<string name="headset_being_worn_label">En uso</string>
|
<string name="headset_being_worn_label">En uso</string>
|
||||||
|
<string name="pods_case_unknown_state">Estado desconocido</string>
|
||||||
<string name="overview_nomaindevice_label">Ningún dispositivo principal</string>
|
<string name="overview_nomaindevice_label">Ningún dispositivo principal</string>
|
||||||
<string name="overview_nomaindevice_description">Es poco probable que todos los dispositivos detectados sean suyos. Encienda y conecte su dispositivo o ajuste la configuración.</string>
|
<string name="overview_nomaindevice_description">Es poco probable que todos los dispositivos detectados sean suyos. Encienda y conecte su dispositivo o ajuste la configuración.</string>
|
||||||
<string name="settings_label">Ajustes</string>
|
<string name="settings_label">Ajustes</string>
|
||||||
@@ -80,7 +81,7 @@
|
|||||||
<string name="settings_monitor_mode_label">Modo monitor</string>
|
<string name="settings_monitor_mode_label">Modo monitor</string>
|
||||||
<string name="settings_monitor_mode_description">Bajo qué circunstancias esta aplicación monitorea los datos Bluetooth.</string>
|
<string name="settings_monitor_mode_description">Bajo qué circunstancias esta aplicación monitorea los datos Bluetooth.</string>
|
||||||
<string name="settings_scanner_mode_label">Modo escáner</string>
|
<string name="settings_scanner_mode_label">Modo escáner</string>
|
||||||
<string name="settings_scanner_mode_description">¿El escáner Bluetooth Low Energy debe priorizar el rendimiento o ahorrar energía?</string>
|
<string name="settings_scanner_mode_description">¿El escáner de datos Bluetooth Low Energy debe priorizar el rendimiento o ahorrar energía?</string>
|
||||||
<string name="settings_monitor_mode_manual_label">Cuando la aplicación está abierta</string>
|
<string name="settings_monitor_mode_manual_label">Cuando la aplicación está abierta</string>
|
||||||
<string name="settings_monitor_mode_automatic_label">Cuando el dispositivo está conectado</string>
|
<string name="settings_monitor_mode_automatic_label">Cuando el dispositivo está conectado</string>
|
||||||
<string name="settings_monitor_mode_always_label">Siempre</string>
|
<string name="settings_monitor_mode_always_label">Siempre</string>
|
||||||
@@ -88,11 +89,11 @@
|
|||||||
<string name="settings_scanner_mode_balanced_label">Balanceado</string>
|
<string name="settings_scanner_mode_balanced_label">Balanceado</string>
|
||||||
<string name="settings_scanner_mode_lowlatency_label">Baja latencia</string>
|
<string name="settings_scanner_mode_lowlatency_label">Baja latencia</string>
|
||||||
<string name="settings_autopause_label">Pausar automáticamente</string>
|
<string name="settings_autopause_label">Pausar automáticamente</string>
|
||||||
<string name="settings_autopause_description">Pausa la música cuando se quites el dispositivo de la oreja.</string>
|
<string name="settings_autopause_description">Pausa el audio cuando te quites el dispositivo de la oreja.</string>
|
||||||
<string name="settings_showall_label">Mostrar todos los dispositivos</string>
|
<string name="settings_showall_label">Mostrar todos los dispositivos</string>
|
||||||
<string name="settings_showall_description">Muestra los dispositivos de otras personas que están cerca de ti.</string>
|
<string name="settings_showall_description">Muestra los dispositivos de otras personas que están cerca de ti.</string>
|
||||||
<string name="settings_autopplay_label">Reproducción automática</string>
|
<string name="settings_autopplay_label">Reproducción automática</string>
|
||||||
<string name="settings_autoplay_description">Iniciar la reproducción de música cuando use el dispositivo.</string>
|
<string name="settings_autoplay_description">Inicia la reproducción de audio cuando se use el dispositivo.</string>
|
||||||
<string name="settings_fake_data_label">Información falsa</string>
|
<string name="settings_fake_data_label">Información falsa</string>
|
||||||
<string name="settings_fake_data_description">Mostrar datos falsos. Por ejemplo: simular un dispositivo que no existe.</string>
|
<string name="settings_fake_data_description">Mostrar datos falsos. Por ejemplo: simular un dispositivo que no existe.</string>
|
||||||
<string name="settings_debug_label">Configuración de depuración</string>
|
<string name="settings_debug_label">Configuración de depuración</string>
|
||||||
@@ -118,11 +119,10 @@
|
|||||||
<string name="upgrade_capod_description">Obtenga funciones adicionales y apoye al desarrollador.</string>
|
<string name="upgrade_capod_description">Obtenga funciones adicionales y apoye al desarrollador.</string>
|
||||||
<string name="settings_popup_caseopen_label">Mostrar ventanas emergentes</string>
|
<string name="settings_popup_caseopen_label">Mostrar ventanas emergentes</string>
|
||||||
<string name="settings_popup_caseopen_description">Muestra una ventana emergente cuando se abre el estuche del dispositivo (experimental).</string>
|
<string name="settings_popup_caseopen_description">Muestra una ventana emergente cuando se abre el estuche del dispositivo (experimental).</string>
|
||||||
<string name="notification_channel_reaction_popup_label">Reacciones emergentes de dispositivos</string>
|
|
||||||
<string name="overview_bluetooth_disabled_label">Bluetooth deshabilitado</string>
|
<string name="overview_bluetooth_disabled_label">Bluetooth deshabilitado</string>
|
||||||
<string name="overview_bluetooth_disabled_description">El Bluetooth está deshabilitado, habilítelo ;)</string>
|
<string name="overview_bluetooth_disabled_description">El Bluetooth está deshabilitado, habilítelo ;)</string>
|
||||||
<string name="help_translate_label">Traducción</string>
|
<string name="help_translate_label">Traducción</string>
|
||||||
<string name="help_translate_description">Ayude a traducir esta aplicación a su idioma favorito.</string>
|
<string name="help_translate_description">Ayuda a traducir esta aplicación a tu idioma favorito.</string>
|
||||||
<string name="settings_onepod_mode_label">Modo un audífono</string>
|
<string name="settings_onepod_mode_label">Modo un audífono</string>
|
||||||
<string name="settings_onepod_mode_description">No es necesario usar ambos AirPods, usar un solo AirPod es suficiente para desencadenar reacciones.</string>
|
<string name="settings_onepod_mode_description">No es necesario usar ambos AirPods, usar un solo AirPod es suficiente para desencadenar reacciones.</string>
|
||||||
<string name="permission_system_alert_window_label">Ventana de alerta del sistema</string>
|
<string name="permission_system_alert_window_label">Ventana de alerta del sistema</string>
|
||||||
@@ -131,4 +131,7 @@
|
|||||||
<string name="first_seen_x">Visto por primera vez: %s</string>
|
<string name="first_seen_x">Visto por primera vez: %s</string>
|
||||||
<string name="settings_blescanner_unfiltered_label">Datos BLE sin filtrar</string>
|
<string name="settings_blescanner_unfiltered_label">Datos BLE sin filtrar</string>
|
||||||
<string name="settings_blescanner_unfiltered_description">Elimina los filtros del escáner BLE para mostrar todos los datos BLE transmitidos. Útil para agregar soporte para nuevos tipos de auriculares.</string>
|
<string name="settings_blescanner_unfiltered_description">Elimina los filtros del escáner BLE para mostrar todos los datos BLE transmitidos. Útil para agregar soporte para nuevos tipos de auriculares.</string>
|
||||||
|
<string name="permission_required_title">Se requiere el siguiente permiso:</string>
|
||||||
|
<string name="settings_compatibility_mode_label">Modo de compatibilidad</string>
|
||||||
|
<string name="settings_compatibility_mode_description">Deshabilita las optimizaciones para mejorar la compatibilidad. Prueba esto si no ves ningún dato.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<string name="general_share_action">Ibahagi</string>
|
<string name="general_share_action">Ibahagi</string>
|
||||||
<string name="general_done_action">Tapos Na</string>
|
<string name="general_done_action">Tapos Na</string>
|
||||||
<string name="general_copy_action">Kopyahin</string>
|
<string name="general_copy_action">Kopyahin</string>
|
||||||
<string name="general_value_unknown_label">Hndi alam</string>
|
|
||||||
<string name="general_thank_you_label">Salamat sayo</string>
|
<string name="general_thank_you_label">Salamat sayo</string>
|
||||||
<string name="general_value_not_available_label">N/A</string>
|
<string name="general_value_not_available_label">N/A</string>
|
||||||
<string name="general_grant_permission_action">Bigyan ng permiso</string>
|
<string name="general_grant_permission_action">Bigyan ng permiso</string>
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
<string name="general_share_action">Partager</string>
|
<string name="general_share_action">Partager</string>
|
||||||
<string name="general_done_action">Terminé</string>
|
<string name="general_done_action">Terminé</string>
|
||||||
<string name="general_copy_action">Copier</string>
|
<string name="general_copy_action">Copier</string>
|
||||||
<string name="general_value_unknown_label">Inconnu</string>
|
|
||||||
<string name="general_thank_you_label">Merci</string>
|
<string name="general_thank_you_label">Merci</string>
|
||||||
<string name="general_value_not_available_label">Non disponible</string>
|
<string name="general_value_not_available_label">Non disponible</string>
|
||||||
<string name="general_grant_permission_action">Accorder l’autorisation</string>
|
<string name="general_grant_permission_action">Accorder l’autorisation</string>
|
||||||
|
<string name="general_upgrade_action">Surclasser vers Pro</string>
|
||||||
<string name="general_check_action">Vérifier</string>
|
<string name="general_check_action">Vérifier</string>
|
||||||
<string name="general_close_action">Fermer</string>
|
<string name="general_close_action">Fermer</string>
|
||||||
<string name="debug_debuglog_size_label">Taille</string>
|
<string name="debug_debuglog_size_label">Taille</string>
|
||||||
@@ -26,5 +26,105 @@
|
|||||||
<string name="permission_bluetooth_label">Bluetooth</string>
|
<string name="permission_bluetooth_label">Bluetooth</string>
|
||||||
<string name="permission_bluetooth_description">Cette appli exige l’autorisation « Bluetooth » pour se connecter aux appareils Bluetooth jumelés.</string>
|
<string name="permission_bluetooth_description">Cette appli exige l’autorisation « Bluetooth » pour se connecter aux appareils Bluetooth jumelés.</string>
|
||||||
<string name="permission_access_fine_location_label">Accéder à la position précise</string>
|
<string name="permission_access_fine_location_label">Accéder à la position précise</string>
|
||||||
<string name="permission_access_fine_location_description">CAPod utilise l’autorisation « position précise » pour recevoir les données « faible énergie » de Bluetooth. Votre casque-micro utilise la technologie « faible énergie » de Bluetooth pour diffuser son état. Cette appli n’utilisera PAS les données Bluetooth pour déterminer votre position.</string>
|
<string name="permission_access_fine_location_description">CAPod utilise l’autorisation « position précise » pour recevoir les données « faible énergie » de Bluetooth. Votre casque-micro utilise la technologie « basse énergie » de Bluetooth pour diffuser son état. Cette appli n’utilisera PAS les données Bluetooth pour déterminer votre position.</string>
|
||||||
|
<string name="permission_background_location_label">Accès à la position en arrière-plan</string>
|
||||||
|
<string name="permission_background_location_description">CAPod utilise « l’accès à la position en arrière-plan » afin de permettre des fonctions telles qu’« Afficher une notification » et « Connexion automatique » alors que l’appli est fermée. L’accès à la position en arrière-plan permet à l’appli de recevoir les données « basse énergie » de Bluetooth. Elles ne seront PAS utilisées pour déterminer votre position géographie.</string>
|
||||||
|
<string name="permission_ignore_battery_optimizations_label">Désactiver les optimisations de la pile/batterie</string>
|
||||||
|
<string name="permission_ignore_battery_optimizations_description">Les optimisations de la pile/batterie empêchent l’appli de recevoir les données Bluetooth de manière fiable alors que l’appli est en arrière-plan.</string>
|
||||||
|
<string name="pods_dual_left_label">AirPod gauche</string>
|
||||||
|
<string name="pods_dual_right_label">AirPod droit</string>
|
||||||
|
<string name="pods_case_label">Étui</string>
|
||||||
|
<string name="pods_case_status_open_label">Ouvert</string>
|
||||||
|
<string name="pods_case_status_closed_label">Fermé</string>
|
||||||
|
<string name="pods_connection_state_disconnected_label">Non connecté à un appareil</string>
|
||||||
|
<string name="pods_connection_state_idle_label">Connecté à un appareil, mais au repos</string>
|
||||||
|
<string name="pods_connection_state_music_label">En mode musique</string>
|
||||||
|
<string name="pods_connection_state_call_label">En mode appel</string>
|
||||||
|
<string name="pods_connection_state_ringing_label">Sonnerie</string>
|
||||||
|
<string name="pods_connection_state_hanging_up_label">Fin de l’appel</string>
|
||||||
|
<string name="pods_connection_state_unknown_label">État de connexion inconnu</string>
|
||||||
|
<string name="pods_unknown_raw_data_label">Données brutes</string>
|
||||||
|
<string name="pods_unknown_label">Appareil inconnu</string>
|
||||||
|
<string name="pods_unknown_contact_dev">Cet appareil est inconnu, mais il utilise un message de format semblable. Prenons-le en charge, contactez-moi :)</string>
|
||||||
|
<string name="pods_none_label_short">Aucun appareil</string>
|
||||||
|
<string name="pods_charging_label">En charge</string>
|
||||||
|
<string name="pods_inear_label">Dans l’oreille</string>
|
||||||
|
<string name="pods_microphone_label">Microphone</string>
|
||||||
|
<string name="pods_yours">Les vôtres</string>
|
||||||
|
<string name="headset_being_worn_label">Porté</string>
|
||||||
|
<string name="pods_case_unknown_state">État inconnu</string>
|
||||||
|
<string name="overview_nomaindevice_label">Aucun appareil principal</string>
|
||||||
|
<string name="overview_nomaindevice_description">Tous les appareils détectés ne sont probablement pas les vôtres. Allumez et connectez votre appareil ou réglez les paramètres.</string>
|
||||||
|
<string name="settings_label">Paramètres</string>
|
||||||
|
<string name="settings_privacy_policy_label">Politique de confidentialité</string>
|
||||||
|
<string name="settings_privacy_policy_desc">Gestion responsable des données.</string>
|
||||||
|
<string name="settings_licenses_label">Licences</string>
|
||||||
|
<string name="settings_category_other_label">Autre</string>
|
||||||
|
<string name="settings_general_label">Paramètres</string>
|
||||||
|
<string name="settings_general_description">Réglage généraux qui affectent l\'appli entière.</string>
|
||||||
|
<string name="settings_acknowledgements_label">Remerciements</string>
|
||||||
|
<string name="changelog_label">Journal des changements</string>
|
||||||
|
<string name="settings_support_email_developer_label">Envoyer un courriel au développeur</string>
|
||||||
|
<string name="settings_support_installid_label">ID d’installation</string>
|
||||||
|
<string name="settings_support_installid_desc">Les relevés automatiques d’erreur sont anonymes. Partagez votre ID d’installation au cas où le développeur aurait besoin de trouver votre relevé d’erreur.</string>
|
||||||
|
<string name="settings_support_label">Assistance</string>
|
||||||
|
<string name="settings_support_description">Si vous avez besoin d’aide.</string>
|
||||||
|
<string name="issue_tracker_label">Gestionnaire de problèmes</string>
|
||||||
|
<string name="issue_tracker_description">Un gestionnaire public de problèmes pour les signalements de bogues et les demandes de fonction (anglais seulement).</string>
|
||||||
|
<string name="discord_label">Discord</string>
|
||||||
|
<string name="discord_description">Un endroit à fréquenter où poser des questions.</string>
|
||||||
|
<string name="settings_support_email_developer_description">Noter que je ne peux répondre qu’en allemand ou en anglais.</string>
|
||||||
|
<string name="settings_debug_autoreports_label">Relevés de bogue automatiques</string>
|
||||||
|
<string name="settings_debug_autoreports_description">Signale automatiquement les problèmes, p. ex., les détails d’un plantage de l’appli, afin que je puisse essayer de les corriger.</string>
|
||||||
|
<string name="settings_debug_mode_label">Mode de débogage</string>
|
||||||
|
<string name="settings_debug_mode_description">Afficher des renseignements supplémentaires pour dépanner les problèmes.</string>
|
||||||
|
<string name="settings_monitor_mode_label">Mode surveillance</string>
|
||||||
|
<string name="settings_monitor_mode_description">Les circonstances de surveillance des données Bluetooth par l’appli.</string>
|
||||||
|
<string name="settings_scanner_mode_label">Mode analyse</string>
|
||||||
|
<string name="settings_monitor_mode_manual_label">Si l’appli est en fonction</string>
|
||||||
|
<string name="settings_monitor_mode_automatic_label">Si l’appareil est connecté</string>
|
||||||
|
<string name="settings_monitor_mode_always_label">Toujours</string>
|
||||||
|
<string name="settings_scanner_mode_lowpower_label">Faible puissance</string>
|
||||||
|
<string name="settings_scanner_mode_balanced_label">Équilibré</string>
|
||||||
|
<string name="settings_scanner_mode_lowlatency_label">Faible latence</string>
|
||||||
|
<string name="settings_autopause_label">Pause automatique</string>
|
||||||
|
<string name="settings_showall_label">Afficher tous les appareils</string>
|
||||||
|
<string name="settings_showall_description">Afficher les appareils d’autres personnes à proximité.</string>
|
||||||
|
<string name="settings_autopplay_label">Lecture automatique</string>
|
||||||
|
<string name="settings_fake_data_label">Fausses données</string>
|
||||||
|
<string name="settings_debug_label">Paramètres de débogage</string>
|
||||||
|
<string name="settings_debug_description">Autres paramètres pour aider à diagnostiquer les problèmes de l’appli.</string>
|
||||||
|
<string name="settings_signal_minimum_label">Qualité minimale du signal</string>
|
||||||
|
<string name="settings_signal_minimum_description">Qualité minimale du signal qu’un appareil doit émettre pour être considéré le vôtre.</string>
|
||||||
|
<string name="settings_autoconnect_label">Connexion automatique</string>
|
||||||
|
<string name="settings_autoconnect_description">Si Android ne se connecte pas automatiquement, nous pouvons lui demander de le faire. Le paramètre du mode surveillance sera « Toujours ».</string>
|
||||||
|
<string name="settings_autoconnect_condition_label">Condition de connexion automatique</string>
|
||||||
|
<string name="settings_autoconnect_condition_description">Quand devrions-nous tenter de nous connecter à votre appareil ?</string>
|
||||||
|
<string name="settings_reaction_label">Réactions</string>
|
||||||
|
<string name="settings_reaction_description">Réagir à des événements et à des comportements.</string>
|
||||||
|
<string name="settings_category_yourdevice_label">Votre appareil</string>
|
||||||
|
<string name="settings_maindevice_address_label">L’adresse de votre appareil</string>
|
||||||
|
<string name="settings_maindevice_address_description">L’adresse de votre appareil jumelé. L’appli l’utilise pour déterminer s’il est connecté à votre téléphone.</string>
|
||||||
|
<string name="settings_maindevice_address_none">Aucune</string>
|
||||||
|
<string name="settings_maindevice_model_label">Le modèle de votre appareil</string>
|
||||||
|
<string name="settings_maindevice_model_description">Le modèle de votre appareil principal. Facilite la reconnaissance de votre appareil par l’appli s’il n’est pas connecté à votre téléphone.</string>
|
||||||
|
<string name="settings_reaction_autoconnect_whenseen_label">S’il est présent</string>
|
||||||
|
<string name="settings_reaction_autoconnect_caseopen_label">Si l’étui est ouvert</string>
|
||||||
|
<string name="settings_reaction_autoconnect_inear_label">S’il est porté</string>
|
||||||
|
<string name="upgrade_capod_label">Surclasser CAPod</string>
|
||||||
|
<string name="upgrade_capod_description">Obtenez des fonctions supplémentaires et soutenez le développeur.</string>
|
||||||
|
<string name="settings_popup_caseopen_label">Afficher une notification</string>
|
||||||
|
<string name="settings_popup_caseopen_description">Afficher une notification à l’ouverture de l’étui de l\'appareil (expérimental).</string>
|
||||||
|
<string name="overview_bluetooth_disabled_label">Le Bluetooth est désactivé</string>
|
||||||
|
<string name="overview_bluetooth_disabled_description">Le Bluetooth est désactivé, activez-le ;)</string>
|
||||||
|
<string name="help_translate_label">Traduction</string>
|
||||||
|
<string name="settings_onepod_mode_label">Mode à un seul AirPod</string>
|
||||||
|
<string name="settings_onepod_mode_description">Il n’est pas nécessaire de porter deux AirPods, en porter un seul suffit à déclencher les réactions.</string>
|
||||||
|
<string name="permission_system_alert_window_label">Fenêtre d’alerte système</string>
|
||||||
|
<string name="permission_system_alert_window_description">Permettre à CAPod d’apparaître par-dessus les autres applis pour rendre la fonction « Afficher une notification » possible.</string>
|
||||||
|
<string name="last_seen_x">Vu pour la dernière fois : %s</string>
|
||||||
|
<string name="first_seen_x">Vu pour la première fois : %s</string>
|
||||||
|
<string name="settings_blescanner_unfiltered_label">Données BÉB non filtrées</string>
|
||||||
|
<string name="settings_blescanner_unfiltered_description">Supprimer tous les filtres de l’analyseur BÉB pour afficher toutes les données BÉB diffusées. Utile pour prendre en charge les nouveaux types de casques-micros.</string>
|
||||||
|
<string name="permission_required_title">L’autorisation suivante est nécessaire :</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,2 +1,130 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<string name="app_name">CAPod</string>
|
||||||
|
<string name="app_name_pro">CAPod_pro</string>
|
||||||
|
<string name="app_name_foss">CAPod nyílt_forráskód</string>
|
||||||
|
<string name="notification_channel_device_status_label">Értesítési_állapot</string>
|
||||||
|
<string name="general_error_label">Hiba</string>
|
||||||
|
<string name="general_share_action">Megosztás</string>
|
||||||
|
<string name="general_done_action">Kész</string>
|
||||||
|
<string name="general_copy_action">Másolás</string>
|
||||||
|
<string name="general_thank_you_label">Köszönöm</string>
|
||||||
|
<string name="general_value_not_available_label">Nincs_adat</string>
|
||||||
|
<string name="general_grant_permission_action">Hozzáférés megadva</string>
|
||||||
|
<string name="general_upgrade_action">Frissítés_előfizetésre</string>
|
||||||
|
<string name="general_check_action">Ellenőrzés</string>
|
||||||
|
<string name="general_close_action">Zárt</string>
|
||||||
|
<string name="debug_debuglog_size_label">Méret</string>
|
||||||
|
<string name="debug_debuglog_size_compressed_label">Tömörített_méret</string>
|
||||||
|
<string name="debug_notification_channel_label">Hibakeresési_értesítések</string>
|
||||||
|
<string name="debug_debuglog_file_label">Rögzített_naplófájl</string>
|
||||||
|
<string name="debug_debuglog_record_action">Hibakeresési_napló_rögzítése</string>
|
||||||
|
<string name="permission_bluetooth_connect_label">Bluetooth_kapcsolat</string>
|
||||||
|
<string name="permission_bluetooth_connect_description">Ehhez az alkalmazáshoz a \"Bluetooth kapcsolat\" engedély szükséges a párosított eszközökkel való interakcióhoz és a kapcsolatok kezdeményezéséhez.</string>
|
||||||
|
<string name="permission_bluetooth_scan_label">Bluetooth_keresés</string>
|
||||||
|
<string name="permission_bluetooth_scan_description">A „Bluetooth-keresés” engedély lehetővé teszi az alkalmazás számára, hogy Bluetooth-adatokat keressen és fogadjon a közeli eszközökről, például az Ön AirPodjairól.</string>
|
||||||
|
<string name="permission_bluetooth_label">Bluetooth</string>
|
||||||
|
<string name="permission_bluetooth_description">Ehhez az alkalmazáshoz „Bluetooth” engedély szükséges a párosított Bluetooth-eszközökhöz való csatlakozáshoz.</string>
|
||||||
|
<string name="permission_access_fine_location_label">Lokalizálás engedélyezése</string>
|
||||||
|
<string name="permission_access_fine_location_description">A CAPod a „megfelelő hely” engedélyt használja a Bluetooth alacsony töltés adatok fogadására. Fejhallgatója Bluetooth alacsony töltés technológiát használ az állapotának közvetítésére. Ez az alkalmazás NEM használ Bluetooth-adatokat az Ön tartózkodási helyének meghatározásához.</string>
|
||||||
|
<string name="permission_background_location_label">Háttér helyhozzáférés</string>
|
||||||
|
<string name="permission_background_location_description">\"Automatikus_csatlakozás\".</string>
|
||||||
|
<string name="permission_ignore_battery_optimizations_label">Az akkumulátor optimalizálás letiltása</string>
|
||||||
|
<string name="permission_ignore_battery_optimizations_description">Az akkumulátor optimalizálás megakadályozza, hogy ez az alkalmazás megbízhatóan fogadja a Bluetooth-adatokat, miközben az alkalmazás a háttérben működik.</string>
|
||||||
|
<string name="pods_dual_left_label">Bal hangszóró</string>
|
||||||
|
<string name="pods_dual_right_label">Jobb hangszóró</string>
|
||||||
|
<string name="pods_case_label">Tok</string>
|
||||||
|
<string name="pods_case_status_open_label">Nyitott</string>
|
||||||
|
<string name="pods_case_status_closed_label">Zárt</string>
|
||||||
|
<string name="pods_connection_state_disconnected_label">Nincs eszközhöz csatlakoztatva</string>
|
||||||
|
<string name="pods_connection_state_idle_label">Eszközhöz csatlakozik, de tétlen</string>
|
||||||
|
<string name="pods_connection_state_music_label">Zenei mód</string>
|
||||||
|
<string name="pods_connection_state_call_label">Hívás üzemmód</string>
|
||||||
|
<string name="pods_connection_state_ringing_label">Hívás</string>
|
||||||
|
<string name="pods_connection_state_hanging_up_label">Hívás vége</string>
|
||||||
|
<string name="pods_connection_state_unknown_label">Ismeretlen kapcsolati állapot</string>
|
||||||
|
<string name="pods_unknown_raw_data_label">Rossz adat</string>
|
||||||
|
<string name="pods_unknown_label">Ismeretlen eszköz</string>
|
||||||
|
<string name="pods_unknown_contact_dev">Ez egy ismeretlen eszköz, de hasonló üzenetformátumot használ. Adjunk hozzá támogatást, vedd fel velem a kapcsolatot :)</string>
|
||||||
|
<string name="pods_none_label_short">Nincs eszköz</string>
|
||||||
|
<string name="pods_charging_label">Töltés</string>
|
||||||
|
<string name="pods_inear_label">Fülhalgató</string>
|
||||||
|
<string name="pods_microphone_label">Mikrofon</string>
|
||||||
|
<string name="pods_yours">A tied</string>
|
||||||
|
<string name="headset_being_worn_label">Használt</string>
|
||||||
|
<string name="pods_case_unknown_state">Ismeretlen állapot</string>
|
||||||
|
<string name="overview_nomaindevice_label">Nincs elsődleges eszköz</string>
|
||||||
|
<string name="overview_nomaindevice_description">Valószínűleg nem minden észlelt eszköz az Öné. Kapcsolja be és csatlakoztassa a készüléket, vagy módosítsa a beállításokat.</string>
|
||||||
|
<string name="settings_label">Beéllítások</string>
|
||||||
|
<string name="settings_privacy_policy_label">Adatvédelmi irányelvek</string>
|
||||||
|
<string name="settings_privacy_policy_desc">Az adatok felelősségteljes kezelése.</string>
|
||||||
|
<string name="settings_licenses_label">Licensz</string>
|
||||||
|
<string name="settings_category_other_label">Másik</string>
|
||||||
|
<string name="settings_general_label">Beéllítások</string>
|
||||||
|
<string name="settings_general_description">Általános módosítások, amelyek az egész alkalmazást érintik.</string>
|
||||||
|
<string name="settings_acknowledgements_label">Köszönetnyilvánítások</string>
|
||||||
|
<string name="changelog_label">Napló</string>
|
||||||
|
<string name="settings_support_email_developer_label">Fejlesztő Email címe</string>
|
||||||
|
<string name="settings_support_installid_label">Azonosító</string>
|
||||||
|
<string name="settings_support_installid_desc">Az automatikus hibajelentések névtelenek. Ossza meg azonosítóját, hogy a fejlesztő megtalálja a hibajelentéseket.</string>
|
||||||
|
<string name="settings_support_label">Támogatás</string>
|
||||||
|
<string name="settings_support_description">Ha segítségre van szüksége.</string>
|
||||||
|
<string name="issue_tracker_label">Problémakövető</string>
|
||||||
|
<string name="issue_tracker_description">Nyilvános problémakövető hibajelentésekhez és szolgáltatáskérésekhez (csak angol nyelven).</string>
|
||||||
|
<string name="discord_label">Viszály</string>
|
||||||
|
<string name="discord_description">Egy hely, ahol kérdéseket tehet fel.</string>
|
||||||
|
<string name="settings_support_email_developer_description">Vegye figyelembe, hogy csak németül vagy angolul tudok válaszolni.</string>
|
||||||
|
<string name="settings_debug_autoreports_label">Automatikus hibajelentések</string>
|
||||||
|
<string name="settings_debug_autoreports_description">Automatikusan jelenti a problémákat, például részleteket az alkalmazás összeomlásáról, hogy kitaláljam, hogyan javíthatom ki.</string>
|
||||||
|
<string name="settings_debug_mode_label">Hibakeresési mód</string>
|
||||||
|
<string name="settings_debug_mode_description">További információk megjelenítése a problémák hibaelhárításához.</string>
|
||||||
|
<string name="settings_monitor_mode_label">Monitor mód</string>
|
||||||
|
<string name="settings_monitor_mode_description">Milyen körülmények között figyeli ez az alkalmazás a Bluetooth-adatokat.</string>
|
||||||
|
<string name="settings_scanner_mode_label">Szkenner mód</string>
|
||||||
|
<string name="settings_monitor_mode_manual_label">Amikor az alkalmazás nyitva van</string>
|
||||||
|
<string name="settings_monitor_mode_automatic_label">Amikor az eszköz csatlakoztatva van</string>
|
||||||
|
<string name="settings_monitor_mode_always_label">Mindig</string>
|
||||||
|
<string name="settings_scanner_mode_lowpower_label">Kis fogyasztású</string>
|
||||||
|
<string name="settings_scanner_mode_balanced_label">Kiegyensúlyozott</string>
|
||||||
|
<string name="settings_scanner_mode_lowlatency_label">Alacsony késleltetés</string>
|
||||||
|
<string name="settings_autopause_label">Automatikus megszakítás</string>
|
||||||
|
<string name="settings_showall_label">Az összes eszköz megjelenítése</string>
|
||||||
|
<string name="settings_showall_description">Mutassa meg másoknak az Ön közelében lévő eszközeit.</string>
|
||||||
|
<string name="settings_autopplay_label">Automatikus lejátszás</string>
|
||||||
|
<string name="settings_fake_data_label">Hamis adat</string>
|
||||||
|
<string name="settings_debug_label">Hibakeresési beállítások</string>
|
||||||
|
<string name="settings_debug_description">További beállítások az alkalmazással kapcsolatos problémák megoldásához.</string>
|
||||||
|
<string name="settings_signal_minimum_label">Minimális jelerősség</string>
|
||||||
|
<string name="settings_signal_minimum_description">Vegye figyelembe a minimális jelerősséget, amelyre egy eszköznek szüksége van.</string>
|
||||||
|
<string name="settings_autoconnect_label">Automatikus csatlakozás</string>
|
||||||
|
<string name="settings_autoconnect_description">Ha az Android nem csatlakozik automatikusan. A monitor mód beállítása „Mindig” lesz.</string>
|
||||||
|
<string name="settings_autoconnect_condition_label">Automatikus csatlakozás állapota</string>
|
||||||
|
<string name="settings_autoconnect_condition_description">Mikor próbáljunk meg csatlakozni az eszközéhez?</string>
|
||||||
|
<string name="settings_reaction_label">Reakciók</string>
|
||||||
|
<string name="settings_reaction_description">Reagáljon az eseményekre és viselkedésekre.</string>
|
||||||
|
<string name="settings_category_yourdevice_label">A Te eszközöd</string>
|
||||||
|
<string name="settings_maindevice_address_label">A készüléked címe</string>
|
||||||
|
<string name="settings_maindevice_address_description">A párosított eszköz címe. Az alkalmazás ezt használja annak meghatározására, hogy mikor csatlakozik a telefonhoz.</string>
|
||||||
|
<string name="settings_maindevice_address_none">Semmi</string>
|
||||||
|
<string name="settings_maindevice_model_label">Az Ön készülékének modellje</string>
|
||||||
|
<string name="settings_maindevice_model_description">A fő eszköz modellje. Ez segít az alkalmazásnak felismerni az eszközt, amikor az nincs csatlakoztatva a telefonhoz.</string>
|
||||||
|
<string name="settings_reaction_autoconnect_whenseen_label">Amikor látható</string>
|
||||||
|
<string name="settings_reaction_autoconnect_caseopen_label">Tok Nyitva</string>
|
||||||
|
<string name="settings_reaction_autoconnect_inear_label">Fülhallgató</string>
|
||||||
|
<string name="upgrade_capod_label">CAPod frissítése</string>
|
||||||
|
<string name="upgrade_capod_description">Szerezzen be további funkciókat és támogassa a fejlesztőt.</string>
|
||||||
|
<string name="settings_popup_caseopen_label">Előugró ablak megjelenítése</string>
|
||||||
|
<string name="settings_popup_caseopen_description">Egy előugró ablak megjelenítése az eszköz házának kinyitásakor (kísérleti).</string>
|
||||||
|
<string name="overview_bluetooth_disabled_label">A Bluetooth kikapcsolva</string>
|
||||||
|
<string name="overview_bluetooth_disabled_description">Bluetooth kikapcsolva, engedélyezd ;)</string>
|
||||||
|
<string name="help_translate_label">Fordítás</string>
|
||||||
|
<string name="settings_onepod_mode_label">Egy fülhallgató mód</string>
|
||||||
|
<string name="settings_onepod_mode_description">Nem szükséges mindkét fülhallgató viselése, elég egy, a működéshez.</string>
|
||||||
|
<string name="permission_system_alert_window_label">Rendszer figyelmeztető ablak</string>
|
||||||
|
<string name="permission_system_alert_window_description">Engedélyezze a CAPod számára, hogy más alkalmazások fölé kerüljön, hogy lehetővé tegye a „Előugró ablak” funkciót.</string>
|
||||||
|
<string name="last_seen_x">Utoljára volt látható %s</string>
|
||||||
|
<string name="first_seen_x">Először volt látható: %s</string>
|
||||||
|
<string name="settings_blescanner_unfiltered_label">Szűretlen BLE adatok</string>
|
||||||
|
<string name="settings_blescanner_unfiltered_description">Távolítson el minden szűrőt a BLE szkennerből, hogy megjelenjen az összes adat. Hasznos új fejhallgató típusok támogatásához.</string>
|
||||||
|
<string name="permission_required_title">A következő engedély szükséges:</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
@@ -8,11 +8,10 @@
|
|||||||
<string name="general_share_action">Bagikan</string>
|
<string name="general_share_action">Bagikan</string>
|
||||||
<string name="general_done_action">Selesai</string>
|
<string name="general_done_action">Selesai</string>
|
||||||
<string name="general_copy_action">Salin</string>
|
<string name="general_copy_action">Salin</string>
|
||||||
<string name="general_value_unknown_label">Tidak diketahui</string>
|
|
||||||
<string name="general_thank_you_label">Terima kasih</string>
|
<string name="general_thank_you_label">Terima kasih</string>
|
||||||
<string name="general_value_not_available_label">T/A</string>
|
<string name="general_value_not_available_label">T/A</string>
|
||||||
<string name="general_grant_permission_action">Berikan izin</string>
|
<string name="general_grant_permission_action">Berikan izin</string>
|
||||||
<string name="general_upgrade_action" comment="general_upgrade_action, Used as label for dialog buttons, i.e. the dialog is about upgrading the app to "Pro" and the positive confirmation button is labeled "Upgrade"">Tingkatkan</string>
|
<string name="general_upgrade_action">Tingkatkan</string>
|
||||||
<string name="general_check_action">Memeriksa</string>
|
<string name="general_check_action">Memeriksa</string>
|
||||||
<string name="general_close_action">Tutup</string>
|
<string name="general_close_action">Tutup</string>
|
||||||
<string name="debug_debuglog_size_label">Ukuran</string>
|
<string name="debug_debuglog_size_label">Ukuran</string>
|
||||||
@@ -43,6 +42,7 @@
|
|||||||
<string name="pods_connection_state_call_label">Dalam mode panggilan</string>
|
<string name="pods_connection_state_call_label">Dalam mode panggilan</string>
|
||||||
<string name="pods_connection_state_ringing_label">Berdering</string>
|
<string name="pods_connection_state_ringing_label">Berdering</string>
|
||||||
<string name="pods_connection_state_hanging_up_label">Mengangkat</string>
|
<string name="pods_connection_state_hanging_up_label">Mengangkat</string>
|
||||||
|
<string name="pods_connection_state_unknown_label">Status koneksi tidak diketahui</string>
|
||||||
<string name="pods_unknown_raw_data_label">Data mentah</string>
|
<string name="pods_unknown_raw_data_label">Data mentah</string>
|
||||||
<string name="pods_unknown_label">Perangkat tidak dikenal</string>
|
<string name="pods_unknown_label">Perangkat tidak dikenal</string>
|
||||||
<string name="pods_unknown_contact_dev">Ini adalah perangkat yang tidak dikenal, tapi menggunakan format pesan yang serupa. Mari tambahkan dukungan untuk itu, hubungi saya :)</string>
|
<string name="pods_unknown_contact_dev">Ini adalah perangkat yang tidak dikenal, tapi menggunakan format pesan yang serupa. Mari tambahkan dukungan untuk itu, hubungi saya :)</string>
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
<string name="pods_microphone_label">Mikrofon</string>
|
<string name="pods_microphone_label">Mikrofon</string>
|
||||||
<string name="pods_yours">Milikmu</string>
|
<string name="pods_yours">Milikmu</string>
|
||||||
<string name="headset_being_worn_label">Sedang dipakai</string>
|
<string name="headset_being_worn_label">Sedang dipakai</string>
|
||||||
|
<string name="pods_case_unknown_state">Status tidak diketahui</string>
|
||||||
<string name="overview_nomaindevice_label">Tidak ada perangkat utama</string>
|
<string name="overview_nomaindevice_label">Tidak ada perangkat utama</string>
|
||||||
<string name="overview_nomaindevice_description">Semua perangkat yang terdeteksi tidak mungkin menjadi milik anda. Nyalakan & sambungkan perangkat anda atau sesuaikan pengaturan.</string>
|
<string name="overview_nomaindevice_description">Semua perangkat yang terdeteksi tidak mungkin menjadi milik anda. Nyalakan & sambungkan perangkat anda atau sesuaikan pengaturan.</string>
|
||||||
<string name="settings_label">Pengaturan</string>
|
<string name="settings_label">Pengaturan</string>
|
||||||
@@ -80,7 +81,6 @@
|
|||||||
<string name="settings_monitor_mode_label">Mode monitor</string>
|
<string name="settings_monitor_mode_label">Mode monitor</string>
|
||||||
<string name="settings_monitor_mode_description">Dalam keadaan apa aplikasi ini memonitor data Bluetooth.</string>
|
<string name="settings_monitor_mode_description">Dalam keadaan apa aplikasi ini memonitor data Bluetooth.</string>
|
||||||
<string name="settings_scanner_mode_label">Modus memindai</string>
|
<string name="settings_scanner_mode_label">Modus memindai</string>
|
||||||
<string name="settings_scanner_mode_description">Haruskah pemindai Bluetooth Hemat Energi memprioritaskan kinerja atau menghemat energi?</string>
|
|
||||||
<string name="settings_monitor_mode_manual_label">Saat aplikasi terbuka</string>
|
<string name="settings_monitor_mode_manual_label">Saat aplikasi terbuka</string>
|
||||||
<string name="settings_monitor_mode_automatic_label">Saat perangkat terhubung</string>
|
<string name="settings_monitor_mode_automatic_label">Saat perangkat terhubung</string>
|
||||||
<string name="settings_monitor_mode_always_label">Selalu</string>
|
<string name="settings_monitor_mode_always_label">Selalu</string>
|
||||||
@@ -88,13 +88,10 @@
|
|||||||
<string name="settings_scanner_mode_balanced_label">Seimbang</string>
|
<string name="settings_scanner_mode_balanced_label">Seimbang</string>
|
||||||
<string name="settings_scanner_mode_lowlatency_label">Latemsi rendah</string>
|
<string name="settings_scanner_mode_lowlatency_label">Latemsi rendah</string>
|
||||||
<string name="settings_autopause_label">Jeda otomatis</string>
|
<string name="settings_autopause_label">Jeda otomatis</string>
|
||||||
<string name="settings_autopause_description">Jeda musik saat melepaskan perangkat dari telinga anda.</string>
|
|
||||||
<string name="settings_showall_label">Tampilkan semua perangkat</string>
|
<string name="settings_showall_label">Tampilkan semua perangkat</string>
|
||||||
<string name="settings_showall_description">Tampilkan perangkat orang lain yang ada di dekat anda.</string>
|
<string name="settings_showall_description">Tampilkan perangkat orang lain yang ada di dekat anda.</string>
|
||||||
<string name="settings_autopplay_label">Putar otomatis</string>
|
<string name="settings_autopplay_label">Putar otomatis</string>
|
||||||
<string name="settings_autoplay_description">Mulai pemutaran musik musik saat memakai perangkat.</string>
|
|
||||||
<string name="settings_fake_data_label">Data palsu</string>
|
<string name="settings_fake_data_label">Data palsu</string>
|
||||||
<string name="settings_fake_data_description">Tampilkan data palsu, mis: mensimulasikan perangkat yang tidak ada.</string>
|
|
||||||
<string name="settings_debug_label">Pengaturan debug</string>
|
<string name="settings_debug_label">Pengaturan debug</string>
|
||||||
<string name="settings_debug_description">Pengaturan tambahan untuk membantu memecahkan masalah dengan aplikasi.</string>
|
<string name="settings_debug_description">Pengaturan tambahan untuk membantu memecahkan masalah dengan aplikasi.</string>
|
||||||
<string name="settings_signal_minimum_label">Kualitas sinyal minimum</string>
|
<string name="settings_signal_minimum_label">Kualitas sinyal minimum</string>
|
||||||
@@ -118,11 +115,9 @@
|
|||||||
<string name="upgrade_capod_description">Dapatkan fitur tambahan & bantu dukung pengembang.</string>
|
<string name="upgrade_capod_description">Dapatkan fitur tambahan & bantu dukung pengembang.</string>
|
||||||
<string name="settings_popup_caseopen_label">Tampilkan popup</string>
|
<string name="settings_popup_caseopen_label">Tampilkan popup</string>
|
||||||
<string name="settings_popup_caseopen_description">Tampilkan popup saat kasing perangkat dibuka (eksperimental).</string>
|
<string name="settings_popup_caseopen_description">Tampilkan popup saat kasing perangkat dibuka (eksperimental).</string>
|
||||||
<string name="notification_channel_reaction_popup_label">Reaksi perangkat popup</string>
|
|
||||||
<string name="overview_bluetooth_disabled_label">Bluetooth dinonaktifkan</string>
|
<string name="overview_bluetooth_disabled_label">Bluetooth dinonaktifkan</string>
|
||||||
<string name="overview_bluetooth_disabled_description">Bluetooth dinonaktifkan, aktifkan terlebih dahulu ;)</string>
|
<string name="overview_bluetooth_disabled_description">Bluetooth dinonaktifkan, aktifkan terlebih dahulu ;)</string>
|
||||||
<string name="help_translate_label">Terjemahan</string>
|
<string name="help_translate_label">Terjemahan</string>
|
||||||
<string name="help_translate_description">Bantu terjemahkan ini ke bahasa favorit anda.</string>
|
|
||||||
<string name="settings_onepod_mode_label">Mode satu pod</string>
|
<string name="settings_onepod_mode_label">Mode satu pod</string>
|
||||||
<string name="settings_onepod_mode_description">Menggunakan kedua pod tidak diperlukan, memakai satu pod sudah cukup untuk memicu reaksi.</string>
|
<string name="settings_onepod_mode_description">Menggunakan kedua pod tidak diperlukan, memakai satu pod sudah cukup untuk memicu reaksi.</string>
|
||||||
<string name="permission_system_alert_window_label">Jendela Peringatan Sistem</string>
|
<string name="permission_system_alert_window_label">Jendela Peringatan Sistem</string>
|
||||||
@@ -131,4 +126,5 @@
|
|||||||
<string name="first_seen_x">Pertama kali terlihat: %s</string>
|
<string name="first_seen_x">Pertama kali terlihat: %s</string>
|
||||||
<string name="settings_blescanner_unfiltered_label">Data BLE yang tidak difilter</string>
|
<string name="settings_blescanner_unfiltered_label">Data BLE yang tidak difilter</string>
|
||||||
<string name="settings_blescanner_unfiltered_description">Hapus semua filter dari pemindai BLE untuk menampilkan semua data BLE yang disiarkan. Berguna untuk menambahkan dukungan pada jenis headphone baru.</string>
|
<string name="settings_blescanner_unfiltered_description">Hapus semua filter dari pemindai BLE untuk menampilkan semua data BLE yang disiarkan. Berguna untuk menambahkan dukungan pada jenis headphone baru.</string>
|
||||||
|
<string name="permission_required_title">Izin berikut diperlukan:</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
<string name="general_share_action">Condividi</string>
|
<string name="general_share_action">Condividi</string>
|
||||||
<string name="general_done_action">Fatto</string>
|
<string name="general_done_action">Fatto</string>
|
||||||
<string name="general_copy_action">Copia</string>
|
<string name="general_copy_action">Copia</string>
|
||||||
<string name="general_value_unknown_label">Sconosciuto</string>
|
|
||||||
<string name="general_thank_you_label">Grazie</string>
|
<string name="general_thank_you_label">Grazie</string>
|
||||||
<string name="general_value_not_available_label">N/A</string>
|
<string name="general_value_not_available_label">N/A</string>
|
||||||
<string name="general_grant_permission_action">Concedi permessi</string>
|
<string name="general_grant_permission_action">Concedi permessi</string>
|
||||||
@@ -25,6 +24,7 @@
|
|||||||
<string name="permission_bluetooth_scan_label">Scansione bluetooth</string>
|
<string name="permission_bluetooth_scan_label">Scansione bluetooth</string>
|
||||||
<string name="permission_bluetooth_scan_description">Il permesso di \"Scansione bluetooth\" permette a questa app di trovare e ricevere dati Bluetooth da dispositivi vicini come le tue Airpods.</string>
|
<string name="permission_bluetooth_scan_description">Il permesso di \"Scansione bluetooth\" permette a questa app di trovare e ricevere dati Bluetooth da dispositivi vicini come le tue Airpods.</string>
|
||||||
<string name="permission_bluetooth_label">Bluetooth</string>
|
<string name="permission_bluetooth_label">Bluetooth</string>
|
||||||
|
<string name="permission_bluetooth_description">Questa app richiede il permesso \"Bluetooth\" per connettersi ai dispoitivi Bluetooth.</string>
|
||||||
<string name="permission_access_fine_location_label">Access fine location</string>
|
<string name="permission_access_fine_location_label">Access fine location</string>
|
||||||
<string name="permission_access_fine_location_description">CAPod usa i permessi di Geolocalizzazione per ricevere dati Bluetooth a basso consumo. Le tue cuffie suano la tecnologia Bluetooth a basso consumo per inviare al dispositivo al quale sono connesse il loro stato. Questa app non utilizza i dati Bluetooth per geolocalizzarti.</string>
|
<string name="permission_access_fine_location_description">CAPod usa i permessi di Geolocalizzazione per ricevere dati Bluetooth a basso consumo. Le tue cuffie suano la tecnologia Bluetooth a basso consumo per inviare al dispositivo al quale sono connesse il loro stato. Questa app non utilizza i dati Bluetooth per geolocalizzarti.</string>
|
||||||
<string name="permission_background_location_label">Accesso in background alla tua posizione</string>
|
<string name="permission_background_location_label">Accesso in background alla tua posizione</string>
|
||||||
@@ -42,14 +42,17 @@
|
|||||||
<string name="pods_connection_state_call_label">In modalità chiamata</string>
|
<string name="pods_connection_state_call_label">In modalità chiamata</string>
|
||||||
<string name="pods_connection_state_ringing_label">Squilla</string>
|
<string name="pods_connection_state_ringing_label">Squilla</string>
|
||||||
<string name="pods_connection_state_hanging_up_label">Riconnessione</string>
|
<string name="pods_connection_state_hanging_up_label">Riconnessione</string>
|
||||||
|
<string name="pods_connection_state_unknown_label">Stato di connessione sconosciuto</string>
|
||||||
<string name="pods_unknown_raw_data_label">Dati non elaborati</string>
|
<string name="pods_unknown_raw_data_label">Dati non elaborati</string>
|
||||||
<string name="pods_unknown_label">Dispositivo sconosciuto</string>
|
<string name="pods_unknown_label">Dispositivo sconosciuto</string>
|
||||||
|
<string name="pods_unknown_contact_dev">Questo é un dispositivo sconosciutom ma sta utilizzando un formato di comunicazione noto. Aggiungiamo il supporto per questo device, Contattami! :)</string>
|
||||||
<string name="pods_none_label_short">Nessun dispositivo</string>
|
<string name="pods_none_label_short">Nessun dispositivo</string>
|
||||||
<string name="pods_charging_label">In ricarica</string>
|
<string name="pods_charging_label">In ricarica</string>
|
||||||
<string name="pods_inear_label">Nell\'orecchio</string>
|
<string name="pods_inear_label">Nell\'orecchio</string>
|
||||||
<string name="pods_microphone_label">Microfono</string>
|
<string name="pods_microphone_label">Microfono</string>
|
||||||
<string name="pods_yours">Tuoi</string>
|
<string name="pods_yours">Tuoi</string>
|
||||||
<string name="headset_being_worn_label">Indossato</string>
|
<string name="headset_being_worn_label">Indossato</string>
|
||||||
|
<string name="pods_case_unknown_state">Stato sconosciuto</string>
|
||||||
<string name="overview_nomaindevice_label">Nessun device primario</string>
|
<string name="overview_nomaindevice_label">Nessun device primario</string>
|
||||||
<string name="overview_nomaindevice_description">Tutti i dispositivi rilevati molto probabilmente non sono tuoi. Accendi e connetti i tuoi dispositivi oppure sistema le impostazioni.</string>
|
<string name="overview_nomaindevice_description">Tutti i dispositivi rilevati molto probabilmente non sono tuoi. Accendi e connetti i tuoi dispositivi oppure sistema le impostazioni.</string>
|
||||||
<string name="settings_label">Impostazioni</string>
|
<string name="settings_label">Impostazioni</string>
|
||||||
@@ -86,13 +89,11 @@
|
|||||||
<string name="settings_scanner_mode_balanced_label">Bilanciato</string>
|
<string name="settings_scanner_mode_balanced_label">Bilanciato</string>
|
||||||
<string name="settings_scanner_mode_lowlatency_label">Bassa latenza</string>
|
<string name="settings_scanner_mode_lowlatency_label">Bassa latenza</string>
|
||||||
<string name="settings_autopause_label">Pausa automatica</string>
|
<string name="settings_autopause_label">Pausa automatica</string>
|
||||||
<string name="settings_autopause_description">Metti in pausa la musica quando viene rimossa la cuffia da un orecchio.</string>
|
<string name="settings_autopause_description">Metti in pausa l\'audio quando viene rimossa la cuffia da un orecchio.</string>
|
||||||
<string name="settings_showall_label">Mostra tutti i dispositivi</string>
|
<string name="settings_showall_label">Mostra tutti i dispositivi</string>
|
||||||
<string name="settings_showall_description">Mostra i dispositivi delle altre persone vicine a te.</string>
|
<string name="settings_showall_description">Mostra i dispositivi delle altre persone vicine a te.</string>
|
||||||
<string name="settings_autopplay_label">Riproduzione automatica</string>
|
<string name="settings_autopplay_label">Riproduzione automatica</string>
|
||||||
<string name="settings_autoplay_description">Avvia la riproduzione della musica quando indossi il dispositivo.</string>
|
|
||||||
<string name="settings_fake_data_label">Dati immaginari</string>
|
<string name="settings_fake_data_label">Dati immaginari</string>
|
||||||
<string name="settings_fake_data_description">Mostra dati immaginari così da poter simulare dispositivi che in realtà non esistono.</string>
|
|
||||||
<string name="settings_debug_label">Impostazioni di debug</string>
|
<string name="settings_debug_label">Impostazioni di debug</string>
|
||||||
<string name="settings_debug_description">Impostazioni aggiuntive che possono aiutare a risolvere i problemi con l\'applicazione.</string>
|
<string name="settings_debug_description">Impostazioni aggiuntive che possono aiutare a risolvere i problemi con l\'applicazione.</string>
|
||||||
<string name="settings_signal_minimum_label">Qualità del segnale minima</string>
|
<string name="settings_signal_minimum_label">Qualità del segnale minima</string>
|
||||||
@@ -116,8 +117,8 @@
|
|||||||
<string name="upgrade_capod_description">Ottieni funzionalità aggiuntive e supporta lo sviluppatore.</string>
|
<string name="upgrade_capod_description">Ottieni funzionalità aggiuntive e supporta lo sviluppatore.</string>
|
||||||
<string name="settings_popup_caseopen_label">Mostra popup</string>
|
<string name="settings_popup_caseopen_label">Mostra popup</string>
|
||||||
<string name="settings_popup_caseopen_description">Mostra un popup quando la custodia del dispositivo è aperta (sperimentale).</string>
|
<string name="settings_popup_caseopen_description">Mostra un popup quando la custodia del dispositivo è aperta (sperimentale).</string>
|
||||||
<string name="notification_channel_reaction_popup_label">Popup reazioni dispositivo</string>
|
|
||||||
<string name="overview_bluetooth_disabled_label">Il Bluetooth é disabilitato</string>
|
<string name="overview_bluetooth_disabled_label">Il Bluetooth é disabilitato</string>
|
||||||
|
<string name="overview_bluetooth_disabled_description">Il bluetooth é disabilitato, abilitalo ;)</string>
|
||||||
<string name="help_translate_label">Traduzione</string>
|
<string name="help_translate_label">Traduzione</string>
|
||||||
<string name="help_translate_description">Aiuta a tradurre l\'applicazione nella tua lingua preferita.</string>
|
<string name="help_translate_description">Aiuta a tradurre l\'applicazione nella tua lingua preferita.</string>
|
||||||
<string name="settings_onepod_mode_label">Modalità singolo pod</string>
|
<string name="settings_onepod_mode_label">Modalità singolo pod</string>
|
||||||
@@ -126,4 +127,7 @@
|
|||||||
<string name="permission_system_alert_window_description">Permetti a CAPod di far apprarire overlay sopra le altre applicazioni per far funzionare \"Mostra PopUp\".</string>
|
<string name="permission_system_alert_window_description">Permetti a CAPod di far apprarire overlay sopra le altre applicazioni per far funzionare \"Mostra PopUp\".</string>
|
||||||
<string name="last_seen_x">Ultimo accesso: %s</string>
|
<string name="last_seen_x">Ultimo accesso: %s</string>
|
||||||
<string name="first_seen_x">Primo accesso: %s</string>
|
<string name="first_seen_x">Primo accesso: %s</string>
|
||||||
|
<string name="settings_blescanner_unfiltered_label">Dati BLE non filtrati</string>
|
||||||
|
<string name="permission_required_title">È richiesta la seguente autorizzazione:</string>
|
||||||
|
<string name="settings_compatibility_mode_label">Modalità di compatibilità</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user