From c0adbf59c366f0b1bdb97772a6879fa593ebccc4 Mon Sep 17 00:00:00 2001 From: Marc Nause Date: Tue, 29 Mar 2022 23:11:35 +0200 Subject: [PATCH 001/110] Added rule to keep static members of GattCharacteristic class --- app/proguard-rules.pro | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 6af6c8ff1..65ded85a0 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -18,10 +18,14 @@ -keepclassmembers class nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.JSInterface { public *; } -# Required for refection in BangleJSDeviceSupport +# Required for reflection in BangleJSDeviceSupport -keepclassmembers class nodomain.freeyourgadget.gadgetbridge.model.CallSpec { public static *; } +# Required for reflection in method GattCharacteristic.initDebugMap() +-keepclassmembers class nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic { + public static *; +} -keepattributes JavascriptInterface # https://github.com/tony19/logback-android/issues/29 From ad36569376f367303ecd4b2fd4cae83560fe077d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Fern=C3=A1ndez=20D=C3=ADaz?= Date: Thu, 17 Mar 2022 20:34:03 +0000 Subject: [PATCH 002/110] Translated using Weblate (Spanish) Currently translated at 100.0% (1468 of 1468 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/es/ --- app/src/main/res/values-es/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 3cba4fce6..49304fe14 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1591,4 +1591,11 @@ Parada de seguimiento de la aplicación de ejercicio físico Nombre del paquete OpenTracks Se usa para iniciar/detener la grabación del seguimiento GPS en la aplicación externa de ejercicio físico. + La autoexportación está activada. + La autoexportación no está activada. + La autoexportación ha sido programada (originalmente) para %1$s + La autoexportación no ha sido programada. + preconfigurando la posición a %s + Última autoexportación: %1$s + No se ha podido entender la ubicación. Probablemente un problema del nuevo sistema de permisos de Android. Lo más probable es que la autoexportación no funcione ahora. \ No newline at end of file From f9fbde3d13a22e771879653cadf3d07a751bd437 Mon Sep 17 00:00:00 2001 From: arjan-s Date: Sun, 20 Mar 2022 08:24:10 +0000 Subject: [PATCH 003/110] Translated using Weblate (Dutch) Currently translated at 100.0% (1468 of 1468 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nl/ --- app/src/main/res/values-nl/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 7acb91769..c16d969c4 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -1592,4 +1592,5 @@ AutoExport is ingeschakeld. AutoExport is (oorspronkelijk) gepland voor %1$s Laatste AutoExport: %1$s + Positie ingesteld op %s \ No newline at end of file From 4f5cef9e144a20af7b259554b8b9e3038a1533dd Mon Sep 17 00:00:00 2001 From: HenRy Date: Wed, 23 Mar 2022 09:14:16 +0000 Subject: [PATCH 004/110] Translated using Weblate (German) Currently translated at 100.0% (1469 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/de/ --- app/src/main/res/values-de/strings.xml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c7a592dad..02875ad3a 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1593,4 +1593,13 @@ Dient zum Starten/Stoppen der GPS-Track-Aufzeichnung in der externen Fitness-App. Android-Benachrichtigungseinstellungen setze position auf %s - + Fitness-App Tracking Stopp + Fitness-App Tracking Start + Autom. Export ist aktiviert. + Autom. Export ist deaktiviert. + Autom. Export wurde (ursprünglich) geplant für %1$s + Autom. Export wurde nicht geplant. + Aufleuchten bei neuer Benachrichtigung + Letzter autom. Export: %1$s + Standort ermittelt nicht möglich. Wahrscheinlich ein Problem des neueren Android-Berechtigungssystems. Höchstwahrscheinlich funktioniert der autom. Export jetzt nicht. + \ No newline at end of file From 1495772f9ff4c822d31d33d52a8c1754e8fb7518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vinc=C3=A8n=20PUJOL?= Date: Tue, 22 Mar 2022 20:12:41 +0000 Subject: [PATCH 005/110] Translated using Weblate (French) Currently translated at 100.0% (1469 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/fr/ --- app/src/main/res/values-fr/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 6e3c5c682..28436286a 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1596,4 +1596,5 @@ Temps de sommeil préféré en heures L\'export automatique est désactivé. L\'emplacement n\'a pas pu être détecté. Probablement un problème avec les nouvelles permissions du système Android. Très probablement, l\'export automatique ne fonctionne pas actuellement. pré-configuration de la position à %s + S\'allumer pour une nouvelle notification \ No newline at end of file From 8095b8948d0f47fbcb5e98c09512167913386273 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Wed, 23 Mar 2022 04:52:40 +0000 Subject: [PATCH 006/110] Translated using Weblate (Hebrew) Currently translated at 100.0% (1469 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 9fe7ad229..de312adc6 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -1592,4 +1592,5 @@ הייצוא האוטומטי תוזמן (במקור) ל־%1$s לא ניתן לפענח את המיקום. כנראה תקלה במערכת ההרשאות החדשה של Android. סביר להניח שהייצוא האוטומטי לא עובד כרגע. המיקום מוגדר מראש לכדי %s + הארה עם התראות חדשות \ No newline at end of file From d132037d8dee1c7b3a4c34322fd15803e9d08417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Wed, 23 Mar 2022 08:06:51 +0000 Subject: [PATCH 007/110] Translated using Weblate (Turkish) Currently translated at 100.0% (1469 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/tr/ --- app/src/main/res/values-tr/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 3a2ab4b7b..2a24bc272 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -1609,4 +1609,5 @@ Otomatik dışa aktarma etkin. Konum anlaşılamadı. Bu, muhtemelen daha yeni bir Android izin sistemi sorunudur. Büyük olasılıkla, otomatik dışa aktarma şu anda çalışmıyor. konumu %s olarak ön ayarlama + Yeni bildirimde ışığı aç \ No newline at end of file From 0f837393efc149376b0dbe054f54cdb6b801ad8b Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 22 Mar 2022 22:29:57 +0000 Subject: [PATCH 008/110] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1469 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/uk/ --- app/src/main/res/values-uk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 1b8d399aa..51a330b34 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1600,4 +1600,5 @@ Останній автоекспорт: %1$s Не вдалося встановити місцеперебування. Ймовірно, проблема з новішою системою дозволів Android. Швидше за все, автоекспорт зараз не працює. попереднє встановлення розташування на %s + Засвітлювати за нового сповіщення \ No newline at end of file From f007e362d28c444cc1e0fe05256a1652ec3d5be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Wed, 23 Mar 2022 01:42:23 +0000 Subject: [PATCH 009/110] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1469 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index ea6d5dcdf..d866c5f8e 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1598,4 +1598,5 @@ 自动导出未开启。 自动导出已开启。 预设位置为 %s + 有新通知时亮起 \ No newline at end of file From 1b7d71837920f26d466dd6dfb6e9d6751790844e Mon Sep 17 00:00:00 2001 From: arjan-s Date: Fri, 25 Mar 2022 07:48:14 +0000 Subject: [PATCH 010/110] Translated using Weblate (Dutch) Currently translated at 100.0% (1469 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nl/ --- app/src/main/res/values-nl/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index c16d969c4..152ea63fd 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -1593,4 +1593,5 @@ AutoExport is (oorspronkelijk) gepland voor %1$s Laatste AutoExport: %1$s Positie ingesteld op %s + Scherm oplichten bij nieuwe melding \ No newline at end of file From e1b0b9f4a94de2e164ddb6a93dbd9c9d786446f1 Mon Sep 17 00:00:00 2001 From: Aprilhoomie Date: Fri, 25 Mar 2022 00:20:29 +0000 Subject: [PATCH 011/110] Translated using Weblate (Persian) Currently translated at 10.5% (155 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/fa/ --- app/src/main/res/values-fa/strings.xml | 86 ++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 6c9da732f..7b72ea164 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -145,4 +145,90 @@ اطلاعات باتری تعیین نام مستعار جستجو برای %1$s؟ + خاموش کردن + تایید خاموش کردن + آیا مطمئن هستید که میخواهید دستگاه خاموش شود؟ + اطلاعات فعالیت روی کارت دستگاه + خواب + انتخاب جزئیات فعالیت‌های نمایش داده شده روی کارت‌های دستگاه + نمایش تعداد کل قدم‌ها + شما در حال نصب فرمویر (Firmware) %s بر روی دستگاه می بند پنج (mi band 5) خود می‌باشید. +\n +\nلطفا از نصب فایل با پسوند .fw و پس از آن فایل با پسوند .res و اطمینان حاصل فرمایید. ساعت شما پس از نصب فایل با پسوند .fw راه‌اندازی مجدد (ری‌استارت) خواهد شد. +\n +\nیادداشت: درصورتی که فایل با فرمت .res شما دقیقا مشابه فایلِ از پیش نصب شده می‌باشد نیازی به نصب مجدد آن نیست. +\n +\nبا مسئولیت خودتان ادامه دهید! + شما در حال نصب فرمویر (Firmware) %s بر روی دستگاه امیزفیت کور ۲ (Amazfit core 2) خود می‌باشید. +\n +\nلطفا از نصب فایل با پسوند .fw و پس از آن فایل با پسوند .res اطمینان حاصل فرمایید. ساعت شما پس از نصب فایل با پسوند .fw راه‌اندازی مجدد (ری‌استارت) خواهد شد. +\n +\nیادداشت: درصورتی که فایل با فرمت .res شما دقیقا مشابه فایلِ از پیش نصب شده می‌باشد نیازی به نصب مجدد آن نیست. +\n +\nبا مسئولیت خودتان ادامه دهید! +\n +\nکاملا تست نشده، در صورتی که نام دستگاه شما \"Amazfit Band 2\" می‌باشد، ممکن است نیاز داشته باشید که یک فرمویر BEATS_W روی دستگاه خود بریزید. + شما در حال نصب فرمویر (Firmware) %s بر روی دستگاه امیزفیت تی رکس (Amazfit T-REX) خود می‌باشید. +\n +\nلطفا از نصب فایل با پسوند .fw و پس از آن فایل با پسوند .res و در نهایت فایل با پسوند .gps اطمینان حاصل فرمایید. ساعت شما پس از نصب فایل با پسوند .fw راه‌اندازی مجدد (ری‌استارت) خواهد شد. +\n +\nیادداشت: درصورتی که فایل‌های با فرمت .res و .gps شما دقیقا مشابه فایلِ از پیش نصب شده می‌باشد نیازی به نصب مجدد آن نیست. +\n +\nبا مسئولیت خودتان ادامه دهید! + انتخاب تمام اپلیکیشن‌ها + تنظیمات اعلان‌ها + حذف انتخاب تمام اپلیکیشن‌ها + شما در حال نصب سیستم‌عامل (Firmware) %s بر روی دستگاه امیزفیت بیپ لایت (Amazfit bip lite) خود می‌باشید. +\n +\nلطفا از نصب فایل با پسوند .fw و پس از آن فایل با پسوند .res اطمینان حاصل فرمایید. ساعت شما پس از نصب فایل با پسوند .fw راه‌اندازی مجدد (ری‌استارت) خواهد شد. +\n +\nیادداشت: درصورتی که فایل با فرمت .res شما دقیقا مشابه فایلِ از پیش نصب شده می‌باشد نیازی به نصب مجدد آن نیست. +\n +\nبا مسئولیت خودتان ادامه دهید! + مسافت با استفاده از تعداد قدم‌ها و طول هر قدم (که از بخش درباره شما در تنظیمات قابل تغییر است) محاسبه می‌شود + نمایش اطلاعات فعالیت روی کارت‌های دستگاه + نمایش مدت خواب + نمایش تعداد قدم‌های فعلی، مسافت طی شده یا میزان خواب روی کارت دستگاه + شما در حال نصب فرمویر (Firmware) %s بر روی دستگاه می بند شش (mi band 6) خود می‌باشید. +\n +\nلطفا از نصب فایل با پسوند .fw و پس از آن فایل با پسوند .res و اطمینان حاصل فرمایید. ساعت شما پس از نصب فایل با پسوند .fw راه‌اندازی مجدد (ری‌استارت) خواهد شد. +\n +\nیادداشت: درصورتی که فایل با فرمت .res شما دقیقا مشابه فایلِ از پیش نصب شده می‌باشد نیازی به نصب مجدد آن نیست. +\n +\nبا مسئولیت خودتان ادامه دهید! + شما در حال نصب فرمویر (Firmware) %s بر روی دستگاه امیزفیت جی تی آر (Amazfit GTR) خود می‌باشید. +\n +\nلطفا از نصب فایل با پسوند .fw و پس از آن فایل با پسوند .res و در نهایت فایل با پسوند .gps اطمینان حاصل فرمایید. ساعت شما پس از نصب فایل با پسوند .fw راه‌اندازی مجدد (ری‌استارت) خواهد شد. +\n +\nیادداشت: درصورتی که فایل‌های با فرمت .res و .gps شما دقیقا مشابه فایلِ از پیش نصب شده می‌باشد نیازی به نصب مجدد آن نیست. +\n +\nبا مسئولیت خودتان ادامه دهید! + شما در حال نصب فرمویر (Firmware) %s بر روی دستگاه امیزفیت جی تی اس (Amazfit GTS) خود می‌باشید. +\n +\nلطفا از نصب فایل با پسوند .fw و پس از آن فایل با پسوند .res و در نهایت فایل با پسوند .gps اطمینان حاصل فرمایید. ساعت شما پس از نصب فایل با پسوند .fw راه‌اندازی مجدد (ری‌استارت) خواهد شد. +\n +\nیادداشت: درصورتی که فایل‌های با فرمت .res و .gps شما دقیقا مشابه فایلِ از پیش نصب شده می‌باشد نیازی به نصب مجدد آن نیست. +\n +\nبا مسئولیت خودتان ادامه دهید! + شما در حال نصب فرمویر (Firmware) %s بر روی دستگاه امیزفیت ورج لایت (Amazfit verge lite) خود می‌باشید. +\n +\nلطفا از نصب فایل با پسوند .fw و پس از آن فایل با پسوند .res و در نهایت فایل با پسوند .gps اطمینان حاصل فرمایید. ساعت شما پس از نصب فایل با پسوند .fw راه‌اندازی مجدد (ری‌استارت) خواهد شد. +\n +\nیادداشت: درصورتی که فایل‌های با فرمت .res و .gps شما دقیقا مشابه فایلِ از پیش نصب شده می‌باشد نیازی به نصب مجدد آن نیست. +\n +\nبا مسئولیت خودتان ادامه دهید! + شما در حال نصب فرمویر (Firmware) %s بر روی دستگاه می بند چهار (mi band 4) خود می‌باشید. +\n +\nلطفا از نصب فایل با پسوند .fw و پس از آن فایل با پسوند .res و اطمینان حاصل فرمایید. ساعت شما پس از نصب فایل با پسوند .fw راه‌اندازی مجدد (ری‌استارت) خواهد شد. +\n +\nیادداشت: درصورتی که فایل با فرمت .res شما دقیقا مشابه فایلِ از پیش نصب شده می‌باشد نیازی به نصب مجدد آن نیست. +\n +\nبا مسئولیت خودتان ادامه دهید! + شما در حال نصب فرمویر (Firmware) %s بر روی دستگاه امیزفیت ایکس (Amazfit X) خود می‌باشید. +\n +\nلطفا از نصب فایل با پسوند .fw و پس از آن فایل با پسوند .res و اطمینان حاصل فرمایید. ساعت شما پس از نصب فایل با پسوند .fw راه‌اندازی مجدد (ری‌استارت) خواهد شد. +\n +\nیادداشت: درصورتی که فایل با فرمت .res شما دقیقا مشابه فایلِ از پیش نصب شده می‌باشد نیازی به نصب مجدد آن نیست. +\n +\nبا مسئولیت خودتان ادامه دهید! \ No newline at end of file From 267bb3f011f347f73998ea18cbf9f36f6eb896bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Fern=C3=A1ndez=20D=C3=ADaz?= Date: Wed, 30 Mar 2022 11:41:41 +0000 Subject: [PATCH 012/110] Translated using Weblate (Spanish) Currently translated at 100.0% (1469 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/es/ --- app/src/main/res/values-es/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 49304fe14..4ecbeec37 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1598,4 +1598,5 @@ preconfigurando la posición a %s Última autoexportación: %1$s No se ha podido entender la ubicación. Probablemente un problema del nuevo sistema de permisos de Android. Lo más probable es que la autoexportación no funcione ahora. + Encender al recibir una notificación nueva \ No newline at end of file From 9c6ba34c99c0c47ed1799cd68ee15a6af702a60d Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Wed, 30 Mar 2022 17:57:39 +0000 Subject: [PATCH 013/110] Translated using Weblate (Croatian) Currently translated at 99.1% (1457 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/hr/ --- app/src/main/res/values-hr/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 711a0edb3..813ad6637 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -1557,4 +1557,17 @@ Amazfit Pop Pro Ništa Nepoznato + Atmosferski tlak + Analiziranje … + Postavke obavijesti za Android + Zadnji automatski izvoz: %1$s + Automatski izvoz je deaktiviran. + Automatski izvoz nije aktiviran. + Automatski izvoz je (izvorno) planiran za %1$s + Automatski izvoz nije planiran. + Optimiraj + Pokretanje … + Nije pokrenuto + Mjerenje atmostferskog tlaka … + Dovršavanje … \ No newline at end of file From 28a2573f8d8d549c7967822e98d18e7b5a1d4f99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Thu, 31 Mar 2022 16:58:25 +0000 Subject: [PATCH 014/110] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 91.5% (1345 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nb_NO/ --- app/src/main/res/values-nb-rNO/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 89b097f23..18f6e3e8b 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -1595,4 +1595,5 @@ Auto-eksport er ikke planlagt. Forsto ikke plassering. Antagelig er dette et tilgangsproblem i Android. Mest sannsynlig fungerer ikke auto-eksport nå. forhåndsinnstiller posisjon til %s + Slå på lys ved nye merknader \ No newline at end of file From d8c8a068d8bee987154ddb1ea1b990f9842ea040 Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Thu, 31 Mar 2022 11:21:10 +0000 Subject: [PATCH 015/110] Translated using Weblate (Croatian) Currently translated at 100.0% (1469 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/hr/ --- app/src/main/res/values-hr/strings.xml | 30 ++++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 813ad6637..11e483392 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -405,9 +405,9 @@ Fokusiranje na glas Razina ambijentalnog zvuka Položaj zvuka - Prednji - Prednji lijevi - Stražnji desni + Sprijeda + Sprijeda lijevo + Straga desno Surround način rada Isključeno Arena @@ -424,7 +424,7 @@ Prilagođeno unaprijed postavljeno 1 Prilagođeno unaprijed postavljeno 2 400 - 1000 + 1.000 16.000 Čisti bas Upravljanje senzorom na dodir @@ -502,8 +502,8 @@ Upozorenje! Donji gumb dvostruko min/mi - Prednji desni - Stražnji lijevi + Sprijeda desno + Straga lijevo Povezivanje s %1$s odmah nije uspjelo. Pokušavam se povezati s: %1$s Omogućite Bluetooth za otkrivanje uređaja. @@ -1007,7 +1007,7 @@ Upravljanje ambijentalnim zvukom Isključeno Poništavanje buke - Smanjenje šuma vjetra + Smanjenje buke vjetra Uzbuđeno Ostalo Sustav @@ -1049,8 +1049,8 @@ Odbacite pozive sa sata SMS porukom 100 koraka Meko - 2500 - 6300 + 2.500 + 6.300 Vrijeme čekanja ažuriranja u minutama: Sakrij tekst nakon isteka: Bešumno @@ -1570,4 +1570,16 @@ Nije pokrenuto Mjerenje atmostferskog tlaka … Dovršavanje … + Mjerenje stanja nošenja … + Nije bilo moguće razumjeti lokaciju. Vjerojatno se radi o problemu novijeg Android sustava dozvola. Najvjerojatnije automatski izvoz sada ne radi. + Optimizator poništavanje buke + Optimizator poništavanje buke + Koristi slušalice kao obično. Ako se stanje nošenja ili atmosferski tlak promijene, ponovo pokreni optimizator. + Pritisni za pokretanje optimizatora poništavanja buke. + Pokretanje praćenja aplikacije za fitness + Prekid praćenja aplikacije za fitness + Ime OpenTracks paketa + predpodešavanje položaja na %s + Zasvijetli pri novoj obavijesti + Koristi se za pokretanje/prekidanje snimanja GPS zapisa u vanjskoj aplikaciji za fitness. \ No newline at end of file From 9c851699e832cedcdf424dc83ed03485da825cb8 Mon Sep 17 00:00:00 2001 From: ifurther Date: Mon, 4 Apr 2022 15:44:27 +0000 Subject: [PATCH 016/110] Translated using Weblate (Chinese (Traditional)) Currently translated at 45.4% (668 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 1c761d590..c0361c7a3 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -688,4 +688,17 @@ 根據系統 藍芽掃描: 低功耗藍芽掃描: + 您即將在您的小米手環6上安裝韌體 %s +\n +\n請確定先安裝 .fw 檔,然後再安裝 .res 檔。您的手環將在安裝完 .fw 檔後重新啟動。 +\n +\n注意:如果您安裝的是與先前同樣的版本,您就不必再安裝 .res 檔。 +\n +\n過程中的風險請自負! + 新通知时亮起 + 您將要在Amazfit Neo上安裝%s固件。 +\n +\n安裝 .fw 檔後,您的頻帶將重新啟動。 +\n +\n過程中的風險請自負! \ No newline at end of file From 469e082e58a3e7e08e86c1f15ada512d534c48f0 Mon Sep 17 00:00:00 2001 From: ifurther Date: Tue, 5 Apr 2022 14:38:34 +0000 Subject: [PATCH 017/110] Translated using Weblate (Chinese (Traditional)) Currently translated at 45.5% (669 of 1469 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hant/ --- app/src/main/res/values-zh-rTW/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index c0361c7a3..d31c63536 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -698,7 +698,14 @@ 新通知时亮起 您將要在Amazfit Neo上安裝%s固件。 \n -\n安裝 .fw 檔後,您的頻帶將重新啟動。 +\n安裝 .fw 檔後,您的手環將重新啟動。 +\n +\n過程中的風險請自負! + 您將要在Amazfit X上安裝%s固件。 +\n +\n請確定先安裝 .fw 檔,然後再安裝 .res 檔。您的手環將在安裝完 .fw 檔後重新啟動。 +\n +\n注意:如果您安裝的是與先前同樣的版本,您就不必再安裝 .res 檔。 \n \n過程中的風險請自負! \ No newline at end of file From 1c6967e1ec2635fb04f0b6297585d24f223206d2 Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Fri, 8 Apr 2022 11:24:30 +0000 Subject: [PATCH 018/110] Translated using Weblate (German) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/de/ --- app/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 02875ad3a..f67e7a61d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1602,4 +1602,5 @@ Aufleuchten bei neuer Benachrichtigung Letzter autom. Export: %1$s Standort ermittelt nicht möglich. Wahrscheinlich ein Problem des neueren Android-Berechtigungssystems. Höchstwahrscheinlich funktioniert der autom. Export jetzt nicht. + E-mail \ No newline at end of file From 02241702c0d71f1e9704fec2baf820b153cb91b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vinc=C3=A8n=20PUJOL?= Date: Fri, 8 Apr 2022 06:09:44 +0000 Subject: [PATCH 019/110] Translated using Weblate (French) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/fr/ --- app/src/main/res/values-fr/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 28436286a..72fc51142 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1597,4 +1597,5 @@ Temps de sommeil préféré en heures L\'emplacement n\'a pas pu être détecté. Probablement un problème avec les nouvelles permissions du système Android. Très probablement, l\'export automatique ne fonctionne pas actuellement. pré-configuration de la position à %s S\'allumer pour une nouvelle notification + Email \ No newline at end of file From f8f43a47ca84ddf2ee5d127793da34dee16bb4c6 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Fri, 8 Apr 2022 08:22:15 +0000 Subject: [PATCH 020/110] Translated using Weblate (Hebrew) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index de312adc6..e3a3dc0e1 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -1593,4 +1593,5 @@ לא ניתן לפענח את המיקום. כנראה תקלה במערכת ההרשאות החדשה של Android. סביר להניח שהייצוא האוטומטי לא עובד כרגע. המיקום מוגדר מראש לכדי %s הארה עם התראות חדשות + דוא״ל \ No newline at end of file From 13cae08afc67f32783cec47d875e4483d9c704df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Fri, 8 Apr 2022 04:37:21 +0000 Subject: [PATCH 021/110] Translated using Weblate (Turkish) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/tr/ --- app/src/main/res/values-tr/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 2a24bc272..b316aaaf5 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -1610,4 +1610,5 @@ Konum anlaşılamadı. Bu, muhtemelen daha yeni bir Android izin sistemi sorunudur. Büyük olasılıkla, otomatik dışa aktarma şu anda çalışmıyor. konumu %s olarak ön ayarlama Yeni bildirimde ışığı aç + E-posta \ No newline at end of file From c5a2a71e54a2dd0228b52c99b2645f1aee6eec6e Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Thu, 7 Apr 2022 21:18:00 +0000 Subject: [PATCH 022/110] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/uk/ --- app/src/main/res/values-uk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 51a330b34..8ea3305e8 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1601,4 +1601,5 @@ Не вдалося встановити місцеперебування. Ймовірно, проблема з новішою системою дозволів Android. Швидше за все, автоекспорт зараз не працює. попереднє встановлення розташування на %s Засвітлювати за нового сповіщення + Е-пошта \ No newline at end of file From e8211d1cbed0897ae8c2df7e75b0afd66f739786 Mon Sep 17 00:00:00 2001 From: arjan-s Date: Sat, 9 Apr 2022 07:03:54 +0000 Subject: [PATCH 023/110] Translated using Weblate (Dutch) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nl/ --- app/src/main/res/values-nl/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 152ea63fd..afc1c40e5 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -1594,4 +1594,5 @@ Laatste AutoExport: %1$s Positie ingesteld op %s Scherm oplichten bij nieuwe melding + E-mail \ No newline at end of file From 041bc25d97dd2aee9caa05591604d5c6e3772867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Fri, 8 Apr 2022 02:26:35 +0000 Subject: [PATCH 024/110] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d866c5f8e..313f273be 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1599,4 +1599,5 @@ 自动导出已开启。 预设位置为 %s 有新通知时亮起 + 电子邮件 \ No newline at end of file From aa34c432954c530aa0cc6d40ba9b52b56a2d06be Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Fri, 8 Apr 2022 11:11:44 +0000 Subject: [PATCH 025/110] Translated using Weblate (Croatian) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/hr/ --- app/src/main/res/values-hr/strings.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 11e483392..56443598a 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -1543,11 +1543,11 @@ Visoka Niska Fokusiranje na glas - Pauza + Vremensko ograničenje Isključeno - Kratka (15 s) - Standardna (30 s) - Duga (1 min) + Kratko (15 s) + Standardno (30 s) + Dugo (1 min) Poveži se na dva uređaja istovremeno Speak-to-chat Informacije urađaja @@ -1582,4 +1582,5 @@ predpodešavanje položaja na %s Zasvijetli pri novoj obavijesti Koristi se za pokretanje/prekidanje snimanja GPS zapisa u vanjskoj aplikaciji za fitness. + E-mail \ No newline at end of file From 6bfd4991d4fe6467d73bdf662d95685c341a1b9f Mon Sep 17 00:00:00 2001 From: nautilusx Date: Mon, 11 Apr 2022 07:15:11 +0000 Subject: [PATCH 026/110] Translated using Weblate (German) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/de/ --- app/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f67e7a61d..c8acf6e93 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1602,5 +1602,5 @@ Aufleuchten bei neuer Benachrichtigung Letzter autom. Export: %1$s Standort ermittelt nicht möglich. Wahrscheinlich ein Problem des neueren Android-Berechtigungssystems. Höchstwahrscheinlich funktioniert der autom. Export jetzt nicht. - E-mail + E-Mail \ No newline at end of file From a07e942cf530f23d11a2fe6f655fb71a990fab7c Mon Sep 17 00:00:00 2001 From: Kintu Date: Thu, 14 Apr 2022 10:08:24 +0000 Subject: [PATCH 027/110] Translated using Weblate (Catalan) Currently translated at 89.5% (1317 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ca/ --- app/src/main/res/values-ca/strings.xml | 92 ++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index dfd01fa43..0b26dcf32 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -443,9 +443,14 @@ Desa les dades \"tal qual\", tot augmentant l\'ús de la base de dades per tal de permetre possibles interpretacions més tard. Gestió de dades Gestió de dades - Les operacions de base de dades fan servir el següent camí al vostre aparell. -\nAquest camí és accessible des d\'altres aparells Android i des del vostre ordinador. -\nQuan exporteu una base de dades, la trobareu aquí, i quan vulgueu importar una base de dades, heu de deixar els fitxers també aquí: + Les operacions d\'exportació/importació fan servir el següent camí (vegeu a sota) cap a un directori al vostre aparell. Aquest directori és accessible des d\'altres aparells Android i des del vostre ordinador. Tingueu en compte que aquest directori i tots els seus fitxers seran esborrats si desinstal·leu Gadgetbridge. Les dades inclouen: +\n Export_preference - configuració global +\n Export_preference_MAC - configuració específica de l\'aparell +\n Gadgetbridge - base de dades d\'activitat i aparell +\n Gadgetbridge_date - base de dades exportada en una data +\n *.gpx - gravacions GPS +\n *.log - fitxers de registre +\nTrobeu els vostres fitxers exportats (o deseu els fitxers que volgueu importar) aquí: Esborra la base de dades antiga No es pot accedir al camí d\'exportació. Si us plau, contacteu els desenvolupadors. S\'ha exportat a: %1$s @@ -1277,7 +1282,7 @@ Nombre d\'esdeveniments del calendari que seran sincronitzats Configureu quan l\'aparell pitarà Preconfiguracions - Informació d\'activitat a la tarja de l\'aparell + Informació d\'activitat a la targeta de l\'aparell Configuració per aplicació Useu la llista d\'aplicacions per a ... Rebutgeu les notificacions de les aplicacions triades @@ -1352,4 +1357,83 @@ Prendre mesures durant el son (per desactivar-lo completament, habiliteu el moviment relatiu i establiu tots els valors a 0) Previsualització del rellotge + Desconegut + Inicia + Edició de la pista GPX enllaçada + Detecció intraorella + So ambiental + Pressió atmosfèrica + ### ft + ###.# mi + ###.# km + Detecta aparells no suportats + Configuració incompleta, giny no afegit + Activa la vibració + Freqüència de mesures + Auricular esquerre + Auricular dret + Frontal esquerra + ### m + Ample: + Menú + automàtic + pregunta + Afegeix aparell de prova + Estàs segur que vols apagar l\'aparell\? + Mode de privacitat de missatges + Amazfit Pop + Amazfit Pop Pro + NO SUPORTAT + 2n fus horari + Informació de l\'aparell + Reducció de soroll de vent + Optimitza + Minuts actiu + Senderisme + To de ping + Escull quins detalls d\'activitat es mostren a la targeta de l\'aparell + Mostra informació d\'activitat a la targeta de l\'aparell + Mostra les passes, la distància o el son actuals a la targeta de l\'aparell + Sony SWR12 + índex swolf + Escaneig Bluetooth: + Escaneig Bluetooth LE: + Opcions de detecció i emparellament + Opcions tàctils + cap + Volum ambiental + L\'exportació automàtica està activada. + Última exportació automàtica: %1$s + L\'exportació automàtica no està activada. + L\'exportació automàtica està programada (originalment) per a %1$s + L\'exportació automàtica no ha sigut programada. + Res + Calibra les manetes del rellotge + Actualització parcial (en minuts): + Galaxy Buds + Galaxy Buds Live + Nothing Ear (1) + Bose QC35 + VESC + Apaga + Configuració de notificacions Android + Apaga + Neteja la pista GPX + Sony WF-SP800N + Correu electrònic + Sou a punt d\'instal·lar la següent caràtula: +\n +\n%1$s +\nVersió %2$s per %3$s +\n + Domyos T540 + Escalada + Selecciona la pista GPX + Sony WH-1000XM4 + Confirma %s + Actualització completa (en minuts): + Cancel·lació de soroll + Frontal dreta + Receptor GPX Gadgetbridge + Cancel·lació de soroll activa \ No newline at end of file From 7f2d55a1f07bb0ba7c1c8f808ddbabbdbf6ff3f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Fern=C3=A1ndez=20D=C3=ADaz?= Date: Sat, 16 Apr 2022 15:12:48 +0000 Subject: [PATCH 028/110] Translated using Weblate (Spanish) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/es/ --- app/src/main/res/values-es/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 4ecbeec37..1cb42b9ca 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1599,4 +1599,5 @@ Última autoexportación: %1$s No se ha podido entender la ubicación. Probablemente un problema del nuevo sistema de permisos de Android. Lo más probable es que la autoexportación no funcione ahora. Encender al recibir una notificación nueva + Correo electrónico \ No newline at end of file From d0623ccd4e3824a1b1a4d1bfc9d3814305d63124 Mon Sep 17 00:00:00 2001 From: Michal L Date: Sat, 16 Apr 2022 17:29:16 +0000 Subject: [PATCH 029/110] Translated using Weblate (Polish) Currently translated at 99.7% (1467 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/pl/ --- app/src/main/res/values-pl/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index bed0b2fe6..6eafd0291 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -1604,4 +1604,6 @@ Zatrzymanie śledzenia aplikacji fitness Wstępne ustawienie położenia na %s Lokalizacja nie jest dostępna. Najprawdopodobniej jest to spowodowane nowym systemem uprawnień Androida. Prawdopodobnie automatyczny eksport teraz nie działa. + Podświetlanie nowych powiadomień + E-mail \ No newline at end of file From 9fdb947ec9ac93dac3b5bab23271299b1670e093 Mon Sep 17 00:00:00 2001 From: Shimoon Horanek Date: Tue, 19 Apr 2022 10:42:59 +0000 Subject: [PATCH 030/110] Translated using Weblate (Czech) Currently translated at 99.9% (1469 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/cs/ --- app/src/main/res/values-cs/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 507730638..71b747c15 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -1595,4 +1595,5 @@ přednastavuji pozici na %s AutoExport není aktivní. AutoExport zatím nebyl naplánován. + E-mail \ No newline at end of file From 63f2cfa336a525df29ef1dc07efbdb8972ada2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Gir=C3=B3n?= Date: Tue, 19 Apr 2022 15:28:09 +0000 Subject: [PATCH 031/110] Translated using Weblate (Catalan) Currently translated at 91.2% (1341 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ca/ --- app/src/main/res/values-ca/strings.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 0b26dcf32..6a1b8e896 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -1436,4 +1436,28 @@ Frontal dreta Receptor GPX Gadgetbridge Cancel·lació de soroll activa + Botó superior doble + Botó central doble + Fes servir events del dispositiu per executar accions i emissions d\'Android + Sons de funcionament + Botó central llarg + Encendre la pantalla al agafar el dispositiu amb \"No molestar\" + Botó superior llarg + Botó inferior doble + Gambada màxima + Total recorregut + Timbre continu fals + Dibuixar cercles de widget + Gambada mínima + Botó central curt + Botó inferior curt + Botó superior curt + Configuració de Watchface + Paquet AGPS + Botó inferior llarg + No s\'ha entés la ubicació. És possible que sigui un problema de permissos del nou sistema Android. El més probable és que l\'autoexportació de dades no funcioni ara. + Els fitxers exportats a la carpeta d\'Exportar/Importar poden ser llegits per qualsevol aplicació al teu dispositiu. És possible que vulguis suprimir aquests fixters després de sincronitzar o fer una copia de seguretat. Assegura\'t de fer una copia abans d\'esborrar-los. Els fitxers GPX, les subcarpetes i la base de dades auto-exportada (si existeix) no s\'esborrarà. La carpeta d\'Exportar/Importar es troba a: + Emparellament de dispositius de companyia + Permetre que altres aplicacions d\'Android puguin sobre/escriure fitxers + Mitjana d\'avançada \ No newline at end of file From b564a6c8953094576ce86e67072ac108639da850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vinc=C3=A8n=20PUJOL?= Date: Thu, 21 Apr 2022 18:55:43 +0000 Subject: [PATCH 032/110] Translated using Weblate (French) Currently translated at 100.0% (1470 of 1470 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/fr/ --- app/src/main/res/values-fr/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 72fc51142..cd2b07501 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1062,7 +1062,7 @@ Temps de sommeil préféré en heures Longueur de la pause pour séparer les activités (minutes) Nombre de pas minimum par minute pour détecter une activité Nombre de pas minimum par minute pour détecter une course - Liste d\'activités + Activités du jour Avoir une activité et synchroniser l\'appareil. Aucune activité détectée. Lefun @@ -1130,7 +1130,7 @@ Temps de sommeil préféré en heures \nIntensité Durée d\'activité Distance - Pas réalisés + Pas réels Amazfit GTS 2 Casio GBX-100 Onglets visibles des tableaux From d386b01169af6c9feb45ac9de98f3fd73eaef960 Mon Sep 17 00:00:00 2001 From: vanous Date: Sat, 2 Apr 2022 16:49:09 +0200 Subject: [PATCH 033/110] Allow string resources for build variants to be customized via gradle --- app/build.gradle | 22 +++++++++++++- app/src/banglejs/res/values/strings.xml | 8 ----- app/src/main/AndroidManifest.xml | 3 +- app/src/main/res/layout/activity_about.xml | 2 +- app/src/main/res/values/strings.xml | 35 ++++++++++++++++++---- app/src/nightly/res/values/strings.xml | 4 --- app/src/nopebble/res/values/strings.xml | 4 --- 7 files changed, 54 insertions(+), 24 deletions(-) delete mode 100644 app/src/banglejs/res/values/strings.xml delete mode 100644 app/src/nightly/res/values/strings.xml delete mode 100644 app/src/nopebble/res/values/strings.xml diff --git a/app/build.gradle b/app/build.gradle index b7264498e..eb6da978e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -62,6 +62,11 @@ android { buildConfigField "String", "GIT_HASH_SHORT", "\"${getGitHashShort()}\"" buildConfigField "boolean", "INTERNET_ACCESS", "false" resValue "string", "pebble_content_provider", "com.getpebble.android.provider" + resValue "string", "app_name", "@string/application_name_generic" + resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_generic" + resValue "string", "about_activity_title", "@string/about_activity_title_generic" + resValue "string", "about_description", "@string/about_description_generic" + resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_generic" } signingConfigs { nightly { @@ -91,6 +96,11 @@ android { } proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" resValue "string", "pebble_content_provider", "com.getpebble.android.provider" + resValue "string", "app_name", "@string/application_name_main_nightly" + resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_main_nightly" + resValue "string", "about_activity_title", "@string/about_activity_title_main_nightly" + resValue "string", "about_description", "@string/about_description_main_nightly" + resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nightly" debuggable true } nopebble { @@ -104,6 +114,11 @@ android { } proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" resValue "string", "pebble_content_provider", "com.getpebble.android.nopebble.provider" + resValue "string", "app_name", "@string/application_name_main_nopebble" + resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_main_nopebble" + resValue "string", "about_activity_title", "@string/about_activity_title_main_nopebble" + resValue "string", "about_description", "@string/about_description_main_nopebble" + resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nopebble" debuggable true } @@ -139,7 +154,12 @@ android { versionNameSuffix "-banglejs" buildConfigField "boolean", "INTERNET_ACCESS", "true" // Disable pebble provider to allow Bangle.js Gadgetbridge to coexist with Gadgetbridge - resValue "string", "pebble_content_provider", "com.getpebble.android.nopebble.provider" + resValue "string", "pebble_content_provider", "com.getpebble.android.nopebble.bangle.provider" + resValue "string", "app_name", "@string/application_name_banglejs_main" + resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_banglejs_main" + resValue "string", "about_activity_title", "@string/about_activity_title_banglejs_main" + resValue "string", "about_description", "@string/about_description_banglejs_main" + resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_banglejs_main" } } diff --git a/app/src/banglejs/res/values/strings.xml b/app/src/banglejs/res/values/strings.xml deleted file mode 100644 index e965e9764..000000000 --- a/app/src/banglejs/res/values/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - Bangle.js Gadgetbridge - Bangle.js Gadgetbridge - About Bangle.js Gadgetbridge - Android companion app for Bangle.js built on top of the Gadgetbridge project, with added Internet Access. - Bangle.js running - diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index edf7b965e..a2078b549 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -69,7 +69,8 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:requestLegacyExternalStorage="true" - android:theme="@style/GadgetbridgeTheme"> + android:theme="@style/GadgetbridgeTheme" + tools:replace="android:label"> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8d65c4df6..b4c78e916 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,7 +1,35 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge + About Gadgetbridge + Cloudless copylefted libre replacement for closed source Android gadget apps from vendors. + Gadgetbridge running + + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + About Bangle.js Gadgetbridge + Android companion app for Bangle.js built on top of the Gadgetbridge project, with added Internet Access. + Bangle.js running + + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + About Bangle.js Gadgetbridge + Android companion app for Bangle.js built on top of the Gadgetbridge project, with added Internet Access. + Bangle.js running + + Gadgetbridge (Nightly) + Gadgetbridge Nightly + About Gadgetbridge Nightly + Cloudless copylefted libre replacement for closed source Android gadget apps from vendors. Nightly releases of Gadgetbridge. It cannot be installed if you already have either the Gadgetbridge or the Pebble app installed, due to a conflict in the Pebble provider. + Nightly GB running + + Gadgetbridge (Nightly, No Pebble provider) + Gadgetbridge Nightly No Pebble + About Gadgetbridge Nightly No Pebble + Cloudless copylefted libre replacement for closed source Android gadget apps from vendors. Nightly releases of Gadgetbridge. This version has the Pebble provider renamed to prevent conflicts, so some Pebble related integrations will not work, but it can be installed alongside existing Gadgetbridge installation. + Nightly NoPebble GB running + Settings Debug Quit @@ -368,7 +396,6 @@ Tap connected device for vibration Tap a device to connect Cannot connect. Bluetooth address invalid? - Gadgetbridge running Installing binary %1$d/%2$d Installation failed Installed @@ -1096,11 +1123,9 @@ About Version %s Commit %s - About Gadgetbridge GPX Receiver Gadgetbridge GPX file(s) received: Some file(s) already exist. Overwrite? - Cloudless copylefted libre replacement for closed source Android gadget apps from vendors. Core Team (in order of first code contribution) Contributors Andreas Shimokawa\nCarsten Pfeiffer\nDaniele Gobbetti diff --git a/app/src/nightly/res/values/strings.xml b/app/src/nightly/res/values/strings.xml deleted file mode 100644 index c4e5885c9..000000000 --- a/app/src/nightly/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Gadgetbridge (Nightly) - diff --git a/app/src/nopebble/res/values/strings.xml b/app/src/nopebble/res/values/strings.xml deleted file mode 100644 index 090f10a24..000000000 --- a/app/src/nopebble/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Gadgetbridge (Nightly, No Pebble provider) - From fea2d98bd172bef5d47c38ded89cd23234caed00 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 26 Apr 2022 15:29:05 +0100 Subject: [PATCH 034/110] Update strings for app_name/etc to '_generic' values to allow differently named apps - https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/2627 --- app/src/main/res/values-bg/strings.xml | 6 +++--- app/src/main/res/values-ca/strings.xml | 10 +++++----- app/src/main/res/values-cs/strings.xml | 10 +++++----- app/src/main/res/values-de/strings.xml | 10 +++++----- app/src/main/res/values-el/strings.xml | 10 +++++----- app/src/main/res/values-en-rGB/strings.xml | 10 +++++----- app/src/main/res/values-es/strings.xml | 10 +++++----- app/src/main/res/values-et/strings.xml | 10 +++++----- app/src/main/res/values-fa/strings.xml | 4 ++-- app/src/main/res/values-fi/strings.xml | 6 +++--- app/src/main/res/values-fr-rCA/strings.xml | 6 +++--- app/src/main/res/values-fr/strings.xml | 10 +++++----- app/src/main/res/values-gl/strings.xml | 6 +++--- app/src/main/res/values-he/strings.xml | 10 +++++----- app/src/main/res/values-hr/strings.xml | 10 +++++----- app/src/main/res/values-hu/strings.xml | 6 +++--- app/src/main/res/values-id/strings.xml | 6 +++--- app/src/main/res/values-it/strings.xml | 10 +++++----- app/src/main/res/values-ja/strings.xml | 8 ++++---- app/src/main/res/values-ka/strings.xml | 4 ++-- app/src/main/res/values-ko/strings.xml | 6 +++--- app/src/main/res/values-lt/strings.xml | 6 +++--- app/src/main/res/values-ml/strings.xml | 4 ++-- app/src/main/res/values-my/strings.xml | 4 ++-- app/src/main/res/values-nb-rNO/strings.xml | 10 +++++----- app/src/main/res/values-nl/strings.xml | 10 +++++----- app/src/main/res/values-pl/strings.xml | 10 +++++----- app/src/main/res/values-pt-rBR/strings.xml | 10 +++++----- app/src/main/res/values-pt/strings.xml | 10 +++++----- app/src/main/res/values-ro/strings.xml | 4 ++-- app/src/main/res/values-ru/strings.xml | 10 +++++----- app/src/main/res/values-sk/strings.xml | 6 +++--- app/src/main/res/values-sv/strings.xml | 4 ++-- app/src/main/res/values-tr/strings.xml | 10 +++++----- app/src/main/res/values-uk/strings.xml | 10 +++++----- app/src/main/res/values-vi/strings.xml | 6 +++--- app/src/main/res/values-zh-rCN/strings.xml | 10 +++++----- app/src/main/res/values-zh-rTW/strings.xml | 10 +++++----- 38 files changed, 151 insertions(+), 151 deletions(-) diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index e74f26fca..2976c5371 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -17,8 +17,8 @@ Обхват на Графиката Обхвата е Месец Обхвата е Седмица - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Настройки Дебъгване Изход @@ -228,7 +228,7 @@ Докоснете свързаното устройство за вибрации Докоснете устройство за свързване Не може да се установи връзка. Грешен Bluetooth адрес\? - Gadgetbridge работи + Gadgetbridge работи Инсталиране на двоичен файл %1$d/%2$d Инсталацията пропадна Инсталирано diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 6a1b8e896..2b4807b2c 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Configuració Depuració Surt @@ -174,7 +174,7 @@ Toca l\'aparell per fer-lo vibrar Toca un aparell per connectar-hi No es pot connectar. Potser la direcció Bluetooth és incorrecta\? - El Gadgetbridge està funcionant + El Gadgetbridge està funcionant S\'està instal·lant el binari %1$d/%2$d La instal·lació ha fallat Instal·lat @@ -913,7 +913,7 @@ Support d\'aparell addicional Col·laboradors Equip principal (en ordre de primera contribució de codi) - Substitut lliure, copyleft i sense núvol per a les aplicacions Android de codi tancat dels fabricants dels aparells. + Substitut lliure, copyleft i sense núvol per a les aplicacions Android de codi tancat dels fabricants dels aparells. No molestis SpO2 PAI @@ -1000,7 +1000,7 @@ ES REQUEREIX CLAU La ubicació ha d\'estar activada Enllaços - Quant a Gadgetbridge + Quant a Gadgetbridge Versió %s Quant a Última notificació diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 71b747c15..ef0c4a36a 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Nastavení Ladění Ukončit @@ -154,7 +154,7 @@ Dotkněte se zařízení pro vibrace Dotkněte se zařízení pro připojení Nelze připojit. Je BT adresa v pořádku? - Gadgetbridge běží + Gadgetbridge běží Instaluji soubor %1$d/%2$d Instalace selhala Instalace úspěšná @@ -915,8 +915,8 @@ Podpora dalších zařízení Přispěvatelé Centrální tým (v pořadí příspěvku prvního kódu) - Svobodná a lokální náhrada za uzavřenou aplikaci vašich hodinek/náramku. - O aplikaci Gadgetbridge + Svobodná a lokální náhrada za uzavřenou aplikaci vašich hodinek/náramku. + O aplikaci Gadgetbridge O aplikaci Světový Čas Použito s poskytovatelem počasí LineageOS. Ostatní verze Androidu vyžadují \"Weather Notification\" app. Více informací naleznete na Gadgetbridge wiki. diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c8acf6e93..e0dc57876 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Einstellungen Debug Beenden @@ -161,7 +161,7 @@ Tippe auf das verbundene Gerät, um es vibrieren zu lassen Tippe auf ein Gerät, um eine Verbindung herzustellen Keine Verbindung möglich. Bluetooth-Adresse ungültig\? - Gadgetbridge läuft + Gadgetbridge läuft Binärdatei %1$d/%2$d wird installiert Installation fehlgeschlagen Installiert @@ -923,8 +923,8 @@ Unterstützung zusätzlicher Geräte Beitragende Kernteam (Reihenfolge der ersten Mitwirkung am Code) - Cloudloser freier Ersatz für proprietäre Android-Gadget-Apps der Hersteller. - Über Gadgetbridge + Cloudloser freier Ersatz für proprietäre Android-Gadget-Apps der Hersteller. + Über Gadgetbridge Über Wird für den LineageOS Wetterdienst genutzt, andere Android-Versionen müssen eine Anwendung wie Weather notification nutzen. Mehr Informationen gibt es im Gadgetbride-Wiki. Weltzeituhr diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index cd82ac718..e4c50f513 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Ρυθμίσεις Αποσφαλμάτωση Έξοδος @@ -174,7 +174,7 @@ Πατήστε τη συνδεδεμένη συσκευή για δόνηση Πατήστε μία συσκευή για να συνδεθεί Δεν μπορεί να γίνει σύνδεση. Μήπως δεν είναι έγκυρη η διεύθυνση Bluetooth; - Το Gadgetbridge εκτελείται + Το Gadgetbridge εκτελείται Γίνεται εγκατάσταση των βιβλιοθηκών %1$d/%2$d Η εγκατάσταση απέτυχε Εγκατεστημένο @@ -901,8 +901,8 @@ Πρόσθετη υποστήριξη συσκευών Συντελεστές Βασική ομάδα (κατά σειρά μεγαλύτερης συνεισφοράς κώδικα) - Μια δωρεάν, ελεύθερου κώδικα και χωρίς πρόσβαση στο διαδίκτυο εφαρμογή Android για να αντικαταστήσει τις υπάρχουσες εφαρμογές κλειστού κώδικα των κατασκευαστών του smartwatch σας. - Σχετικά με το Gadgetbridge + Μια δωρεάν, ελεύθερου κώδικα και χωρίς πρόσβαση στο διαδίκτυο εφαρμογή Android για να αντικαταστήσει τις υπάρχουσες εφαρμογές κλειστού κώδικα των κατασκευαστών του smartwatch σας. + Σχετικά με το Gadgetbridge Σχετικά Παγκόσμιο Ρολόι Amazfit T-Rex diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index 401143723..953d8f9e2 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -684,7 +684,7 @@ Installed Installation failed Installing binary %1$d/%2$d - Gadgetbridge running + Gadgetbridge running Cannot connect. Bluetooth address invalid\? Tap a device to connect Tap connected device for vibration @@ -853,8 +853,8 @@ Quit Debug Settings - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Save raw activity files Workout Event Reminder @@ -1124,7 +1124,7 @@ Statistics Upper Button short Upper Button double - About Gadgetbridge + About Gadgetbridge GPX file(s) received: Some file(s) already exist. Overwrite\? Many thanks to all unlisted contributors for contributing code, translations, support, ideas, motivation, bug reports, money… ✊ @@ -1276,7 +1276,7 @@ Temperature Version %s About - Cloudless copylefted libre replacement for closed source Android gadget apps from vendors. + Cloudless copylefted libre replacement for closed source Android gadget apps from vendors. 30 days Time period Already bonded diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 1cb42b9ca..bf85b9cd1 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Configuración Depuración Salir @@ -161,7 +161,7 @@ Toque el dispositivo conectado para la vibración Toca un dispositivo para conectarlo No se puede conectar. ¿Dirección BT incorrecta? - Gadgetbridge funcionando + Gadgetbridge funcionando Instalando binario %1$d/%2$d Instalación fallida Instalado @@ -1093,8 +1093,8 @@ Soporte de dispositivos adicionales Colaboradores Equipo principal (por orden de primera contribución de código) - Sustitución sin nube y con copyleft de las aplicaciones de código cerrado para Android de los proveedores. - Acerca de Gadgetbridge + Sustitución sin nube y con copyleft de las aplicaciones de código cerrado para Android de los proveedores. + Acerca de Gadgetbridge Versión %s Acerca de Última notificación diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index c1dcfc880..d271cdd78 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Seaded Silumine Välju @@ -243,7 +243,7 @@ Puuduta ühendatud seadet värina tekitamiseks Puuduta seadet, et ühendada Ei saa ühendust. Vigane bluetooth aadress\? - Gadgetbridge töötab + Gadgetbridge töötab Binaarfaili %1$d/%2$d paigaldamine Paigaldamine nurjus Paigaldatud @@ -746,8 +746,8 @@ Täiendavate seadmete tugi Kaasaaitajad Tuumiktiim (järjestatud esimese koodirea kuupäeva järgi) - Tasuta ja pilvevaba asendus teie kantavate nutiseadmete tootjate rakendustele. - Gadgetbridge\'ist + Tasuta ja pilvevaba asendus teie kantavate nutiseadmete tootjate rakendustele. + Gadgetbridge\'ist Rakendusest Alumine nupp Keskmine nupp diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 7b72ea164..da08dba02 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -1,7 +1,7 @@ - گجت‌بریج - گجت‌بریج + گجت‌بریج + گجت‌بریج تنظیمات اشکال‌زدایی خروج diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index f2c7af838..820f5adff 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -3,8 +3,8 @@ Asetukset Synkronoi Löydä kadonnut laite - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Lopeta Lahjoita Ota ruutukaappaus @@ -447,7 +447,7 @@ Askeleiden historia Kokonaisaskeleet Tietoja - Tietoja Gadgetbridgestä + Tietoja Gadgetbridgestä Alkaen Päättyen Vastaamatta jääneen puhelun ilmoitus diff --git a/app/src/main/res/values-fr-rCA/strings.xml b/app/src/main/res/values-fr-rCA/strings.xml index b93cfdd6c..d588a524f 100644 --- a/app/src/main/res/values-fr-rCA/strings.xml +++ b/app/src/main/res/values-fr-rCA/strings.xml @@ -129,8 +129,8 @@ Calories Vibration Long - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge %d heure %d heures @@ -697,7 +697,7 @@ Installé Échec de l\'installation Installation du binaire %1$d/%2$d - Gadgetbridge est en fonctionnement + Gadgetbridge est en fonctionnement Tapez sur le périphérique pour le connecter Cliquez sur connecter pour envoyer une vibration Cliquez sur l\'appareil pour ouvrir le gestionnaire d’activité diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index cd2b07501..05adb2646 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Paramètres Déboguer Quitter @@ -161,7 +161,7 @@ Cliquez sur connecter pour envoyer une vibration Tapez sur le périphérique pour le connecter Connexion impossible. L’adresse Bluetooth est-elle valide ? - Gadgetbridge est en fonctionnement + Gadgetbridge est en fonctionnement Installation du binaire %1$d/%2$d Échec de l\'installation Installé @@ -1017,8 +1017,8 @@ Temps de sommeil préféré en heures Support d\'appareil supplémentaire Contributeurs Équipe principal (dans l\'ordre de la première contribution au code) - Un remplaçant libre et sans cloud aux applications Android propriétaires des fabricants de vos bracelets. - A propos de Gadgetbridge + Un remplaçant libre et sans cloud aux applications Android propriétaires des fabricants de vos bracelets. + A propos de Gadgetbridge A propos Horloge mondiale Stress diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 2947c1049..ae765d3aa 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Axustes Depuración Saír @@ -143,7 +143,7 @@ Toque nun dispositivo conectado para facelo Vibrar Toque nun dispositivo para conectar Non foi posíbel conectar. Enderezo Bluetooth inválido? - Gadgetbridge en execución + Gadgetbridge en execución Instalando binario %1$d/%2$d Fallou a instalación Instalado diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index e3a3dc0e1..aef1dbfbb 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge הגדרות ניפוי שגיאות יציאה @@ -147,7 +147,7 @@ נקישה על ההתקן המחובר לרטט יש לגעת בהתקן כדי להתחבר לא ניתן להתחבר. כתובת ה־Bluetooth שגויה? - Gadgetbridge פעיל + Gadgetbridge פעיל התקנת הבינרי %1$d/%2$d ההתקנה נכשלה ההתקנה הצליחה @@ -913,8 +913,8 @@ תמיכה במכשירים נוספים תורמים צוות הליבה (מסודרים לפי מועד תרומת הקוד הראשונה) - חלופה חופשית ונטולת ענן ליישומוני ה־Android לחפיצים עם הקוד הסגור של היצרנים. - על אודות Gadgetbridge + חלופה חופשית ונטולת ענן ליישומוני ה־Android לחפיצים עם הקוד הסגור של היצרנים. + על אודות Gadgetbridge על אודות משמש לספק מזג האוויר של LineageOS, גרסאות אחרות של Android צריכות להשתמש ביישומונים כמו „התראות מזג אוויר”. אפשר למצוא מידע נוסף בוויקי של Gadgetbridge. שעון עולמי diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 56443598a..4da3fec84 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -1,6 +1,6 @@ - Gadgetbridge + Gadgetbridge Muško Žensko Ostalo @@ -28,7 +28,7 @@ Postavi pseudonim Izlaz Debug - Gadgetbridge + Gadgetbridge Stvarno izbrisati staru bazu podataka aktivnosti\? Podaci aktivnosti koji nisu uvezeni će se izgubiti. Izbrisati staru bazu podataka aktivnosti\? Podaci izbrisani. @@ -1268,8 +1268,8 @@ Dodaj widget Postavljanje alarma za %1$02d:%2$02d Verzija %s - O Gadgetbridge - Zamjena za libre bez oblaka bez kopiranja za zatvorene aplikacije za Android gadgete od dobavljača. + O Gadgetbridge + Zamjena za libre bez oblaka bez kopiranja za zatvorene aplikacije za Android gadgete od dobavljača. Osnovni tim (po redoslijedu doprinosa prvog koda) Konfiguracija izgleda sata Promjena pozadinske slike @@ -1358,7 +1358,7 @@ \n \n \n Ovaj firmware je za HW reviziju: %s - Gadgetbridge je pokrenut + Gadgetbridge je pokrenut Dodirnite uređaj za povezivanje Test Nije povezano diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index d9cf5a1f6..36b660a49 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Beállítások Hibakeresés Kilépés @@ -157,7 +157,7 @@ Koppints az eszközre a rezgetéshez. Koppints az eszközre a csatlakozáshoz Nem lehet csatlakozni. Rossz Bluetooth cím? - A Gadgetbridge fut + A Gadgetbridge fut %1$d/%2$d bináris telepítése Sikertelen telepítés Telepítve diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index dd7f06e40..2f9a12290 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Pengaturan Keluar Donasi @@ -175,7 +175,7 @@ Kalori Penerima GPX Gadgetbridge Lokasi harus diaktifkan - Tentang Gadgetbridge + Tentang Gadgetbridge Versi %s Tentang Tautan diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index f6ab2f1c9..d7877fe9e 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Impostazioni Debug Esci @@ -158,7 +158,7 @@ Tocca il dispositivo connesso per la vibrazione tocca il dispositivo a cui connettersi Impossibile connettersi. Indirizzo Bluetooth non valido? - Gadgetbridge in esecuzione + Gadgetbridge in esecuzione Installazione del binario %1$d/%2$d Installazione fallita Installazione conclusa con successo @@ -884,8 +884,8 @@ Supporto a dispositivi aggiuntivi Contributori Team principale (ordinati in base al primo contributo di codice) - Un\'alternativa gratuita, libera e senza cloud alle applicazioni Android a sorgente chiusa del tuo dispositivo. - Su Gadgetbridge + Un\'alternativa gratuita, libera e senza cloud alle applicazioni Android a sorgente chiusa del tuo dispositivo. + Su Gadgetbridge Informazioni Ultima notifica Salva i dati raw (grezzi) delle attività diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 90f5245de..2e8deca6e 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1,7 +1,7 @@ - ガジェットブリッジ - ガジェットブリッジ + ガジェットブリッジ + ガジェットブリッジ 設定 デバッグ 終了 @@ -161,7 +161,7 @@ バイブレーションの接続されたデバイスをタップ 接続するデバイスをタップ 接続できません。 Bluetoothアドレスが無効ですか\? - ガジェットブリッジは実行中 + ガジェットブリッジは実行中 バイナリーのインストール中 %1$d/%2$d インストールに失敗しました インストールに成功しました @@ -708,7 +708,7 @@ 距離 キーが必要です 貢献者 - Gadgetbridgeについて + Gadgetbridgeについて について 最終通知 通勤 diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index b55601dd1..43984c98e 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge პარამეტრები შეწყვეტა დონაცია diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 35e2abd47..7afd8b2d9 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -1,7 +1,7 @@ - 가젯브릿지 - 가젯브릿지 + 가젯브릿지 + 가젯브릿지 설정 디버그 종료 @@ -77,7 +77,7 @@ 연결된 기기를 선택해 앱 관리자 실행 기기를 선택해 연결 연결할 수 없습니다. 블루투스 주소가 올바르지 않은 것 같습니다\? - 가젯브릿지 실행중 + 가젯브릿지 실행중 바이너리 설치중: %1$d/%2$d 설치 실패 설치됨 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index f466c9a57..3180dafc8 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Nustatymai Šalinti riktus Išeiti @@ -167,7 +167,7 @@ Bluetooth nepalaikomas. Bluetooth išjungtas. Bagstelėkite įrenginį, kad prisijungtumėte - Gadgetbridge paleistas + Gadgetbridge paleistas Instaluota Įrenginio paieška Stabdyti skenavimą diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 692c26523..7e0dca922 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -78,8 +78,8 @@ പുറത്തു കടക്കുക തെറ്റുകൾ തിരുത്തുക ക്രമീകരണങ്ങൾ - ഗാഡ്ജക്‌റ്റ് ബ്രിഡ്ജ് - ഗാഡ്ജക്‌റ്റ് ബ്രിഡ്ജ് + ഗാഡ്ജക്‌റ്റ് ബ്രിഡ്ജ് + ഗാഡ്ജക്‌റ്റ് ബ്രിഡ്ജ് ബാൻഡിൽ വൈബ്രേഷന്റെ കുറഞ്ഞ തീവ്രത പ്രവർത്തനക്ഷമമാക്കുക പവർ സേവിംഗ് മോഡ് ഹൃദയമിടിപ്പിന്റെ ആനുകാലിക യാന്ത്രിക അളവ് ഓഫുചെയ്യുന്നത് പ്രവർത്തന സമയം വർദ്ധിപ്പിക്കുന്നു ഇൻസ്റ്റാൾ ചെയ്ത അലാറത്തിന് മുമ്പുള്ള ഇടവേളയാണ് സ്മാർട്ട് അലാറം ഇടവേള. ഈ ഇടവേള ഉപകരണം ഉപയോക്താവിനെ ഉണർത്താൻ ഉറക്കത്തിന്റെ ഭാരം കുറഞ്ഞ ഘട്ടം കണ്ടെത്താൻ ശ്രമിക്കുന്നു diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml index 4caf4bc91..6b15aa624 100644 --- a/app/src/main/res/values-my/strings.xml +++ b/app/src/main/res/values-my/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge ခ်ိန္ညွိရန္ ျပစ္ခ်က္ ထြက္မည္ diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 18f6e3e8b..a4ec29f47 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -39,8 +39,8 @@ Svartelistede kalendere Fastvare-/program-installerer Du er i ferd med å installere %s. - Gadgetbru - Gadgetbru + Gadgetbru + Gadgetbru Dette vil slette enheten og all tilknyttet data! Du er i ferd med å installere %s-fastvaren på din Amazfit Bip. \n @@ -165,7 +165,7 @@ Trykk på tilkoblet enhet for vibrasjon Trykk på en enhet for å koble til Kan ikke koble til. Ugyldig Blåtannsadresse? - Gadgetbro kjører + Gadgetbro kjører Installerer binærfil %1$d/%2$d Installasjon mislyktes Installert @@ -902,7 +902,7 @@ Klarte ikke å starte bakgrunnstjeneste Ytterligere enhetsstøtte Bidragsytere - Om Gadgetbridge + Om Gadgetbridge Om Verdensklokke Stress @@ -1034,7 +1034,7 @@ Aktiver lav vibrasjonsintensitet på båndet Strømsparingsmodus slår av periodisk automatisk måling av hjertefrekvensen og øker dermed arbeidstiden Smart alarmintervall er intervall før installert alarm. I dette intervallet prøver enheten å oppdage den letteste søvnfasen for å våkne brukeren - Skyfri, gemenhetslig fri erstatning for den lukkede motsatsen for dine Android-slaveenheter. + Skyfri, gemenhetslig fri erstatning for den lukkede motsatsen for dine Android-slaveenheter. Sjekk og forespør tilganger selv om de ikke trengs umiddelbart. Skru av dette kun hvis enhetene dine ikke støtter noen av disse funksjonene. Å ikke innvilge tilganger kan forårsake problemer! Skrur på slaveenhets-API (funker kun på Android 8 og høyere, og tilknytningen må settes opp på ny med Gadgetbro), noe som øker påliteligheten hvis tjenester må startes på ny i bakgrunnen Advarsel: Kunne ikke sjekke versjonsinfo! Du bør ikke fortsette og versjonsnavnet «%s» ble sett. diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index afc1c40e5..9f26eba66 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Instellingen Debug Sluit af @@ -185,7 +185,7 @@ Tap op het verbonden apparaat voor vibratie Tap op een apparaat om te verbinden Kan niet verbinden. Is het Bluetooth adres ongeldig? - Gadgetbridge loopt + Gadgetbridge loopt Binary installeren %1$d/%2$d Installatie gefaald Geïnstalleerd @@ -914,8 +914,8 @@ Extra apparaatondersteuning Bijdragers Kernteam (in volgorde van eerste codebijdrage) - Cloudloze vrije vervanging voor de gesloten Android-applicaties van gadgetfabrikanten. - Over Gadgetbridge + Cloudloze vrije vervanging voor de gesloten Android-applicaties van gadgetfabrikanten. + Over Gadgetbridge Over Gebruikt voor de LineageOS-weeraanbieder, andere Android versies moeten een app zoals \"Weather notification\" gebruiken. Meer informatie is te vinden in de Gadgetbridge wiki. Wereld Klok diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 6eafd0291..28eea76cc 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Ustawienia Debuguj Wyjdź @@ -108,7 +108,7 @@ Kliknij połączone urządzenie, aby uruchomić menadżer aplikacji Dotknij urządzenie aby połączyć Nie można połączyć. Nieprawidłowy adres Bluetooth\? - Gadgetbridge działa + Gadgetbridge działa Instalowanie binarki %1$d/%2$d Instalacja nie powiodła się Zainstalowano @@ -913,7 +913,7 @@ Ostatnie powiadomienie Ustaw własną nazwę Współtwórcy - O Gadgetbridge + O Gadgetbridge Amazfit T-Rex Styl grzbietowy Styl dowolny @@ -1031,7 +1031,7 @@ Linki Dziękujemy wszystkim nie notowanym na liście współtwórcom za udostępnienie kodu, tłumaczenia, wsparcie, pomysły, motywację, zgłoszenia błędów, pieniądze… ✊ Zespół główny (w kolejności od pierwszego wkładu w kod aplikacji) - Wolny od chmury zamiennik dla aplikacji o zamkniętym kodzie źródłowym dostarczanych przez producentów gadżetów dla systemu Android. + Wolny od chmury zamiennik dla aplikacji o zamkniętym kodzie źródłowym dostarczanych przez producentów gadżetów dla systemu Android. Edytuj etykietę Ping-pong Krykiet diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index a411025d3..d42561908 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Configurações Depurar Sair @@ -148,7 +148,7 @@ Toque no dispositivo conectado para vibração Toque num dispositivo para ligar Não foi possível conectar. Endereço de Bluetooth inválido\? - Gadgetbridge em execução + Gadgetbridge em execução Instalando binário %1$d/%2$d Instalação falhou Instalado @@ -920,8 +920,8 @@ Suporte a dispositivos adicionais Contribuidores Equipe Core (na ordem da primeira contribuição de código) - Um substituto livre, protegido por copyleft, sem acesso a nuvem para os aplicativos Android de código fechado dos fornecedores de gadgets. - Sobre o Gadgetbridge + Um substituto livre, protegido por copyleft, sem acesso a nuvem para os aplicativos Android de código fechado dos fornecedores de gadgets. + Sobre o Gadgetbridge Sobre Usado para o provedor do clima do LineageOS, outras versões do Android precisam usar um aplicativo como o \"Notificação de clima\". Encontrará mais informações no wiki do Gadgetbridge. Relógio mundial diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 74efd9cd1..d26dbd7aa 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Definições Depurar Sair @@ -156,7 +156,7 @@ Toque no aparelho ligado para o fazer vibrar Toque num aparelho para ligar Não foi possível conectar. Endereço de Bluetooth inválido\? - Gadgetbridge a executar + Gadgetbridge a executar Instalando binário %1$d/%2$d A instalação falhou Instalado @@ -573,8 +573,8 @@ Suporte a aparelhos adicionais Contribuidores Equipa Core (na ordem da primeira contribuição de código) - Um substituto livre, protegido por copyleft, sem acesso a nuvem para as apps Android de código fechado dos fornecedores de gadgets. - Sobre o Gadgetbridge + Um substituto livre, protegido por copyleft, sem acesso a nuvem para as apps Android de código fechado dos fornecedores de gadgets. + Sobre o Gadgetbridge Sobre Está prestes a instalar o firmware %s no seu Amazit T-Rex. \n diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index a05411b86..a12113c8a 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Setari Depaneaza Iesire diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index a6c394052..1d606ba1d 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Настройки Отладка Выйти @@ -157,7 +157,7 @@ Коснитесь подключённого устройства для Вибрации Коснитесь устройства для соединения Не удалось соединиться. Неверный адрес Bluetooth\? - Gadgetbridge запущен + Gadgetbridge запущен установка бинарного файла %1$d/%2$d Установка не удалась Установлено @@ -848,8 +848,8 @@ Дополнительная поддержка устройств Соавторы Основная команда (в порядке поступления первого кода) - \"Безоблачная\" свободная альтернатива закрытым приложениям от производителей гаджетов. - О Gadgetbridge + \"Безоблачная\" свободная альтернатива закрытым приложениям от производителей гаджетов. + О Gadgetbridge О программе Последнее уведомление Сохранять необработанные файлы активности diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 8cff0a970..ec6aba113 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Nastavenia Ladenie Ukončiť @@ -180,7 +180,7 @@ Dotknite sa pripojeného zariadenia pre vibrácie Dotknite sa pripojeného zariadenia pre pripojenie Nie je možné pripojiť. Je BT adresa v poriadku? - Gadgetbridge je spustený + Gadgetbridge je spustený Instalujem binárny súbor %1$d/%2$d Inštalácia zlyhala Inštalácia bola úspešná diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 6a8f73ae5..47dea915a 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Inställningar Avsluta Donera diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index b316aaaf5..3ed1c3fc2 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -88,7 +88,7 @@ \nSürüm %2$s, %3$s tarafından \n Yukarı taşı - Gadgetbridge + Gadgetbridge Kur Pebble uygulama mağazasında ara Önbellekteki uygulamalar @@ -314,7 +314,7 @@ Dosya kurulamıyor, aygıt hazır değil. Aygıta bağlantı: %1$s Bu ürün yazılımı bu aygıtla uyumlu değil - Gadgetbridge çalışıyor + Gadgetbridge çalışıyor Almanca Kalp ritmi Yatay @@ -754,7 +754,7 @@ Uygulama Yöneticisi Kara Listeye Alınan Takvimler Etkinlik ve Uyku - Gadgetbridge + Gadgetbridge Veri yönetimi Hata Ayıklama Aygıta özel ayarlar @@ -937,8 +937,8 @@ Ek aygıt desteği Katkıda bulunanlar Çekirdek Ekip (ilk kod katkıda bulunma sırasına göre) - Satıcıların kapalı kaynaklı Android aygıt uygulamalarının yerine bulut gerektirmeyen copyleft özgür alternatif. - Gadgetbridge hakkında + Satıcıların kapalı kaynaklı Android aygıt uygulamalarının yerine bulut gerektirmeyen copyleft özgür alternatif. + Gadgetbridge hakkında Hakkında LineageOS hava durumu sağlayıcısı için kullanılır, diğer Android sürümleri \"Weather notification\" gibi bir uygulama kullanmalıdır. Gadgetbridge wiki sayfasında daha fazla bilgi bulabilirsiniz. Dünya Saati diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 8ea3305e8..4422a3df7 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Налаштування Зневадження Вийти @@ -98,7 +98,7 @@ Bluetooth не підтримується. Bluetooth вимкнуто. Не вдалося з\'єднатися. Неправильна Bluetooth адреса\? - Gadgetbridge запущено + Gadgetbridge запущено Встановлення двійкового файлу %1$d/%2$d Невдале встановлення Встановлено @@ -1022,8 +1022,8 @@ Підтримка додаткових пристроїв Співавтори Основна команда (впорядковано за датою допомоги) - Незалежний від хмари, вільний замінник закритих застосунків від інших виробників. - Про Gadgetbridge + Незалежний від хмари, вільний замінник закритих застосунків від інших виробників. + Про Gadgetbridge Про застосунок Останнє сповіщення Світовий час diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 3e852602c..fbd33c430 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge Cài đặt Dò lỗi Thoát @@ -49,7 +49,7 @@ Không hỗ trợ Bluetooth. Đã tắt Bluetooth. Không thể kết nối. Địa chỉ Bluetooth không hợp lệ\? - Gadgetbridge đang chạy + Gadgetbridge đang chạy Đang cài tệp nhị phân %1$d/%2$d Cài đặt thất bại Đã cài đặt diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 313f273be..ab20c7d41 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1,7 +1,7 @@ - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge 设置 调试 退出 @@ -166,7 +166,7 @@ 点按以震动已连接的设备 点按一个设备以连接 无法连接。 蓝牙地址无效? - Gadgetbridge 正在运行 + Gadgetbridge 正在运行 正在安装二进制文件 %1$d/%2$d 安装失败 安装成功 @@ -917,8 +917,8 @@ 额外设备支持 贡献者 核心成员 (以第一次提交代码排序) - 用于替代原厂手环应用的脱机无版权自由应用。 - 关于 Gadgetbridge + 用于替代原厂手环应用的脱机无版权自由应用。 + 关于 Gadgetbridge 关于 由LineageOS天气服务提供,其他版本的Android系统需要使用诸如“Weather notification”。更多信息请访问 Gadgetbridge 的Wiki。 世界时钟 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index d31c63536..cf8f656c0 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -26,8 +26,8 @@ 刪除並清除緩存 重新安裝 nodomain.freeyourgadget.gadgetbridge.ButtonPressed - Gadgetbridge - Gadgetbridge + Gadgetbridge + Gadgetbridge 連接中… 截取設備的屏幕截圖 校正設備 @@ -524,7 +524,7 @@ 配對您的小米手環 配對裝置 初始化完成 - Gadgetbridge 正在執行 + Gadgetbridge 正在執行 點擊一個裝置以進行連線 藍芽不支援。 涵蓋活動與未活動時消耗的卡路里 @@ -583,8 +583,8 @@ 額外裝置支援 貢獻者 核心團隊(按第一次程式碼貢獻順序排列) - 用來取代廠商提供的閉源 Android 小裝置應用程式的離線且版權自由的替代品。 - 關於 Gadgetbridge + 用來取代廠商提供的閉源 Android 小裝置應用程式的離線且版權自由的替代品。 + 關於 Gadgetbridge 關於 運動活動 游泳 From 1092e1b10ac2600b8bd63cad6e590ffb8e6e23aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 30 Apr 2022 20:24:34 +0100 Subject: [PATCH 035/110] Unset notification color for Android 12+ --- .../freeyourgadget/gadgetbridge/GBApplication.java | 3 +++ .../nodomain/freeyourgadget/gadgetbridge/util/GB.java | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 6282ebcac..35f4b1f6a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -380,6 +380,9 @@ public class GBApplication extends Application { return VERSION.SDK_INT >= Build.VERSION_CODES.Q; } + public static boolean isRunningTwelveOrLater() { + return VERSION.SDK_INT >= 31; // Build.VERSION_CODES.S, but our target SDK is lower + } public static boolean isRunningPieOrLater() { return VERSION.SDK_INT >= Build.VERSION_CODES.P; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java index 5bc9b1fc3..d2cbd09bb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java @@ -151,10 +151,13 @@ public class GB { .setContentText(text) .setSmallIcon(connected ? device.getNotificationIconConnected() : device.getNotificationIconDisconnected()) .setContentIntent(getContentIntent(context)) - .setColor(context.getResources().getColor(R.color.accent)) .setShowWhen(false) .setOngoing(true); + if (!GBApplication.isRunningTwelveOrLater()) { + builder.setColor(context.getResources().getColor(R.color.accent)); + } + Intent deviceCommunicationServiceIntent = new Intent(context, DeviceCommunicationService.class); if (connected) { deviceCommunicationServiceIntent.setAction(DeviceService.ACTION_DISCONNECT); @@ -187,9 +190,13 @@ public class GB { .setContentText(text) .setSmallIcon(R.drawable.ic_notification_disconnected) .setContentIntent(getContentIntent(context)) - .setColor(context.getResources().getColor(R.color.accent)) .setShowWhen(false) .setOngoing(true); + + if (!GBApplication.isRunningTwelveOrLater()) { + builder.setColor(context.getResources().getColor(R.color.accent)); + } + if (GBApplication.getPrefs().getString("last_device_address", null) != null) { Intent deviceCommunicationServiceIntent = new Intent(context, DeviceCommunicationService.class); deviceCommunicationServiceIntent.setAction(DeviceService.ACTION_CONNECT); From 2aecb85015dc83a5f6794a150d6a3c2d2462f77f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 7 May 2022 20:45:33 +0100 Subject: [PATCH 036/110] Fix fitness goal and inactivity warning threshold preference migration --- .../freeyourgadget/gadgetbridge/GBApplication.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 35f4b1f6a..3085c607e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -115,7 +115,7 @@ public class GBApplication extends Application { private static SharedPreferences sharedPrefs; private static final String PREFS_VERSION = "shared_preferences_version"; //if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version - private static final int CURRENT_PREFS_VERSION = 11; + private static final int CURRENT_PREFS_VERSION = 12; private static LimitedQueue mIDSenderLookup = new LimitedQueue(16); private static Prefs prefs; @@ -1075,6 +1075,11 @@ public class GBApplication extends Application { Log.w(TAG, "error acquiring DB lock"); } } + if (oldVersion < 12) { + // Convert preferences that were wrongly migrated to int, since Android saves them as Strings internally + editor.putString("inactivity_warnings_threshold", String.valueOf(prefs.getInt("inactivity_warnings_threshold", 60))); + editor.putString("fitness_goal", String.valueOf(prefs.getInt("fitness_goal", 8000))); + } editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION)); editor.apply(); } From 873ac850017d859932d3b72bb0b77b5478f2517e Mon Sep 17 00:00:00 2001 From: vanous Date: Mon, 9 May 2022 17:18:06 +0200 Subject: [PATCH 037/110] Enable Fitness App Tracking Stop in Huami actions. Add Toggle function to the Tracking --- .../devices/huami/HuamiConst.java | 1 + .../externalevents/OpenTracksController.java | 9 +++++++++ .../service/devices/huami/HuamiSupport.java | 7 +++++++ app/src/main/res/values/arrays.xml | 20 ++++--------------- app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/values.xml | 1 + 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java index f03b5c21e..8fef25994 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java @@ -74,6 +74,7 @@ public class HuamiConst { public static final String PREF_BUTTON_ACTION_SELECTION_BROADCAST = "BROADCAST"; public static final String PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_START = "FITNESS_CONTROL_START"; public static final String PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_STOP = "FITNESS_CONTROL_STOP"; + public static final String PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_TOGGLE = "FITNESS_CONTROL_TOGGLE"; public static final String PREF_DEVICE_ACTION_SELECTION_OFF = "UNKNOWN"; public static final String PREF_DEVICE_ACTION_SELECTION_BROADCAST = "BROADCAST"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/OpenTracksController.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/OpenTracksController.java index 3d94d8951..93a6d9892 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/OpenTracksController.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/OpenTracksController.java @@ -113,4 +113,13 @@ public class OpenTracksController extends Activity { } GBApplication.app().setOpenTracksObserver(null); } + + public static void toggleRecording(Context context) { + OpenTracksContentObserver openTracksObserver = GBApplication.app().getOpenTracksObserver(); + if (openTracksObserver == null) { + startRecording(context); + } else { + stopRecording(context); + } + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 6851f2bea..2b738ad28 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -177,6 +177,7 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_BUTTON_ACTION_SELECTION_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_START; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_STOP; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_TOGGLE; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_BUTTON_ACTION_SELECTION_OFF; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_FELL_SLEEP_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_FELL_SLEEP_SELECTION; @@ -1438,6 +1439,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_STOP: OpenTracksController.stopRecording(this.getContext()); break; + case PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_TOGGLE: + OpenTracksController.toggleRecording(this.getContext()); + break; default: handleMediaButton(buttonPreference); } @@ -1457,6 +1461,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_STOP: OpenTracksController.stopRecording(this.getContext()); break; + case PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_TOGGLE: + OpenTracksController.toggleRecording(this.getContext()); + break; default: handleMediaButton(deviceAction); } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index e71a0eaaf..ef6fc510c 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1655,11 +1655,8 @@ @string/pref_media_rewind @string/pref_device_action_broadcast @string/pref_device_action_fitness_app_control_start - + @string/pref_device_action_fitness_app_control_toggle @@ -1675,11 +1672,8 @@ @string/pref_media_rewind_value @string/pref_device_action_broadcast_value @string/pref_device_action_fitness_app_control_start_value - + @string/pref_device_action_fitness_app_control_toggle_value @@ -1689,11 +1683,8 @@ @string/pref_media_playpause @string/pref_device_action_broadcast @string/pref_device_action_fitness_app_control_start - + @string/pref_device_action_fitness_app_control_toggle @@ -1703,11 +1694,8 @@ @string/pref_media_playpause_value @string/pref_device_action_broadcast_value @string/pref_device_action_fitness_app_control_start_value - + @string/pref_device_action_fitness_app_control_toggle_value diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b4c78e916..7b5386c0a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1530,6 +1530,7 @@ Send Broadcast Fitness App Tracking Start Fitness App Tracking Stop + Toggle Fitness App Tracking ###m diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml index 7380f9f1c..355fbad6a 100644 --- a/app/src/main/res/values/values.xml +++ b/app/src/main/res/values/values.xml @@ -109,6 +109,7 @@ BROADCAST FITNESS_CONTROL_START FITNESS_CONTROL_STOP + FITNESS_CONTROL_TOGGLE Voice Assistant Active Noise Cancelling Quick Ambient Sound From 43bcac072d6d5f35b7e58a783a3556a2355b4ab6 Mon Sep 17 00:00:00 2001 From: mvn23 Date: Mon, 9 May 2022 11:51:28 +0200 Subject: [PATCH 038/110] Add com.asus.asusincallui to handleCallNotification blacklist --- .../gadgetbridge/externalevents/NotificationListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index 1402a92d1..16e9c34b1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -494,7 +494,7 @@ public class NotificationListener extends NotificationListenerService { private void handleCallNotification(StatusBarNotification sbn) { String app = sbn.getPackageName(); LOG.debug("got call from: " + app); - if (app.equals("com.android.dialer") || app.equals("com.android.incallui") || app.equals("com.google.android.dialer")) { + if (app.equals("com.android.dialer") || app.equals("com.android.incallui") || app.equals("com.google.android.dialer") || app.equals("com.asus.asusincallui")) { LOG.debug("Ignoring non-voip call"); return; } From c74bbffb4d8ae6bcee64775e958c024359541a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Mon, 9 May 2022 13:57:44 +0100 Subject: [PATCH 039/110] Mi Band 5: Add activate display on lift sensitivity --- .../DeviceSettingsPreferenceConst.java | 1 + .../DeviceSpecificSettingsFragment.java | 19 ++++++++- .../ActivateDisplayOnLiftSensitivity.java | 22 +++++++++++ .../devices/huami/HuamiCoordinator.java | 9 +++++ .../devices/huami/HuamiService.java | 2 + .../huami/miband5/MiBand5Coordinator.java | 2 +- .../service/devices/huami/HuamiSupport.java | 24 ++++++++++++ .../devices/huami/miband5/MiBand5Support.java | 8 +++- app/src/main/res/values/arrays.xml | 9 +++++ app/src/main/res/values/strings.xml | 3 ++ app/src/main/res/values/values.xml | 3 ++ ...settings_liftwrist_display_sensitivity.xml | 39 +++++++++++++++++++ 12 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/ActivateDisplayOnLiftSensitivity.java create mode 100644 app/src/main/res/xml/devicesettings_liftwrist_display_sensitivity.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index 7e461dfd1..1f82f62e6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -58,6 +58,7 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_ACTIVATE_DISPLAY_ON_LIFT = "activate_display_on_lift_wrist"; public static final String PREF_DISPLAY_ON_LIFT_START = "display_on_lift_start"; public static final String PREF_DISPLAY_ON_LIFT_END = "display_on_lift_end"; + public static final String PREF_DISPLAY_ON_LIFT_SENSITIVITY = "display_on_lift_sensitivity"; public static final String PREF_SLEEP_TIME = "prefs_enable_sleep_time"; public static final String PREF_SLEEP_TIME_START = "prefs_sleep_time_start"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index 260a64ea8..5f817cc9d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -516,6 +516,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp } String displayOnLiftState = prefs.getString(PREF_ACTIVATE_DISPLAY_ON_LIFT, PREF_DO_NOT_DISTURB_OFF); boolean displayOnLiftScheduled = displayOnLiftState.equals(PREF_DO_NOT_DISTURB_SCHEDULED); + boolean displayOnLiftOff = displayOnLiftState.equals(PREF_DO_NOT_DISTURB_OFF); final Preference rotateWristCycleInfo = findPreference(PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO); if (rotateWristCycleInfo != null) { @@ -553,16 +554,32 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp }); } + final Preference displayOnLiftSensitivity = findPreference(PREF_DISPLAY_ON_LIFT_SENSITIVITY); + if (displayOnLiftSensitivity != null) { + displayOnLiftSensitivity.setEnabled(!displayOnLiftOff); + displayOnLiftSensitivity.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + notifyPreferenceChanged(PREF_DISPLAY_ON_LIFT_SENSITIVITY); + return true; + } + }); + } + final Preference displayOnLift = findPreference(PREF_ACTIVATE_DISPLAY_ON_LIFT); if (displayOnLift != null) { displayOnLift.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newVal) { final boolean scheduled = PREF_DO_NOT_DISTURB_SCHEDULED.equals(newVal.toString()); + final boolean off = PREF_DO_NOT_DISTURB_OFF.equals(newVal.toString()); Objects.requireNonNull(displayOnLiftStart).setEnabled(scheduled); Objects.requireNonNull(displayOnLiftEnd).setEnabled(scheduled); if (rotateWristCycleInfo != null) { - rotateWristCycleInfo.setEnabled(!PREF_DO_NOT_DISTURB_OFF.equals(newVal.toString())); + rotateWristCycleInfo.setEnabled(!off); + } + if (displayOnLiftSensitivity != null) { + displayOnLiftSensitivity.setEnabled(!off); } notifyPreferenceChanged(PREF_ACTIVATE_DISPLAY_ON_LIFT); return true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/ActivateDisplayOnLiftSensitivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/ActivateDisplayOnLiftSensitivity.java new file mode 100644 index 000000000..f50750b78 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/ActivateDisplayOnLiftSensitivity.java @@ -0,0 +1,22 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.devices.huami; + +public enum ActivateDisplayOnLiftSensitivity { + NORMAL, + SENSITIVE +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java index c7e63a266..af54a0a2f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java @@ -35,6 +35,7 @@ import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.Locale; import de.greenrobot.dao.query.QueryBuilder; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -166,6 +167,14 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { return getTimePreference(DeviceSettingsPreferenceConst.PREF_DISPLAY_ON_LIFT_END, "00:00", deviceAddress); } + public static ActivateDisplayOnLiftSensitivity getDisplayOnLiftSensitivity(String deviceAddress) { + final SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(deviceAddress); + + final String pref = prefs.getString(DeviceSettingsPreferenceConst.PREF_DISPLAY_ON_LIFT_SENSITIVITY, "sensitive"); + + return ActivateDisplayOnLiftSensitivity.valueOf(pref.toUpperCase(Locale.ROOT)); + } + public static DisconnectNotificationSetting getDisconnectNotificationSetting(Context context, String deviceAddress) { Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java index 35fc46c9e..9cc8245f8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java @@ -149,6 +149,8 @@ public class HuamiService { public static final byte[] COMMAND_ENABLE_DISPLAY_ON_LIFT_WRIST = new byte[]{ENDPOINT_DISPLAY, 0x05, 0x00, 0x01}; public static final byte[] COMMAND_DISABLE_DISPLAY_ON_LIFT_WRIST = new byte[]{ENDPOINT_DISPLAY, 0x05, 0x00, 0x00}; public static final byte[] COMMAND_SCHEDULE_DISPLAY_ON_LIFT_WRIST = new byte[]{ENDPOINT_DISPLAY, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}; + public static final byte[] COMMAND_DISPLAY_ON_LIFT_WRIST_SPEED_NORMAL = new byte[]{ENDPOINT_DISPLAY, 0x23, 0x00, 0x00}; + public static final byte[] COMMAND_DISPLAY_ON_LIFT_WRIST_SPEED_SENSITIVE = new byte[]{ENDPOINT_DISPLAY, 0x23, 0x00, 0x01}; public static final byte[] COMMAND_ENABLE_GOAL_NOTIFICATION = new byte[]{ENDPOINT_DISPLAY, 0x06, 0x00, 0x01}; public static final byte[] COMMAND_DISABLE_GOAL_NOTIFICATION = new byte[]{ENDPOINT_DISPLAY, 0x06, 0x00, 0x00}; public static final byte[] COMMAND_ENABLE_ROTATE_WRIST_TO_SWITCH_INFO = new byte[]{ENDPOINT_DISPLAY, 0x0d, 0x00, 0x01}; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java index 477f3036f..75b2061ee 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java @@ -94,7 +94,7 @@ public class MiBand5Coordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_nightmode, - R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_liftwrist_display_sensitivity, R.xml.devicesettings_swipeunlock, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 2b738ad28..665c34f5a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -72,6 +72,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInf import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.huami.ActivateDisplayOnLift; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.ActivateDisplayOnLiftSensitivity; import nodomain.freeyourgadget.gadgetbridge.devices.huami.DisconnectNotificationSetting; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator; @@ -129,6 +130,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotific import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.actions.StopNotificationAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2NotificationStrategy; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2TextNotificationStrategy; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband5.MiBand5Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchActivityOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.InitOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.InitOperation2021; @@ -151,6 +153,7 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_ALLOW_HIGH_MTU; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BT_CONNECTED_ADVERTISEMENT; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DATEFORMAT; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DISPLAY_ON_LIFT_SENSITIVITY; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DISPLAY_ON_LIFT_START; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DISPLAY_ON_LIFT_END; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DISCONNECT_NOTIFICATION; @@ -188,6 +191,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_WOKE_UP_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_WOKE_UP_SELECTION; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.DISPLAY_ITEM_BIT_CLOCK; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY_ITEMS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_COUNT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_PROFILE; @@ -2237,6 +2241,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case PREF_DISPLAY_ON_LIFT_END: setActivateDisplayOnLiftWrist(builder); break; + case PREF_DISPLAY_ON_LIFT_SENSITIVITY: + setActivateDisplayOnLiftWristSensitivity(builder); + break; case PREF_DISCONNECT_NOTIFICATION: case PREF_DISCONNECT_NOTIFICATION_START: case PREF_DISCONNECT_NOTIFICATION_END: @@ -2666,6 +2673,23 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return this; } + protected HuamiSupport setActivateDisplayOnLiftWristSensitivity(TransactionBuilder builder) { + final ActivateDisplayOnLiftSensitivity sensitivity = HuamiCoordinator.getDisplayOnLiftSensitivity(gbDevice.getAddress()); + LOG.info("Setting activate display on lift wrist sensitivity to " + sensitivity); + + switch (sensitivity) { + case SENSITIVE: + writeToConfiguration(builder, HuamiService.COMMAND_DISPLAY_ON_LIFT_WRIST_SPEED_SENSITIVE); + break; + case NORMAL: + default: + writeToConfiguration(builder, HuamiService.COMMAND_DISPLAY_ON_LIFT_WRIST_SPEED_NORMAL); + break; + } + + return this; + } + protected HuamiSupport setDisplayItems(TransactionBuilder builder) { SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()); Set pages = prefs.getStringSet(HuamiConst.PREF_DISPLAY_ITEMS, new HashSet<>(Arrays.asList(getContext().getResources().getStringArray(R.array.pref_mi2_display_items_default)))); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java index 79dbeb075..d96edc865 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java @@ -50,7 +50,6 @@ public class MiBand5Support extends MiBand4Support { return new MiBand5FWHelper(uri, context); } - @Override public boolean supportsSunriseSunsetWindHumidity() { return true; @@ -60,4 +59,11 @@ public class MiBand5Support extends MiBand4Support { public int getActivitySampleSize() { return 8; } + + @Override + public void phase3Initialize(TransactionBuilder builder) { + super.phase3Initialize(builder); + LOG.info("phase3Initialize..."); + setActivateDisplayOnLiftWristSensitivity(builder); // TODO? Move this to HuamiSupport? + } } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index ef6fc510c..e9b7245bd 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -272,6 +272,15 @@ @string/p_scheduled + + @string/normal + @string/sensitive + + + @string/p_normal + @string/p_sensitive + + @string/off + + + + + + + + + + + + \ No newline at end of file From d973f50560c72a4fb766ca6ebd535a39678a6ebf Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 9 May 2022 23:01:57 +0200 Subject: [PATCH 040/110] Mi Band 6: enable setting sensitivty for display on lift setting Tested and seens to work --- .../gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java index c55f4fa08..a5aba4b37 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java @@ -79,7 +79,7 @@ public class MiBand6Coordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_nightmode, - R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_liftwrist_display_sensitivity, R.xml.devicesettings_swipeunlock, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, From 5c6edea2335a80c7963ddfb320e00446616d1f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Mon, 9 May 2022 19:47:08 +0100 Subject: [PATCH 041/110] Mi Band 5: Add support for World Clocks --- .../gadgetbridge/daogen/GBDaoGenerator.java | 21 +- app/build.gradle | 4 + app/src/main/AndroidManifest.xml | 10 + .../gadgetbridge/GBApplication.java | 5 + .../activities/ConfigureWorldClocks.java | 218 ++++++++++++++++++ .../activities/WorldClockDetails.java | 174 ++++++++++++++ .../DeviceSettingsActivity.java | 31 +-- .../DeviceSettingsPreferenceConst.java | 2 + .../DeviceSpecificSettingsFragment.java | 52 ++++- .../adapter/GBWorldClockListAdapter.java | 132 +++++++++++ .../gadgetbridge/database/DBHelper.java | 42 ++++ .../devices/AbstractDeviceCoordinator.java | 10 + .../devices/DeviceCoordinator.java | 10 + .../gadgetbridge/devices/EventHandler.java | 3 + .../huami/miband5/MiBand5Coordinator.java | 11 + .../gadgetbridge/impl/GBDeviceService.java | 8 + .../gadgetbridge/model/DeviceService.java | 2 + .../gadgetbridge/model/WorldClock.java | 30 +++ .../service/DeviceCommunicationService.java | 7 + .../service/ServiceDeviceSupport.java | 9 + .../btle/AbstractBTLEDeviceSupport.java | 6 + .../service/devices/huami/HuamiSupport.java | 123 ++++++++++ .../serial/AbstractSerialDeviceSupport.java | 7 + .../service/serial/GBDeviceProtocol.java | 5 + .../activity_configure_world_clocks.xml | 27 +++ .../layout/activity_world_clock_details.xml | 97 ++++++++ app/src/main/res/layout/device_itemv2.xml | 14 +- app/src/main/res/layout/item_world_clock.xml | 64 +++++ app/src/main/res/values/strings.xml | 9 + .../res/xml/devicesettings_world_clocks.xml | 8 + 30 files changed, 1100 insertions(+), 41 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureWorldClocks.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WorldClockDetails.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBWorldClockListAdapter.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/WorldClock.java create mode 100644 app/src/main/res/layout/activity_configure_world_clocks.xml create mode 100644 app/src/main/res/layout/activity_world_clock_details.xml create mode 100644 app/src/main/res/layout/item_world_clock.xml create mode 100644 app/src/main/res/xml/devicesettings_world_clocks.xml diff --git a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java index b6f5fdef6..11cda37c9 100644 --- a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java +++ b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java @@ -43,7 +43,7 @@ public class GBDaoGenerator { public static void main(String[] args) throws Exception { - final Schema schema = new Schema(37, MAIN_PACKAGE + ".entities"); + final Schema schema = new Schema(38, MAIN_PACKAGE + ".entities"); Entity userAttributes = addUserAttributes(schema); Entity user = addUserInfo(schema, userAttributes); @@ -87,6 +87,7 @@ public class GBDaoGenerator { addCalendarSyncState(schema, device); addAlarms(schema, user, device); addReminders(schema, user, device); + addWorldClocks(schema, user, device); Entity notificationFilter = addNotificationFilters(schema); @@ -561,6 +562,24 @@ public class GBDaoGenerator { reminder.addToOne(device, deviceId); } + private static void addWorldClocks(Schema schema, Entity user, Entity device) { + Entity worldClock = addEntity(schema, "WorldClock"); + worldClock.implementsInterface("nodomain.freeyourgadget.gadgetbridge.model.WorldClock"); + Property deviceId = worldClock.addLongProperty("deviceId").notNull().getProperty(); + Property userId = worldClock.addLongProperty("userId").notNull().getProperty(); + Property worldClockId = worldClock.addStringProperty("worldClockId").notNull().primaryKey().getProperty(); + Index indexUnique = new Index(); + indexUnique.addProperty(deviceId); + indexUnique.addProperty(userId); + indexUnique.addProperty(worldClockId); + indexUnique.makeUnique(); + worldClock.addIndex(indexUnique); + worldClock.addStringProperty("label").notNull(); + worldClock.addStringProperty("timeZoneId").notNull(); + worldClock.addToOne(user, userId); + worldClock.addToOne(device, deviceId); + } + private static void addNotificationFilterEntry(Schema schema, Entity notificationFilterEntity) { Entity notificatonFilterEntry = addEntity(schema, "NotificationFilterEntry"); notificatonFilterEntry.addIdProperty().autoincrement(); diff --git a/app/build.gradle b/app/build.gradle index eb6da978e..aff0035ab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -238,6 +238,10 @@ dependencies { implementation 'com.google.protobuf:protobuf-lite:3.0.1' implementation "androidx.multidex:multidex:2.0.1" implementation 'com.android.volley:volley:1.2.1' + + // JSR-310 timezones backport for Android, since we're still on java 7 + implementation 'com.jakewharton.threetenabp:threetenabp:1.4.0' + testImplementation 'org.threeten:threetenbp:1.6.0' } preBuild.dependsOn(":GBDaoGenerator:genSources") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a2078b549..6a424dfb7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -498,6 +498,10 @@ android:name=".activities.ConfigureReminders" android:label="@string/title_activity_set_reminders" android:parentActivityName=".activities.ControlCenterv2" /> + + . */ +package nodomain.freeyourgadget.gadgetbridge.activities; + +import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.adapter.GBWorldClockListAdapter; +import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; +import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.Device; +import nodomain.freeyourgadget.gadgetbridge.entities.User; +import nodomain.freeyourgadget.gadgetbridge.entities.WorldClock; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; + + +public class ConfigureWorldClocks extends AbstractGBActivity { + private static final Logger LOG = LoggerFactory.getLogger(ConfigureWorldClocks.class); + + private static final int REQ_CONFIGURE_WORLD_CLOCK = 1; + + private GBWorldClockListAdapter mGBWorldClockListAdapter; + private GBDevice gbDevice; + + private BroadcastReceiver timeTickBroadcastReceiver; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_configure_world_clocks); + + gbDevice = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE); + + mGBWorldClockListAdapter = new GBWorldClockListAdapter(this); + + final RecyclerView worldClocksRecyclerView = findViewById(R.id.world_clock_list); + worldClocksRecyclerView.setHasFixedSize(true); + worldClocksRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + worldClocksRecyclerView.setAdapter(mGBWorldClockListAdapter); + updateWorldClocksFromDB(); + + final FloatingActionButton fab = findViewById(R.id.fab); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice); + + int deviceSlots = coordinator.getWorldClocksSlotCount(); + + if (mGBWorldClockListAdapter.getItemCount() >= deviceSlots) { + // No more free slots + new AlertDialog.Builder(v.getContext()) + .setTitle(R.string.world_clock_no_free_slots_title) + .setMessage(getBaseContext().getString(R.string.world_clock_no_free_slots_description, String.format(Locale.getDefault(), "%d", deviceSlots))) + .setIcon(R.drawable.ic_warning) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(final DialogInterface dialog, final int whichButton) { + } + }) + .show(); + return; + } + + final WorldClock worldClock; + try (DBHandler db = GBApplication.acquireDB()) { + final DaoSession daoSession = db.getDaoSession(); + final Device device = DBHelper.getDevice(gbDevice, daoSession); + final User user = DBHelper.getUser(daoSession); + worldClock = createDefaultWorldClock(device, user); + } catch (final Exception e) { + LOG.error("Error accessing database", e); + return; + } + + configureWorldClock(worldClock); + } + }); + } + + @Override + protected void onStart() { + super.onStart(); + + timeTickBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(final Context context, Intent intent) { + if (Intent.ACTION_TIME_TICK.equals(intent.getAction())) { + // Refresh the UI, to update the current time in each timezone + mGBWorldClockListAdapter.notifyDataSetChanged(); + } + } + }; + + registerReceiver(timeTickBroadcastReceiver, new IntentFilter(Intent.ACTION_TIME_TICK)); + } + + @Override + protected void onStop() { + super.onStop(); + + if (timeTickBroadcastReceiver != null) { + unregisterReceiver(timeTickBroadcastReceiver); + } + } + + @Override + protected void onResume() { + super.onResume(); + // Refresh to update the current time on each clock + mGBWorldClockListAdapter.notifyDataSetChanged(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == REQ_CONFIGURE_WORLD_CLOCK && resultCode == 1) { + updateWorldClocksFromDB(); + sendWorldClocksToDevice(); + } + } + + private WorldClock createDefaultWorldClock(@NonNull Device device, @NonNull User user) { + final WorldClock worldClock = new WorldClock(); + final String timezone = TimeZone.getDefault().getID(); + worldClock.setTimeZoneId(timezone); + final String[] timezoneParts = timezone.split("/"); + worldClock.setLabel(timezoneParts[timezoneParts.length - 1]); + + worldClock.setDeviceId(device.getId()); + worldClock.setUserId(user.getId()); + worldClock.setWorldClockId(UUID.randomUUID().toString()); + + return worldClock; + } + + /** + * Reads the available worldClocks from the database and updates the view afterwards. + */ + private void updateWorldClocksFromDB() { + final List worldClocks = DBHelper.getWorldClocks(gbDevice); + + mGBWorldClockListAdapter.setWorldClockList(worldClocks); + mGBWorldClockListAdapter.notifyDataSetChanged(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + // back button + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + public void configureWorldClock(final WorldClock worldClock) { + final Intent startIntent = new Intent(getApplicationContext(), WorldClockDetails.class); + startIntent.putExtra(GBDevice.EXTRA_DEVICE, gbDevice); + startIntent.putExtra(WorldClock.EXTRA_WORLD_CLOCK, worldClock); + startActivityForResult(startIntent, REQ_CONFIGURE_WORLD_CLOCK); + } + + public void deleteWorldClock(final WorldClock worldClock) { + DBHelper.delete(worldClock); + updateWorldClocksFromDB(); + sendWorldClocksToDevice(); + } + + private void sendWorldClocksToDevice() { + if (gbDevice.isInitialized()) { + GBApplication.deviceService().onSetWorldClocks(mGBWorldClockListAdapter.getWorldClockList()); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WorldClockDetails.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WorldClockDetails.java new file mode 100644 index 000000000..a1f3c5646 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WorldClockDetails.java @@ -0,0 +1,174 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.activities; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.text.Editable; +import android.text.InputFilter; +import android.text.TextWatcher; +import android.view.MenuItem; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.TimeZone; + +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.entities.WorldClock; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public class WorldClockDetails extends AbstractGBActivity { + private static final Logger LOG = LoggerFactory.getLogger(WorldClockDetails.class); + + private WorldClock worldClock; + private GBDevice device; + + ArrayAdapter timezoneAdapter; + + TextView worldClockTimezone; + EditText worldClockLabel; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_world_clock_details); + + worldClock = (WorldClock) getIntent().getSerializableExtra(WorldClock.EXTRA_WORLD_CLOCK); + + if (worldClock == null) { + GB.toast("No worldClock provided to WorldClockDetails Activity", Toast.LENGTH_LONG, GB.ERROR); + finish(); + return; + } + + worldClockTimezone = findViewById(R.id.world_clock_timezone); + worldClockLabel = findViewById(R.id.world_clock_label); + + device = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE); + final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device); + + final String[] timezoneIDs = TimeZone.getAvailableIDs(); + timezoneAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, timezoneIDs); + + final View cardTimezone = findViewById(R.id.card_timezone); + cardTimezone.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + new AlertDialog.Builder(WorldClockDetails.this).setAdapter(timezoneAdapter, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + worldClock.setTimeZoneId(timezoneIDs[i]); + updateUiFromWorldClock(); + } + }).create().show(); + } + }); + + worldClockLabel.setFilters(new InputFilter[]{new InputFilter.LengthFilter(coordinator.getWorldClocksLabelLength())}); + worldClockLabel.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(final CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(final CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(final Editable s) { + worldClock.setLabel(s.toString()); + } + }); + + final FloatingActionButton fab = findViewById(R.id.fab_save); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + updateWorldClock(); + WorldClockDetails.this.setResult(1); + finish(); + } + }); + + updateUiFromWorldClock(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + // back button + // TODO confirm when exiting without saving + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + private void updateWorldClock() { + DBHelper.store(worldClock); + } + + @Override + protected void onSaveInstanceState(Bundle state) { + super.onSaveInstanceState(state); + state.putSerializable("worldClock", worldClock); + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + worldClock = (WorldClock) savedInstanceState.getSerializable("worldClock"); + updateUiFromWorldClock(); + } + + public void updateUiFromWorldClock() { + final String oldTimezone = worldClockTimezone.getText().toString(); + + worldClockTimezone.setText(worldClock.getTimeZoneId()); + + // Check if the label was still the default (the timezone city name) + // If so, and if the user changed the timezone, update the label to match the new city name + if (!oldTimezone.equals(worldClock.getTimeZoneId())) { + final String[] oldTimezoneParts = oldTimezone.split("/"); + final String[] newTimezoneParts = worldClock.getTimeZoneId().split("/"); + final String newLabel = newTimezoneParts[newTimezoneParts.length - 1]; + final String oldLabel = oldTimezoneParts[oldTimezoneParts.length - 1]; + final String userLabel = worldClockLabel.getText().toString(); + + if (userLabel.equals(oldLabel)) { + // The label was still the original, so let's override it with the new city + worldClock.setLabel(newLabel); + } + } + + worldClockLabel.setText(worldClock.getLabel()); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsActivity.java index a34fde8bb..9ed08de5d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsActivity.java @@ -48,20 +48,7 @@ public class DeviceSettingsActivity extends AbstractGBActivity implements if (savedInstanceState == null) { Fragment fragment = getSupportFragmentManager().findFragmentByTag(DeviceSpecificSettingsFragment.FRAGMENT_TAG); if (fragment == null) { - DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device); - int[] supportedSettings = coordinator.getSupportedDeviceSpecificSettings(device); - String[] supportedLanguages = coordinator.getSupportedLanguageSettings(device); - - if (supportedLanguages != null) { - supportedSettings = ArrayUtils.insert(0, supportedSettings, R.xml.devicesettings_language_generic); - } - if (coordinator.supportsActivityTracking()) { - supportedSettings = ArrayUtils.addAll(supportedSettings, R.xml.devicesettings_chartstabs); - supportedSettings = ArrayUtils.addAll(supportedSettings, R.xml.devicesettings_device_card_activity_card_preferences); - } - - final DeviceSpecificSettingsCustomizer deviceSpecificSettingsCustomizer = coordinator.getDeviceSpecificSettingsCustomizer(device); - fragment = DeviceSpecificSettingsFragment.newInstance(device.getAddress(), supportedSettings, supportedLanguages, deviceSpecificSettingsCustomizer); + fragment = DeviceSpecificSettingsFragment.newInstance(device); } getSupportFragmentManager() .beginTransaction() @@ -73,21 +60,7 @@ public class DeviceSettingsActivity extends AbstractGBActivity implements @Override public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen preferenceScreen) { - DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device); - int[] supportedSettings = coordinator.getSupportedDeviceSpecificSettings(device); - String[] supportedLanguages = coordinator.getSupportedLanguageSettings(device); - - if (supportedLanguages != null) { - supportedSettings = ArrayUtils.insert(0, supportedSettings, R.xml.devicesettings_language_generic); - } - - if (coordinator.supportsActivityTracking()) { - supportedSettings = ArrayUtils.addAll(supportedSettings, R.xml.devicesettings_chartstabs); - supportedSettings = ArrayUtils.addAll(supportedSettings, R.xml.devicesettings_device_card_activity_card_preferences); - } - - final DeviceSpecificSettingsCustomizer deviceSpecificSettingsCustomizer = coordinator.getDeviceSpecificSettingsCustomizer(device); - PreferenceFragmentCompat fragment = DeviceSpecificSettingsFragment.newInstance(device.getAddress(), supportedSettings, supportedLanguages, deviceSpecificSettingsCustomizer); + final PreferenceFragmentCompat fragment = DeviceSpecificSettingsFragment.newInstance(device); Bundle args = fragment.getArguments(); args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.getKey()); fragment.setArguments(args); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index 1f82f62e6..39964bdcd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -112,6 +112,8 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_KEY_VIBRATION = "key_vibration"; public static final String PREF_FAKE_RING_DURATION = "fake_ring_duration"; + public static final String PREF_WORLD_CLOCKS = "pref_world_clocks"; + public static final String PREF_ANTILOST_ENABLED = "pref_antilost_enabled"; public static final String PREF_HYDRATION_SWITCH = "pref_hydration_switch"; public static final String PREF_HYDRATION_PERIOD = "pref_hydration_period"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index 5f817cc9d..4bbd36b6a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.text.InputType; +import android.view.View; import android.widget.EditText; import androidx.annotation.NonNull; @@ -47,11 +48,17 @@ import java.util.Objects; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureWorldClocks; +import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; +import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; import nodomain.freeyourgadget.gadgetbridge.devices.makibeshr3.MakibesHR3Constants; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; +import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference; import nodomain.freeyourgadget.gadgetbridge.util.XTimePreferenceFragment; @@ -89,6 +96,8 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp private DeviceSpecificSettingsCustomizer deviceSpecificSettingsCustomizer; + private GBDevice device; + private void setSettingsFileSuffix(String settingsFileSuffix, @NonNull int[] supportedSettings, String[] supportedLanguages) { Bundle args = new Bundle(); args.putString("settingsFileSuffix", settingsFileSuffix); @@ -103,6 +112,12 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp setArguments(args); } + private void setDevice(final GBDevice device) { + final Bundle args = getArguments() != null ? getArguments() : new Bundle(); + args.putParcelable("device", device); + setArguments(args); + } + @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { Bundle arguments = getArguments(); @@ -113,6 +128,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp int[] supportedSettings = arguments.getIntArray("supportedSettings"); String[] supportedLanguages = arguments.getStringArray("supportedLanguages"); this.deviceSpecificSettingsCustomizer = arguments.getParcelable("deviceSpecificSettingsCustomizer"); + this.device = arguments.getParcelable("device"); if (settingsFileSuffix == null || supportedSettings == null) { return; @@ -587,6 +603,19 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp }); } + final Preference worldClocks = findPreference(PREF_WORLD_CLOCKS); + if (worldClocks != null) { + worldClocks.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + final Intent intent = new Intent(getContext(), ConfigureWorldClocks.class); + intent.putExtra(GBDevice.EXTRA_DEVICE, device); + startActivity(intent); + return true; + } + }); + } + final Preference cannedMessagesDismissCall = findPreference("canned_messages_dismisscall_send"); if (cannedMessagesDismissCall != null) { cannedMessagesDismissCall.setOnPreferenceClickListener(new androidx.preference.Preference.OnPreferenceClickListener() { @@ -704,13 +733,28 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp } } - static DeviceSpecificSettingsFragment newInstance(String settingsFileSuffix, - @NonNull int[] supportedSettings, - String[] supportedLanguages, - DeviceSpecificSettingsCustomizer deviceSpecificSettingsCustomizer) { + static DeviceSpecificSettingsFragment newInstance(GBDevice device) { + final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device); + int[] supportedSettings = coordinator.getSupportedDeviceSpecificSettings(device); + String[] supportedLanguages = coordinator.getSupportedLanguageSettings(device); + + if (supportedLanguages != null) { + supportedSettings = ArrayUtils.insert(0, supportedSettings, R.xml.devicesettings_language_generic); + } + + if (coordinator.supportsActivityTracking()) { + supportedSettings = ArrayUtils.addAll(supportedSettings, R.xml.devicesettings_chartstabs); + supportedSettings = ArrayUtils.addAll(supportedSettings, R.xml.devicesettings_device_card_activity_card_preferences); + } + + final DeviceSpecificSettingsCustomizer deviceSpecificSettingsCustomizer = coordinator.getDeviceSpecificSettingsCustomizer(device); + + final String settingsFileSuffix = device.getAddress(); + final DeviceSpecificSettingsFragment fragment = new DeviceSpecificSettingsFragment(); fragment.setSettingsFileSuffix(settingsFileSuffix, supportedSettings, supportedLanguages); fragment.setDeviceSpecificSettingsCustomizer(deviceSpecificSettingsCustomizer); + fragment.setDevice(device); return fragment; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBWorldClockListAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBWorldClockListAdapter.java new file mode 100644 index 000000000..82f07cde9 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBWorldClockListAdapter.java @@ -0,0 +1,132 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.adapter; + + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.cardview.widget.CardView; +import androidx.recyclerview.widget.RecyclerView; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureWorldClocks; +import nodomain.freeyourgadget.gadgetbridge.entities.WorldClock; + +/** + * Adapter for displaying WorldClock instances. + */ +public class GBWorldClockListAdapter extends RecyclerView.Adapter { + + private final Context mContext; + private ArrayList worldClockList; + + public GBWorldClockListAdapter(final Context context) { + this.mContext = context; + } + + public void setWorldClockList(final List worldClocks) { + this.worldClockList = new ArrayList<>(worldClocks); + } + + public ArrayList getWorldClockList() { + return worldClockList; + } + + @NonNull + @Override + public GBWorldClockListAdapter.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) { + final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_world_clock, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, final int position) { + final WorldClock worldClock = worldClockList.get(position); + + holder.container.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ((ConfigureWorldClocks) mContext).configureWorldClock(worldClock); + } + }); + + holder.container.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + new AlertDialog.Builder(v.getContext()) + .setTitle(v.getContext().getString(R.string.world_clock_delete_confirm_title, worldClock.getLabel())) + .setMessage(R.string.world_clock_delete_confirm_description) + .setIcon(R.drawable.ic_warning) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(final DialogInterface dialog, final int whichButton) { + ((ConfigureWorldClocks) mContext).deleteWorldClock(worldClock); + } + }) + .setNegativeButton(android.R.string.no, null) + .show(); + + return true; + } + }); + + holder.worldClockLabel.setText(worldClock.getLabel()); + holder.worldClockTimezone.setText(worldClock.getTimeZoneId()); + + final DateFormat df = new SimpleDateFormat("HH:mm", GBApplication.getLanguage()); + df.setTimeZone(TimeZone.getTimeZone(worldClock.getTimeZoneId())); + holder.worldClockCurrentTime.setText(df.format(new Date())); + } + + @Override + public int getItemCount() { + return worldClockList.size(); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + final CardView container; + + final TextView worldClockTimezone; + final TextView worldClockLabel; + final TextView worldClockCurrentTime; + + ViewHolder(View view) { + super(view); + + container = view.findViewById(R.id.card_view); + + worldClockTimezone = view.findViewById(R.id.world_clock_item_timezone); + worldClockLabel = view.findViewById(R.id.world_clock_item_label); + worldClockCurrentTime = view.findViewById(R.id.world_clock_current_time); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHelper.java index 7e97e9862..ef5981eae 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/DBHelper.java @@ -62,6 +62,8 @@ import nodomain.freeyourgadget.gadgetbridge.entities.TagDao; import nodomain.freeyourgadget.gadgetbridge.entities.User; import nodomain.freeyourgadget.gadgetbridge.entities.UserAttributes; import nodomain.freeyourgadget.gadgetbridge.entities.UserDao; +import nodomain.freeyourgadget.gadgetbridge.entities.WorldClock; +import nodomain.freeyourgadget.gadgetbridge.entities.WorldClockDao; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; import nodomain.freeyourgadget.gadgetbridge.model.ValidByDate; @@ -658,6 +660,28 @@ public class DBHelper { return Collections.emptyList(); } + @NonNull + public static List getWorldClocks(@NonNull GBDevice gbDevice) { + try (DBHandler db = GBApplication.acquireDB()) { + final DaoSession daoSession = db.getDaoSession(); + final User user = getUser(daoSession); + final Device dbDevice = DBHelper.findDevice(gbDevice, daoSession); + if (dbDevice != null) { + final WorldClockDao worldClockDao = daoSession.getWorldClockDao(); + final Long deviceId = dbDevice.getId(); + final QueryBuilder qb = worldClockDao.queryBuilder(); + qb.where( + WorldClockDao.Properties.UserId.eq(user.getId()), + WorldClockDao.Properties.DeviceId.eq(deviceId)).orderAsc(WorldClockDao.Properties.WorldClockId); + return qb.build().list(); + } + } catch (final Exception e) { + LOG.error("Error reading world clocks from db", e); + } + + return Collections.emptyList(); + } + public static void store(final Reminder reminder) { try (DBHandler db = GBApplication.acquireDB()) { final DaoSession daoSession = db.getDaoSession(); @@ -667,6 +691,15 @@ public class DBHelper { } } + public static void store(final WorldClock worldClock) { + try (DBHandler db = GBApplication.acquireDB()) { + final DaoSession daoSession = db.getDaoSession(); + daoSession.insertOrReplace(worldClock); + } catch (final Exception e) { + LOG.error("Error acquiring database", e); + } + } + public static void delete(final Reminder reminder) { try (DBHandler db = GBApplication.acquireDB()) { final DaoSession daoSession = db.getDaoSession(); @@ -676,6 +709,15 @@ public class DBHelper { } } + public static void delete(final WorldClock worldClock) { + try (DBHandler db = GBApplication.acquireDB()) { + final DaoSession daoSession = db.getDaoSession(); + daoSession.delete(worldClock); + } catch (final Exception e) { + LOG.error("Error acquiring database", e); + } + } + public static void clearSession() { try (DBHandler dbHandler = GBApplication.acquireDB()) { DaoSession session = dbHandler.getDaoSession(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java index 232c69628..f97a9608a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java @@ -232,6 +232,16 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { return 0; } + @Override + public int getWorldClocksSlotCount() { + return 0; + } + + @Override + public int getWorldClocksLabelLength() { + return 10; + } + @Override public boolean supportsRgbLedColor() { return false; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java index b329c7970..f5dc931bc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java @@ -331,6 +331,16 @@ public interface DeviceCoordinator { */ int getReminderSlotCount(); + /** + * Indicates the maximum number of slots available for world clocks in the device. + */ + int getWorldClocksSlotCount(); + + /** + * Indicates the maximum label length for a world clock in the device. + */ + int getWorldClocksLabelLength(); + /** * Indicates whether the device has an led which supports custom colors */ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java index d20ab54e3..d4ccc7c67 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java @@ -32,6 +32,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.Reminder; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WorldClock; /** * Specifies all events that Gadgetbridge intends to send to the gadget device. @@ -49,6 +50,8 @@ public interface EventHandler { void onSetReminders(ArrayList reminders); + void onSetWorldClocks(ArrayList clocks); + void onSetCallState(CallSpec callSpec); void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java index 75b2061ee..8bf08ac85 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java @@ -85,6 +85,16 @@ public class MiBand5Coordinator extends HuamiCoordinator { return true; } + @Override + public int getWorldClocksSlotCount() { + return 20; // as enforced by Mi Fit + } + + @Override + public int getWorldClocksLabelLength() { + return 30; // at least + } + @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ @@ -93,6 +103,7 @@ public class MiBand5Coordinator extends HuamiCoordinator { R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, + R.xml.devicesettings_world_clocks, R.xml.devicesettings_nightmode, R.xml.devicesettings_liftwrist_display_sensitivity, R.xml.devicesettings_swipeunlock, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index 69ede37da..54f57b170 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -43,6 +43,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.Reminder; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WorldClock; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; import nodomain.freeyourgadget.gadgetbridge.util.RtlUtils; @@ -230,6 +231,13 @@ public class GBDeviceService implements DeviceService { invokeService(intent); } + @Override + public void onSetWorldClocks(ArrayList clocks) { + Intent intent = createIntent().setAction(ACTION_SET_WORLD_CLOCKS) + .putExtra(EXTRA_WORLD_CLOCKS, clocks); + invokeService(intent); + } + @Override public void onSetMusicInfo(MusicSpec musicSpec) { Intent intent = createIntent().setAction(ACTION_SETMUSICINFO) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index 8304b8410..ddf52dc7f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -56,6 +56,7 @@ public interface DeviceService extends EventHandler { String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms"; String ACTION_SAVE_ALARMS = PREFIX + ".action.save_alarms"; String ACTION_SET_REMINDERS = PREFIX + ".action.set_reminders"; + String ACTION_SET_WORLD_CLOCKS = PREFIX + ".action.set_world_clocks"; String ACTION_ENABLE_REALTIME_STEPS = PREFIX + ".action.enable_realtime_steps"; String ACTION_REALTIME_SAMPLES = PREFIX + ".action.realtime_samples"; String ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT = PREFIX + ".action.realtime_hr_measurement"; @@ -110,6 +111,7 @@ public interface DeviceService extends EventHandler { String EXTRA_CONFIG = "config"; String EXTRA_ALARMS = "alarms"; String EXTRA_REMINDERS = "reminders"; + String EXTRA_WORLD_CLOCKS = "world_clocks"; String EXTRA_CONNECT_FIRST_TIME = "connect_first_time"; String EXTRA_BOOLEAN_ENABLE = "enable_realtime_steps"; String EXTRA_INTERVAL_SECONDS = "interval_seconds"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/WorldClock.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/WorldClock.java new file mode 100644 index 000000000..1c6b0bd1d --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/WorldClock.java @@ -0,0 +1,30 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.model; + +import java.io.Serializable; + +public interface WorldClock extends Serializable { + /** + * The {@link android.os.Bundle} name for transferring parceled world clocks. + */ + String EXTRA_WORLD_CLOCK = "world_clock"; + + String getWorldClockId(); + String getLabel(); + String getTimeZoneId(); +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index a9f7ddfa6..52df51f46 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -75,6 +75,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.Reminder; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WorldClock; import nodomain.freeyourgadget.gadgetbridge.service.receivers.AutoConnectIntervalReceiver; import nodomain.freeyourgadget.gadgetbridge.service.receivers.GBAutoFetchReceiver; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; @@ -120,6 +121,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SE import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_LED_COLOR; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_REMINDERS; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_WORLD_CLOCKS; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_START; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_STARTAPP; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_TEST_NEW_FUNCTION; @@ -178,6 +180,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_RES import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_URI; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_VIBRATION_INTENSITY; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_WEATHER; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_WORLD_CLOCKS; public class DeviceCommunicationService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener { private static final Logger LOG = LoggerFactory.getLogger(DeviceCommunicationService.class); @@ -586,6 +589,10 @@ public class DeviceCommunicationService extends Service implements SharedPrefere ArrayList reminders = (ArrayList) intent.getSerializableExtra(EXTRA_REMINDERS); mDeviceSupport.onSetReminders(reminders); break; + case ACTION_SET_WORLD_CLOCKS: + ArrayList clocks = (ArrayList) intent.getSerializableExtra(EXTRA_WORLD_CLOCKS); + mDeviceSupport.onSetWorldClocks(clocks); + break; case ACTION_ENABLE_REALTIME_STEPS: { boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false); mDeviceSupport.onEnableRealtimeSteps(enable); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java index 0cc8a6d06..bc946df64 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java @@ -39,6 +39,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.Reminder; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WorldClock; /** * Wraps another device support instance and supports busy-checking and throttling of events. @@ -318,6 +319,14 @@ public class ServiceDeviceSupport implements DeviceSupport { delegate.onSetReminders(reminders); } + @Override + public void onSetWorldClocks(ArrayList clocks) { + if (checkBusy("set world clocks")) { + return; + } + delegate.onSetWorldClocks(clocks); + } + @Override public void onEnableRealtimeSteps(boolean enable) { if (checkBusy("enable realtime steps: " + enable)) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java index 73a9e1b95..9959cc958 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java @@ -38,6 +38,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Reminder; +import nodomain.freeyourgadget.gadgetbridge.model.WorldClock; import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.CheckInitializedAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBleProfile; @@ -378,6 +379,11 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im } + @Override + public void onSetWorldClocks(ArrayList clocks) { + + } + @Override public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 665c34f5a..dbf67a768 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -37,10 +37,16 @@ import net.e175.klaus.solarpositioning.SPA; import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.threeten.bp.Instant; +import org.threeten.bp.ZoneId; +import org.threeten.bp.zone.ZoneOffsetTransition; +import org.threeten.bp.zone.ZoneRules; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -52,6 +58,7 @@ import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.SimpleTimeZone; +import java.util.TimeZone; import java.util.Timer; import java.util.TimerTask; import java.util.UUID; @@ -112,6 +119,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.Reminder; import nodomain.freeyourgadget.gadgetbridge.model.Weather; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WorldClock; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; @@ -925,6 +933,120 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { writeToChunked(builder, 2, buf.array()); } + @Override + public void onSetWorldClocks(ArrayList clocks) { + final TransactionBuilder builder; + try { + builder = performInitialized("onSetWorldClocks"); + } catch (final IOException e) { + LOG.error("Unable to send world clocks to device", e); + return; + } + + sendWorldClocks(builder, clocks); + + builder.queue(getQueue()); + } + + private void setWorldClocks(final TransactionBuilder builder) { + final List clocks = DBHelper.getWorldClocks(gbDevice); + sendWorldClocks(builder, clocks); + } + + private void sendWorldClocks(final TransactionBuilder builder, final List clocks) { + final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice); + if (coordinator.getWorldClocksSlotCount() == 0) { + return; + } + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try { + baos.write(0x03); + + if (clocks.size() != 0) { + int i = clocks.size(); + for (final WorldClock clock : clocks) { + baos.write(i--); + baos.write(encodeWorldClock(clock)); + } + } else { + baos.write(0); + } + } catch (final IOException e) { + LOG.error("Unable to send world clocks to device", e); + return; + } + + writeToChunked2021(builder, (short) 0x0008, getNextHandle(), baos.toByteArray(), false, false); + } + + public byte[] encodeWorldClock(final WorldClock clock) { + final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice); + + try { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + final TimeZone timezone = TimeZone.getTimeZone(clock.getTimeZoneId()); + final ZoneId zoneId = ZoneId.of(clock.getTimeZoneId()); + + // Usually the 3-letter city code (eg. LIS for Lisbon), but doesn't seem to be used in the UI + baos.write(" ".getBytes(StandardCharsets.UTF_8)); + baos.write(0x00); + + // Some other string? Seems to be empty + baos.write(0x00); + + // The city name / label that shows up on the band + baos.write(StringUtils.truncate(clock.getLabel(), coordinator.getWorldClocksLabelLength()).getBytes(StandardCharsets.UTF_8)); + baos.write(0x00); + + // The raw offset from UTC, in number of 15-minute blocks + baos.write((int) (timezone.getRawOffset() / (1000L * 60L * 15L))); + + // Daylight savings + final boolean useDaylightTime = timezone.useDaylightTime(); + final boolean inDaylightTime = timezone.inDaylightTime(new Date()); + byte daylightByte = 0; + // The daylight savings offset, either currently (the previous transition) or future (the next transition), in minutes + byte daylightOffsetMinutes = 0; + + final ZoneRules zoneRules = zoneId.getRules(); + if (useDaylightTime) { + final ZoneOffsetTransition transition; + if (inDaylightTime) { + daylightByte = 0x01; + transition = zoneRules.previousTransition(Instant.now()); + } else { + daylightByte = 0x02; + transition = zoneRules.nextTransition(Instant.now()); + } + daylightOffsetMinutes = (byte) transition.getDuration().toMinutes(); + } + + baos.write(daylightByte); + baos.write(daylightOffsetMinutes); + + // The timestamp of the next daylight savings transition, if any + final ZoneOffsetTransition nextTransition = zoneRules.nextTransition(Instant.now()); + long nextTransitionTs = 0; + if (nextTransition != null) { + nextTransitionTs = nextTransition + .getDateTimeBefore() + .atZone(zoneId) + .toEpochSecond(); + } + + for (int i = 0; i < 4; i++) { + baos.write((byte) ((nextTransitionTs >> (i * 8)) & 0xff)); + } + + return baos.toByteArray(); + } catch (final IOException e) { + throw new RuntimeException("This should never happen", e); + } + } + @Override public void onNotification(NotificationSpec notificationSpec) { if (notificationSpec.type == NotificationType.GENERIC_ALARM_CLOCK) { @@ -3351,6 +3473,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { setExposeHRThridParty(builder); setHeartrateMeasurementInterval(builder, getHeartRateMeasurementInterval()); sendReminders(builder); + setWorldClocks(builder); requestAlarms(builder); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java index 39da5fb9e..d847031d0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java @@ -31,6 +31,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.Reminder; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WorldClock; import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport; /** @@ -276,4 +277,10 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport byte[] bytes = gbDeviceProtocol.encodeReminders(reminders); sendToDevice(bytes); } + + @Override + public void onSetWorldClocks(ArrayList clocks) { + byte[] bytes = gbDeviceProtocol.encodeWorldClocks(clocks); + sendToDevice(bytes); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java index a4408d053..888d64756 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java @@ -27,6 +27,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.Reminder; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WorldClock; public abstract class GBDeviceProtocol { @@ -151,6 +152,10 @@ public abstract class GBDeviceProtocol { return null; } + public byte[] encodeWorldClocks(ArrayList clocks) { + return null; + } + public byte[] encodeFmFrequency(float frequency) { return null; } diff --git a/app/src/main/res/layout/activity_configure_world_clocks.xml b/app/src/main/res/layout/activity_configure_world_clocks.xml new file mode 100644 index 000000000..727f8c4df --- /dev/null +++ b/app/src/main/res/layout/activity_configure_world_clocks.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/app/src/main/res/layout/activity_world_clock_details.xml b/app/src/main/res/layout/activity_world_clock_details.xml new file mode 100644 index 000000000..93bc99fd6 --- /dev/null +++ b/app/src/main/res/layout/activity_world_clock_details.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/device_itemv2.xml b/app/src/main/res/layout/device_itemv2.xml index 98ff82cad..ef17481b9 100644 --- a/app/src/main/res/layout/device_itemv2.xml +++ b/app/src/main/res/layout/device_itemv2.xml @@ -73,15 +73,15 @@ android:id="@+id/device_image" android:layout_width="48dp" android:layout_height="48dp" - android:layout_alignParentStart="true" android:layout_below="@id/device_item_infos_box" - android:contentDescription="@string/candidate_item_device_image" - android:clickable="true" - android:longClickable="true" - android:background="?android:attr/selectableItemBackground" - card_view:srcCompat="@drawable/ic_device_pebble" + android:layout_alignParentStart="true" android:layout_marginTop="2dp" - android:focusable="true" /> + android:background="?android:attr/selectableItemBackground" + android:clickable="true" + android:contentDescription="@string/candidate_item_device_image" + android:focusable="true" + android:longClickable="true" + card_view:srcCompat="@drawable/ic_device_pebble" /> + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8ec87947b..a2422f918 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -486,6 +486,8 @@ Activity and Sleep Configure alarms Configure reminders + World Clocks + Configure clocks for other timezones Configure alarms Configure reminders Repeat @@ -506,8 +508,15 @@ Are you sure you want to delete the reminder? No free slots The device has no free slots for reminders (total slots: %1$s) + Delete \'%1$s\' + Are you sure you want to delete the world clock? + No free slots + The device has no free slots for world clocks (total slots: %1$s) + Time Zone + Label Alarm details Reminder details + World Clock details Sun Mon Tue diff --git a/app/src/main/res/xml/devicesettings_world_clocks.xml b/app/src/main/res/xml/devicesettings_world_clocks.xml new file mode 100644 index 000000000..46d224761 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_world_clocks.xml @@ -0,0 +1,8 @@ + + + + From 46cd229a1411ac1347319739d904d5f00b2f1884 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 10 May 2022 14:16:52 +0200 Subject: [PATCH 042/110] Mi Band 6: Enable World clock setting Also take care of new/old firmware --- .../devices/huami/miband6/MiBand6Coordinator.java | 11 +++++++++++ .../service/devices/huami/HuamiSupport.java | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java index a5aba4b37..527fb5361 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java @@ -70,6 +70,16 @@ public class MiBand6Coordinator extends HuamiCoordinator { return true; } + @Override + public int getWorldClocksSlotCount() { + return 20; // as enforced by Mi Fit + } + + @Override + public int getWorldClocksLabelLength() { + return 30; // at least + } + @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ @@ -78,6 +88,7 @@ public class MiBand6Coordinator extends HuamiCoordinator { R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, + R.xml.devicesettings_world_clocks, R.xml.devicesettings_nightmode, R.xml.devicesettings_liftwrist_display_sensitivity, R.xml.devicesettings_swipeunlock, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index dbf67a768..3ae94aaf8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -978,7 +978,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return; } - writeToChunked2021(builder, (short) 0x0008, getNextHandle(), baos.toByteArray(), false, false); + writeToChunked2021(builder, (short) 0x0008, getNextHandle(), baos.toByteArray(), force2021Protocol, false); } public byte[] encodeWorldClock(final WorldClock clock) { From 05515d6ba2e8f11d85671c21828dbc69676b6ac8 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 10 May 2022 15:29:47 +0200 Subject: [PATCH 043/110] Amazfit Bip S: Enable world clock configuration --- .../huami/amazfitbips/AmazfitBipSCoordinator.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java index 682e8df66..b40541bbe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java @@ -82,11 +82,22 @@ public class AmazfitBipSCoordinator extends HuamiCoordinator { return true; } + @Override + public int getWorldClocksSlotCount() { + return 20; // as enforced by Mi Fit + } + + @Override + public int getWorldClocksLabelLength() { + return 30; // at least + } + @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_amazfitbips, R.xml.devicesettings_timeformat, + R.xml.devicesettings_world_clocks, R.xml.devicesettings_wearlocation, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, From 3a1d4d6161d97507cb4c8c43b197838fa841d948 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 10 May 2022 15:41:12 +0200 Subject: [PATCH 044/110] Amazfip Bip U/Pro: Enable lift wrist sensitity and world clock configuration --- .../huami/amazfitbipu/AmazfitBipUCoordinator.java | 13 ++++++++++++- .../amazfitbipupro/AmazfitBipUProCoordinator.java | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java index bcd415b47..d866addcc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java @@ -93,15 +93,26 @@ public class AmazfitBipUCoordinator extends HuamiCoordinator { return 0; } + @Override + public int getWorldClocksSlotCount() { + return 20; // as enforced by Mi Fit + } + + @Override + public int getWorldClocksLabelLength() { + return 30; // at least + } + @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_amazfitbipu, //R.xml.devicesettings_canned_dismisscall_16, R.xml.devicesettings_timeformat, + R.xml.devicesettings_world_clocks, R.xml.devicesettings_wearlocation, R.xml.devicesettings_custom_emoji_font, - R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_liftwrist_display_sensitivity, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, R.xml.devicesettings_expose_hr_thirdparty, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java index 543525414..ea0af7783 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java @@ -93,14 +93,25 @@ public class AmazfitBipUProCoordinator extends HuamiCoordinator { return 0; } + @Override + public int getWorldClocksSlotCount() { + return 20; // as enforced by Mi Fit + } + + @Override + public int getWorldClocksLabelLength() { + return 30; // at least + } + @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_amazfitbipupro, R.xml.devicesettings_timeformat, + R.xml.devicesettings_world_clocks, R.xml.devicesettings_wearlocation, R.xml.devicesettings_custom_emoji_font, - R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_liftwrist_display_sensitivity, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, R.xml.devicesettings_expose_hr_thirdparty, From 37ba8c291e3b4f1ac15f118a435c862b76bef8f6 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 10 May 2022 15:49:34 +0200 Subject: [PATCH 045/110] Amazfit Band 5: Enbable lift wrist sensitivity and world clock configuration --- .../huami/amazfitband5/AmazfitBand5Coordinator.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java index 314c3887d..f4ed7aae0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java @@ -85,6 +85,16 @@ public class AmazfitBand5Coordinator extends HuamiCoordinator { return true; } + @Override + public int getWorldClocksSlotCount() { + return 20; // as enforced by Mi Fit + } + + @Override + public int getWorldClocksLabelLength() { + return 30; // at least + } + @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ @@ -94,7 +104,7 @@ public class AmazfitBand5Coordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_nightmode, - R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_liftwrist_display_sensitivity, R.xml.devicesettings_swipeunlock, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, From 682b215985eeddf9521e01f487ea9257f6b6d6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Thu, 5 May 2022 14:14:15 +0100 Subject: [PATCH 046/110] Huami: Send media volume to device --- .../gadgetbridge/devices/EventHandler.java | 7 ++++ .../gadgetbridge/impl/GBDeviceService.java | 7 ++++ .../gadgetbridge/model/DeviceService.java | 2 ++ .../service/DeviceCommunicationService.java | 6 ++++ .../service/ServiceDeviceSupport.java | 8 +++++ .../btle/AbstractBTLEDeviceSupport.java | 5 +++ .../service/devices/huami/HuamiSupport.java | 33 ++++++++++++++++++- .../receivers/GBMusicControlReceiver.java | 6 ++++ .../serial/AbstractSerialDeviceSupport.java | 6 ++++ .../service/serial/GBDeviceProtocol.java | 4 +++ 10 files changed, 83 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java index d4ccc7c67..a0ec99c1c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java @@ -60,6 +60,13 @@ public interface EventHandler { void onSetMusicInfo(MusicSpec musicSpec); + /** + * Sets the current phone media volume. + * + * @param volume the volume percentage (0 to 100). + */ + void onSetPhoneVolume(final float volume); + void onEnableRealtimeSteps(boolean enable); void onInstallApp(Uri uri); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index 54f57b170..15f842bb7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -224,6 +224,13 @@ public class GBDeviceService implements DeviceService { invokeService(intent); } + @Override + public void onSetPhoneVolume(final float volume) { + Intent intent = createIntent().setAction(ACTION_SET_PHONE_VOLUME) + .putExtra(EXTRA_PHONE_VOLUME, volume); + invokeService(intent); + } + @Override public void onSetReminders(ArrayList reminders) { Intent intent = createIntent().setAction(ACTION_SET_REMINDERS) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index ddf52dc7f..edb88e8b6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -39,6 +39,7 @@ public interface DeviceService extends EventHandler { String ACTION_SETTIME = PREFIX + ".action.settime"; String ACTION_SETMUSICINFO = PREFIX + ".action.setmusicinfo"; String ACTION_SETMUSICSTATE = PREFIX + ".action.setmusicstate"; + String ACTION_SET_PHONE_VOLUME = PREFIX + ".action.set_phone_volume"; String ACTION_REQUEST_DEVICEINFO = PREFIX + ".action.request_deviceinfo"; String ACTION_REQUEST_APPINFO = PREFIX + ".action.request_appinfo"; String ACTION_REQUEST_SCREENSHOT = PREFIX + ".action.request_screenshot"; @@ -103,6 +104,7 @@ public interface DeviceService extends EventHandler { String EXTRA_MUSIC_REPEAT = "music_repeat"; String EXTRA_MUSIC_POSITION = "music_position"; String EXTRA_MUSIC_RATE = "music_rate"; + String EXTRA_PHONE_VOLUME = "phone_volume"; String EXTRA_APP_UUID = "app_uuid"; String EXTRA_APP_START = "app_start"; String EXTRA_APP_CONFIG = "app_config"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 52df51f46..0708899dd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -120,6 +120,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SE import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_FM_FREQUENCY; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_LED_COLOR; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_PHONE_VOLUME; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_REMINDERS; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_WORLD_CLOCKS; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_START; @@ -174,6 +175,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOT import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SUBJECT; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TITLE; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TYPE; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_PHONE_VOLUME; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_RECORDED_DATA_TYPES; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_REMINDERS; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_RESET_FLAGS; @@ -533,6 +535,10 @@ public class DeviceCommunicationService extends Service implements SharedPrefere musicSpec.trackNr = intent.getIntExtra(EXTRA_MUSIC_TRACKNR, 0); mDeviceSupport.onSetMusicInfo(musicSpec); break; + case ACTION_SET_PHONE_VOLUME: + float phoneVolume = intent.getFloatExtra(EXTRA_PHONE_VOLUME, 0); + mDeviceSupport.onSetPhoneVolume(phoneVolume); + break; case ACTION_SETMUSICSTATE: MusicStateSpec stateSpec = new MusicStateSpec(); stateSpec.shuffle = intent.getByteExtra(EXTRA_MUSIC_SHUFFLE, (byte) 0); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java index bc946df64..37224e887 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java @@ -207,6 +207,14 @@ public class ServiceDeviceSupport implements DeviceSupport { delegate.onSetMusicInfo(musicSpec); } + @Override + public void onSetPhoneVolume(float volume) { + if (checkBusy("set phone volume")) { + return; + } + delegate.onSetPhoneVolume(volume); + } + @Override public void onInstallApp(Uri uri) { if (checkBusy("install app")) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java index 9959cc958..26c1a587c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEDeviceSupport.java @@ -374,6 +374,11 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im } + @Override + public void onSetPhoneVolume(final float volume) { + + } + @Override public void onSetReminders(ArrayList reminders) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 3ae94aaf8..8c9652404 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -26,6 +26,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.media.AudioManager; import android.net.Uri; import android.widget.Toast; @@ -1230,11 +1231,40 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } } - private void sendMusicStateToDevice() { sendMusicStateToDevice(bufferMusicSpec, bufferMusicStateSpec); } + @Override + public void onSetPhoneVolume(final float volume) { + if (characteristicChunked == null) { + return; + } + + final byte[] volumeCommand = new byte[]{0x40, (byte) Math.round(volume)}; + + try { + final TransactionBuilder builder = performInitialized("send volume"); + writeToChunked(builder, 3, volumeCommand); + + builder.queue(getQueue()); + } catch (final IOException e) { + LOG.error("Unable to send volume", e); + } + + LOG.info("sendVolumeStateToDevice: {}", volume); + } + + private void sendVolumeStateToDevice() { + final AudioManager audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); + + final int volumeLevel = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); + final int volumeMax = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + final int volumePercentage = (byte) Math.round(100 * (volumeLevel / (float) volumeMax)); + + onSetPhoneVolume(volumePercentage); + } + protected void sendMusicStateToDevice(MusicSpec musicSpec, MusicStateSpec musicStateSpec) { if (characteristicChunked == null) { return; @@ -1712,6 +1742,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { LOG.info("Music app started"); isMusicAppStarted = true; sendMusicStateToDevice(); + sendVolumeStateToDevice(); break; case (byte) 225: LOG.info("Music app terminated"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBMusicControlReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBMusicControlReceiver.java index 9a7d299b0..5f4542864 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBMusicControlReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/GBMusicControlReceiver.java @@ -76,6 +76,12 @@ public class GBMusicControlReceiver extends BroadcastReceiver { case VOLUMEDOWN: AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, volumeAdjust, 0); + + final int volumeLevel = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); + final int volumeMax = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + final int volumePercentage = (byte) Math.round(100 * (volumeLevel / (float) volumeMax)); + + GBApplication.deviceService().onSetPhoneVolume(volumePercentage); break; default: return; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java index d847031d0..245f5c5d7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java @@ -158,6 +158,12 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport sendToDevice(bytes); } + @Override + public void onSetPhoneVolume(final float volume) { + byte[] bytes = gbDeviceProtocol.encodeVolume(volume); + sendToDevice(bytes); + } + @Override public void onAppInfoReq() { byte[] bytes = gbDeviceProtocol.encodeAppInfoReq(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java index 888d64756..e2f9005da 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java @@ -64,6 +64,10 @@ public abstract class GBDeviceProtocol { return null; } + public byte[] encodeVolume(float volume) { + return null; + } + public byte[] encodeSetMusicState(byte state, int position, int playRate, byte shuffle, byte repeat) { return null; } From 10d11d4818af7217045eb6afa3a5f3b3a397a63b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Mon, 9 May 2022 14:05:08 +0100 Subject: [PATCH 047/110] Mi Band 5: Add support for configuring activity types --- .../DeviceSpecificSettingsFragment.java | 6 +-- .../devices/huami/HuamiConst.java | 1 + .../service/devices/huami/HuamiSupport.java | 48 +++++++++++++++-- .../huami/HuamiWorkoutActivityType.java | 52 +++++++++++++++++++ .../devices/huami/miband5/MiBand5Support.java | 1 + app/src/main/res/values/arrays.xml | 42 +++++++++++++++ app/src/main/res/values/strings.xml | 6 +++ .../main/res/xml/devicesettings_miband5.xml | 10 ++++ 8 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiWorkoutActivityType.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index 4bbd36b6a..4671a325d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -20,7 +20,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.text.InputType; -import android.view.View; import android.widget.EditText; import androidx.annotation.NonNull; @@ -49,13 +48,10 @@ import java.util.Objects; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureWorldClocks; -import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; -import nodomain.freeyourgadget.gadgetbridge.devices.makibeshr3.MakibesHR3Constants; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; @@ -77,6 +73,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_EXPOSE_HR_THIRDPARTY; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS_SORTABLE; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE; @@ -350,6 +347,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp addPreferenceHandlerFor(PREF_DATEFORMAT); addPreferenceHandlerFor(PREF_DISPLAY_ITEMS); addPreferenceHandlerFor(PREF_DISPLAY_ITEMS_SORTABLE); + addPreferenceHandlerFor(PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE); addPreferenceHandlerFor(PREF_SHORTCUTS); addPreferenceHandlerFor(PREF_SHORTCUTS_SORTABLE); addPreferenceHandlerFor(PREF_LANGUAGE); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java index 8fef25994..2ec6b9f77 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java @@ -59,6 +59,7 @@ public class HuamiConst { public static final String PREF_DISPLAY_ITEMS = "display_items"; public static final String PREF_DISPLAY_ITEMS_SORTABLE = "display_items_sortable"; + public static final String PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE = "workout_activity_types_sortable"; public static final String PREF_SHORTCUTS = "shortcuts"; public static final String PREF_SHORTCUTS_SORTABLE = "shortcuts_sortable"; public static final String PREF_EXPOSE_HR_THIRDPARTY = "expose_hr_thirdparty"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 8c9652404..e6d692330 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -139,7 +139,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotific import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.actions.StopNotificationAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2NotificationStrategy; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2TextNotificationStrategy; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband5.MiBand5Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchActivityOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.InitOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.InitOperation2021; @@ -193,14 +192,12 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_BUTTON_ACTION_SELECTION_OFF; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_FELL_SLEEP_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_FELL_SLEEP_SELECTION; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_SELECTION_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_SELECTION_OFF; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_START_NON_WEAR_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_START_NON_WEAR_SELECTION; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_WOKE_UP_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_WOKE_UP_SELECTION; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.DISPLAY_ITEM_BIT_CLOCK; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY_ITEMS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_COUNT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_PROFILE; @@ -2410,6 +2407,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case HuamiConst.PREF_SHORTCUTS_SORTABLE: setShortcuts(builder); break; + case HuamiConst.PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE: + setWorkoutActivityTypes(builder); + break; case MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO: setRotateWristToSwitchInfo(builder); break; @@ -2992,6 +2992,48 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return this; } + protected HuamiSupport setWorkoutActivityTypes(final TransactionBuilder builder) { + final SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()); + + final List allActivityTypes = Arrays.asList(getContext().getResources().getStringArray(R.array.pref_miband5_workout_activity_types_values)); + final List defaultActivityTypes = Arrays.asList(getContext().getResources().getStringArray(R.array.pref_miband5_workout_activity_types_default)); + final String activityTypesPref = prefs.getString(HuamiConst.PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE, null); + + final List enabledActivityTypes; + if (activityTypesPref == null || activityTypesPref.equals("")) { + enabledActivityTypes = defaultActivityTypes; + } else { + enabledActivityTypes = Arrays.asList(activityTypesPref.split(",")); + } + + LOG.info("Setting workout types to {}", enabledActivityTypes); + + final byte[] command = new byte[allActivityTypes.size() * 3 + 2]; + command[0] = 0x0b; + command[1] = 0x00; + + int pos = 2; + + for (final String workoutType : enabledActivityTypes) { + command[pos++] = HuamiWorkoutActivityType.fromPrefValue(workoutType).getCode(); + command[pos++] = 0x00; + command[pos++] = 0x01; + } + + // Send all the remaining disabled workout types + for (final String workoutType : allActivityTypes) { + if (!enabledActivityTypes.contains(workoutType)) { + command[pos++] = HuamiWorkoutActivityType.fromPrefValue(workoutType).getCode(); + command[pos++] = 0x00; + command[pos++] = 0x00; + } + } + + writeToChunked(builder, 9, command); + + return this; + } + protected HuamiSupport setBeepSounds(TransactionBuilder builder) { SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiWorkoutActivityType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiWorkoutActivityType.java new file mode 100644 index 000000000..70688310c --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiWorkoutActivityType.java @@ -0,0 +1,52 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami; + +import java.util.Locale; + +public enum HuamiWorkoutActivityType { + OutdoorRunning(0x01), + Walking(0x06), + Treadmill(0x08), + OutdoorCycling(0x09), + IndoorCycling(0x0a), + Elliptical(0x0c), + PoolSwimming(0x0e), + Freestyle(0x10), + JumpRope(0x15), + RowingMachine(0x17), + Yoga(0x3c); + + private final byte code; + + HuamiWorkoutActivityType(final int code) { + this.code = (byte) code; + } + + public byte getCode() { + return code; + } + + public static HuamiWorkoutActivityType fromPrefValue(final String prefValue) { + for (HuamiWorkoutActivityType type : values()) { + if (type.name().toLowerCase(Locale.ROOT).equals(prefValue.replace("_", "").toLowerCase(Locale.ROOT))) { + return type; + } + } + throw new RuntimeException("No matching HuamiWorkoutActivityType for pref value: " + prefValue); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java index d96edc865..e38fd3861 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java @@ -65,5 +65,6 @@ public class MiBand5Support extends MiBand4Support { super.phase3Initialize(builder); LOG.info("phase3Initialize..."); setActivateDisplayOnLiftWristSensitivity(builder); // TODO? Move this to HuamiSupport? + setWorkoutActivityTypes(builder); // TODO: Supported by other bands? } } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index e9b7245bd..73cea0d25 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -580,6 +580,48 @@ @string/p_menuitem_music + + @string/activity_type_outdoor_running + @string/activity_type_walking + @string/activity_type_treadmill + @string/activity_type_outdoor_cycling + @string/activity_type_indoor_cycling + @string/activity_type_elliptical + @string/activity_type_swimming + @string/activity_type_freestyle + @string/activity_type_jump_roping + @string/activity_type_rowing_machine + @string/activity_type_yoga + + + + outdoor_running + walking + treadmill + outdoor_cycling + indoor_cycling + elliptical + pool_swimming + freestyle + jump_rope + rowing_machine + yoga + + + + outdoor_running + walking + treadmill + outdoor_cycling + indoor_cycling + elliptical + pool_swimming + freestyle + jump_rope + rowing_machine + yoga + + @string/menuitem_pai @string/menuitem_dnd diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a2422f918..7cff8e280 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -688,6 +688,8 @@ Shortcuts Choose the shortcuts on the band screen Sensitivity + Workout Activity Types + Choose the activity types to display on the workouts screen Force black on white color scheme Useful if you your watch has dark hands Hydration reminder @@ -875,13 +877,17 @@ Deep sleep Device not worn Running + Outdoor Running Walking + Freestyle Hiking Climbing Swimming Swimming (Open water) Indoor Cycling + Outdoor Cycling Elliptical Trainer + Elliptical Jumping Rope Yoga Soccer diff --git a/app/src/main/res/xml/devicesettings_miband5.xml b/app/src/main/res/xml/devicesettings_miband5.xml index e7ea6b1a2..326912155 100644 --- a/app/src/main/res/xml/devicesettings_miband5.xml +++ b/app/src/main/res/xml/devicesettings_miband5.xml @@ -20,4 +20,14 @@ android:persistent="true" android:summary="@string/bip_prefs_shotcuts_summary" android:title="@string/bip_prefs_shortcuts" /> + From c31213c34d357f60823fafe57093809f2006ce1b Mon Sep 17 00:00:00 2001 From: Daniel Dakhno Date: Sat, 14 May 2022 04:47:22 +0200 Subject: [PATCH 048/110] VESC: added battery indicator --- .../DeviceSettingsPreferenceConst.java | 3 + .../devices/vesc/VescControlActivity.java | 8 +- .../devices/vesc/VescCoordinator.java | 12 +- .../service/devices/vesc/CommandType.java | 48 +++- .../devices/vesc/VescDeviceSupport.java | 230 +++++++++++++++--- app/src/main/res/xml/devicesettings_vesc.xml | 18 ++ 6 files changed, 274 insertions(+), 45 deletions(-) create mode 100644 app/src/main/res/xml/devicesettings_vesc.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index 39964bdcd..ad1aa2c91 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -184,6 +184,9 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_UM25_SHOW_THRESHOLD_NOTIFICATION = "um25_current_threshold_notify"; public static final String PREF_UM25_SHOW_THRESHOLD = "um25_current_threshold"; + public static final String PREF_VESC_MINIMUM_VOLTAGE = "vesc_minimum_battery_voltage"; + public static final String PREF_VESC_MAXIMUM_VOLTAGE = "vesc_maximum_battery_voltage"; + public static final String PREF_SOUNDS = "sounds"; public static final String PREF_AUTH_KEY = "authkey"; public static final String PREF_USER_FITNESS_GOAL = "fitness_goal"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vesc/VescControlActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vesc/VescControlActivity.java index 8c745f975..18f904a9d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vesc/VescControlActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vesc/VescControlActivity.java @@ -73,7 +73,7 @@ public class VescControlActivity extends AbstractGBActivity { private void restoreValues(){ rpmEditText.setText(String.valueOf(preferences.getInt(PREFS_KEY_LAST_RPM, 0))); - breakCurrentEditText.setText(String.valueOf(preferences.getInt(PREFS_KEY_LAST_BREAK_CURRENT, 0))); + breakCurrentEditText.setText(String.valueOf(preferences.getInt(PREFS_KEY_LAST_BREAK_CURRENT, 0) / 1000)); } @Override @@ -184,7 +184,11 @@ public class VescControlActivity extends AbstractGBActivity { currentBreakCurrentMa = 0; return; } - VescControlActivity.this.currentBreakCurrentMa = Integer.parseInt(text) * 1000; + try { + VescControlActivity.this.currentBreakCurrentMa = Integer.parseInt(text) * 1000; + }catch (NumberFormatException e){ + VescControlActivity.this.currentBreakCurrentMa = 0; + } } }); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vesc/VescCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vesc/VescCoordinator.java index f34dc2083..773b7e6a1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vesc/VescCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vesc/VescCoordinator.java @@ -24,6 +24,7 @@ import android.os.ParcelUuid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; @@ -38,9 +39,11 @@ import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; public class VescCoordinator extends AbstractDeviceCoordinator { public final static String UUID_SERVICE_SERIAL_HM10 = "0000ffe0-0000-1000-8000-00805f9b34fb"; public final static String UUID_CHARACTERISTIC_SERIAL_TX_HM10 = "0000ffe1-0000-1000-8000-00805f9b34fb"; + public final static String UUID_CHARACTERISTIC_SERIAL_RX_HM10 = "0000ffe1-0000-1000-8000-00805f9b34fb"; public final static String UUID_SERVICE_SERIAL_NRF = "0000ffe0-0000-1000-8000-00805f9b34fb"; public final static String UUID_CHARACTERISTIC_SERIAL_TX_NRF = "0000ffe0-0000-1000-8000-00805f9b34fb"; + public final static String UUID_CHARACTERISTIC_SERIAL_RX_NRF = "0000ffe1-0000-1000-8000-00805f9b34fb"; @Override @@ -48,6 +51,13 @@ public class VescCoordinator extends AbstractDeviceCoordinator { } + @Override + public int[] getSupportedDeviceSpecificSettings(GBDevice device) { + return new int[]{ + R.xml.devicesettings_vesc + }; + } + @Override public DeviceType getSupportedType(GBDeviceCandidate candidate) { ParcelUuid[] uuids = candidate.getServiceUuids(); @@ -77,7 +87,7 @@ public class VescCoordinator extends AbstractDeviceCoordinator { @Override public boolean supportsActivityDataFetching() { - return false; + return true; } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vesc/CommandType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vesc/CommandType.java index b1ce868b4..bd0ca8eae 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vesc/CommandType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vesc/CommandType.java @@ -17,17 +17,47 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.vesc; public enum CommandType { - SET_CURRENT((byte) 0x06), - SET_CURRENT_BRAKE((byte) 0x07), - SET_RPM((byte) 0x08), + COMM_FW_VERSION, + COMM_JUMP_TO_BOOTLOADER, + COMM_ERASE_NEW_APP, + COMM_WRITE_NEW_APP_DATA, + COMM_GET_VALUES, + COMM_SET_DUTY, + COMM_SET_CURRENT, + COMM_SET_CURRENT_BRAKE, + COMM_SET_RPM, + COMM_SET_POS, + COMM_SET_HANDBRAKE, + COMM_SET_DETECT, + COMM_SET_SERVO_POS, + COMM_SET_MCCONF, + COMM_GET_MCCONF, + COMM_GET_MCCONF_DEFAULT, + COMM_SET_APPCONF, + COMM_GET_APPCONF, + COMM_GET_APPCONF_DEFAULT, + COMM_SAMPLE_PRINT, + COMM_TERMINAL_CMD, + COMM_PRINT, + COMM_ROTOR_POSITION, + COMM_EXPERIMENT_SAMPLE, + COMM_DETECT_MOTOR_PARAM, + COMM_DETECT_MOTOR_R_L, + COMM_DETECT_MOTOR_FLUX_LINKAGE, + COMM_DETECT_ENCODER, + COMM_DETECT_HALL_FOC, + COMM_REBOOT, + COMM_ALIVE, + COMM_GET_DECODED_PPM, + COMM_GET_DECODED_ADC, + COMM_GET_DECODED_CHUK, + COMM_FORWARD_CAN, + COMM_SET_CHUCK_DATA, + COMM_CUSTOM_APP_DATA, + COMM_NRF_START_PAIRING ; - byte commandByte; - - CommandType(byte commandByte){ - this.commandByte = commandByte; - } public byte getCommandByte(){ - return this.commandByte; + return (byte) this.ordinal(); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vesc/VescDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vesc/VescDeviceSupport.java index ca10ef14a..2007b6f1d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vesc/VescDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vesc/VescDeviceSupport.java @@ -16,11 +16,14 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.vesc; +import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import androidx.localbroadcastmanager.content.LocalBroadcastManager; @@ -28,8 +31,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.UUID; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; import nodomain.freeyourgadget.gadgetbridge.devices.vesc.VescCoordinator; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; @@ -37,32 +43,44 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; import nodomain.freeyourgadget.gadgetbridge.util.CheckSums; -public class VescDeviceSupport extends VescBaseDeviceSupport{ - BluetoothGattCharacteristic serialWriteCharacteristic; +public class VescDeviceSupport extends VescBaseDeviceSupport { + BluetoothGattCharacteristic serialWriteCharacteristic, serialReadCharacteristic; public static final String COMMAND_SET_RPM = "nodomain.freeyourgadget.gadgetbridge.vesc.command.SET_RPM"; public static final String COMMAND_SET_CURRENT = "nodomain.freeyourgadget.gadgetbridge.vesc.command.SET_CURRENT"; public static final String COMMAND_SET_BREAK_CURRENT = "nodomain.freeyourgadget.gadgetbridge.vesc.command.SET_BREAK_CURRENT"; + public static final String COMMAND_GET_VALUES = "nodomain.freeyourgadget.gadgetbridge.vesc.command.GET_VALUES"; public static final String EXTRA_RPM = "EXTRA_RPM"; public static final String EXTRA_CURRENT = "EXTRA_CURRENT"; + public static final String EXTRA_VOLTAGE = "EXTRA_VOLTAGE"; + + public static final String ACTION_GOT_VALUES = "nodomain.freeyourgadget.gadgetbridge.vesc.action.GOT_VALUES"; private Logger logger = LoggerFactory.getLogger(getClass()); private DeviceType deviceType; - public VescDeviceSupport(DeviceType type){ + private ByteBuffer responseBuffer = ByteBuffer.allocate(100); + + public VescDeviceSupport(DeviceType type) { super(); - logger.debug("VescDeviceSupport() {}", type); + responseBuffer.order(ByteOrder.BIG_ENDIAN); deviceType = type; - if(type == DeviceType.VESC_NRF){ + if (type == DeviceType.VESC_NRF) { addSupportedService(UUID.fromString(VescCoordinator.UUID_SERVICE_SERIAL_NRF)); - }else if(type == DeviceType.VESC_HM10){ + } else if (type == DeviceType.VESC_HM10) { addSupportedService(UUID.fromString(VescCoordinator.UUID_SERVICE_SERIAL_HM10)); } } + @Override + public void onFetchRecordedData(int dataTypes) { + super.onFetchRecordedData(dataTypes); + getValues(); + } + @Override protected TransactionBuilder initializeDevice(TransactionBuilder builder) { logger.debug("initializing device"); @@ -71,15 +89,148 @@ public class VescDeviceSupport extends VescBaseDeviceSupport{ initBroadcast(); - if(deviceType == DeviceType.VESC_NRF){ + if (deviceType == DeviceType.VESC_NRF) { this.serialWriteCharacteristic = getCharacteristic(UUID.fromString(VescCoordinator.UUID_CHARACTERISTIC_SERIAL_TX_NRF)); - }else if(deviceType == DeviceType.VESC_HM10){ + this.serialReadCharacteristic = getCharacteristic(UUID.fromString(VescCoordinator.UUID_CHARACTERISTIC_SERIAL_RX_NRF)); + } else if (deviceType == DeviceType.VESC_HM10) { this.serialWriteCharacteristic = getCharacteristic(UUID.fromString(VescCoordinator.UUID_CHARACTERISTIC_SERIAL_TX_HM10)); + this.serialReadCharacteristic = getCharacteristic(UUID.fromString(VescCoordinator.UUID_CHARACTERISTIC_SERIAL_RX_HM10)); } + builder.notify(this.serialReadCharacteristic, true); + return builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext())); } + @Override + public boolean onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { + super.onDescriptorWrite(gatt, descriptor, status); + getValues(); + + return true; + } + + @Override + public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + handleRxCharacteristic(characteristic); + + return true; + } + + private void handleRxCharacteristic(BluetoothGattCharacteristic characteristic) { + if (characteristic != serialReadCharacteristic) return; + + responseBuffer.put(characteristic.getValue()); + short length = 0; + int oldPosition = responseBuffer.position(); + responseBuffer.position(0); + byte lengthType = responseBuffer.get(); + if (lengthType == 2) { + length = responseBuffer.get(); + } else if (lengthType == 3) { + length = responseBuffer.getShort(); + } else { + return; + } + if (length == oldPosition - 5) { + // whole message transmitted + responseBuffer.position(oldPosition); + handleResponseBuffer(responseBuffer); + + oldPosition = 0; + } + responseBuffer.position(oldPosition); + } + + private void handleResponseBuffer(ByteBuffer responseBuffer) { + int bufferLength = responseBuffer.position(); + int payloadStartPosition = responseBuffer.get(0); + + byte[] payload = new byte[bufferLength - 3 - payloadStartPosition]; + System.arraycopy(responseBuffer.array(), payloadStartPosition, payload, 0, payload.length); + + int actualCrc = CheckSums.getCRC16(payload, 0); + int expectedCrc = responseBuffer.getShort(bufferLength - 3); + + byte responseType = payload[0]; + if (responseType == 0x04) { + handleResponseValues(responseBuffer); + } + } + + private void handleResponseValues(ByteBuffer valueBuffer) { + valueBuffer.position(3); + float temp_mos = buffer_get_float16(valueBuffer, 1e1); + float temp_motor = buffer_get_float16(valueBuffer, 1e1); + float current_motor = buffer_get_float32(valueBuffer, 1e2); + float current_in = buffer_get_float32(valueBuffer, 1e2); + float id = buffer_get_float32(valueBuffer, 1e2); + float iq = buffer_get_float32(valueBuffer, 1e2); + float duty_now = buffer_get_float16(valueBuffer, 1e3); + float rpm = buffer_get_float32(valueBuffer, 1e0); + float v_in = buffer_get_float16(valueBuffer, 1e1); + float amp_hours = buffer_get_float32(valueBuffer, 1e4); + float amp_hours_charged = buffer_get_float32(valueBuffer, 1e4); + float watt_hours = buffer_get_float32(valueBuffer, 1e4); + float watt_hours_charged = buffer_get_float32(valueBuffer, 1e4); + float tachometer = buffer_get_int32(valueBuffer); + float tachometer_abs = buffer_get_int32(valueBuffer); + + handleBatteryVoltage(v_in); + + Intent intent = new Intent(ACTION_GOT_VALUES); + intent.putExtra(EXTRA_VOLTAGE, v_in); + } + + + + void handleBatteryVoltage(float voltage){ + SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); + float minimalVoltage = Float.parseFloat(prefs.getString(DeviceSettingsPreferenceConst.PREF_VESC_MINIMUM_VOLTAGE, "-1")); + float maximalVoltage = Float.parseFloat(prefs.getString(DeviceSettingsPreferenceConst.PREF_VESC_MAXIMUM_VOLTAGE, "-1")); + + if(minimalVoltage == -1){ + return; + } + if(maximalVoltage == -1){ + return; + } + + float voltageAboveMinimum = voltage - minimalVoltage; + float voltageRange = maximalVoltage - minimalVoltage; + float fullness = voltageAboveMinimum / voltageRange; + + int fullnessPercent = (int)(fullness * 100); + fullnessPercent = Math.max(fullnessPercent, 0); + fullnessPercent = Math.min(fullnessPercent, 100); + + getDevice().setBatteryLevel(fullnessPercent); + getDevice().setBatteryVoltage(voltage); + getDevice().sendDeviceUpdateIntent(getContext()); + } + + float buffer_get_float16(ByteBuffer buffer, double scale){ + return (float) (buffer.getShort() / scale); + } + + float buffer_get_float32(ByteBuffer buffer, double scale){ + return (float) (buffer.getInt() / scale); + } + + int buffer_get_int32(ByteBuffer buffer){ + return buffer.getInt(); + } + + @Override + public void onTestNewFunction() { + getValues(); + // getDecodedADC(); + } + + private void getDecodedADC() { + buildAndQueryPacket(CommandType.COMM_GET_DECODED_ADC); + } + private void initBroadcast() { LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getContext()); @@ -87,86 +238,99 @@ public class VescDeviceSupport extends VescBaseDeviceSupport{ filter.addAction(COMMAND_SET_RPM); filter.addAction(COMMAND_SET_CURRENT); filter.addAction(COMMAND_SET_BREAK_CURRENT); + filter.addAction(COMMAND_GET_VALUES); broadcastManager.registerReceiver(commandReceiver, filter); } + @Override + public void dispose() { + super.dispose(); + LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(commandReceiver); + } + BroadcastReceiver commandReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if(intent.getAction().equals(COMMAND_SET_RPM)){ + if (intent.getAction().equals(COMMAND_SET_RPM)) { VescDeviceSupport.this.setRPM( intent.getIntExtra(EXTRA_RPM, 0) ); - }else if(intent.getAction().equals(COMMAND_SET_BREAK_CURRENT)){ + } else if (intent.getAction().equals(COMMAND_SET_BREAK_CURRENT)) { VescDeviceSupport.this.setBreakCurrent( intent.getIntExtra(EXTRA_CURRENT, 0) ); - }else if(intent.getAction().equals(COMMAND_SET_CURRENT)){ + } else if (intent.getAction().equals(COMMAND_SET_CURRENT)) { VescDeviceSupport.this.setCurrent( intent.getIntExtra(EXTRA_CURRENT, 0) ); + } else if (intent.getAction().equals(COMMAND_GET_VALUES)) { + VescDeviceSupport.this.getValues(); } } }; - public void setCurrent(int currentMillisAmperes){ - buildAndQueryPacket(CommandType.SET_CURRENT, currentMillisAmperes); + public void setCurrent(int currentMillisAmperes) { + buildAndQueryPacket(CommandType.COMM_SET_CURRENT, currentMillisAmperes); } - public void setBreakCurrent(int breakCurrentMillisAmperes){ - buildAndQueryPacket(CommandType.SET_CURRENT_BRAKE, breakCurrentMillisAmperes); + public void setBreakCurrent(int breakCurrentMillisAmperes) { + buildAndQueryPacket(CommandType.COMM_SET_CURRENT_BRAKE, breakCurrentMillisAmperes); } - public void setRPM(int rpm){ - buildAndQueryPacket(CommandType.SET_RPM, rpm); + public void getValues() { + buildAndQueryPacket(CommandType.COMM_GET_VALUES); } - public void buildAndQueryPacket(CommandType commandType, Object ... args){ + public void setRPM(int rpm) { + buildAndQueryPacket(CommandType.COMM_SET_RPM, rpm); + } + + public void buildAndQueryPacket(CommandType commandType, Object... args) { byte[] data = buildPacket(commandType, args); queryPacket(data); } - public void queryPacket(byte[] data){ + public void queryPacket(byte[] data) { new TransactionBuilder("write serial packet") .write(this.serialWriteCharacteristic, data) .queue(getQueue()); } - public byte[] buildPacket(CommandType commandType, Object ... args){ + public byte[] buildPacket(CommandType commandType, Object... args) { int dataLength = 0; - for(Object arg : args){ - if(arg instanceof Integer) dataLength += 4; - else if(arg instanceof Short) dataLength += 2; + for (Object arg : args) { + if (arg instanceof Integer) dataLength += 4; + else if (arg instanceof Short) dataLength += 2; } ByteBuffer buffer = ByteBuffer.allocate(dataLength); - for(Object arg : args){ - if(arg instanceof Integer) buffer.putInt((Integer) arg); - if(arg instanceof Short) buffer.putShort((Short) arg); + for (Object arg : args) { + if (arg instanceof Integer) buffer.putInt((Integer) arg); + if (arg instanceof Short) buffer.putShort((Short) arg); } return buildPacket(commandType, buffer.array()); } - public byte[] buildPacket(CommandType commandType, byte[] data){ + public byte[] buildPacket(CommandType commandType, byte[] data) { return buildPacket(commandType.getCommandByte(), data); } - private byte[] buildPacket(byte commandByte, byte[] data){ + private byte[] buildPacket(byte commandByte, byte[] data) { byte[] contents = new byte[data.length + 1]; contents[0] = commandByte; System.arraycopy(data, 0, contents, 1, data.length); return buildPacket(contents); } - private byte[] buildPacket(byte[] contents){ + private byte[] buildPacket(byte[] contents) { int dataLength = contents.length; ByteBuffer buffer = ByteBuffer.allocate(dataLength + (dataLength < 256 ? 5 : 6)); - if(dataLength < 256){ - buffer.put((byte)0x02); - buffer.put((byte)dataLength); - }else{ + if (dataLength < 256) { + buffer.put((byte) 0x02); + buffer.put((byte) dataLength); + } else { buffer.put((byte) 0x03); buffer.putShort((short) dataLength); } diff --git a/app/src/main/res/xml/devicesettings_vesc.xml b/app/src/main/res/xml/devicesettings_vesc.xml new file mode 100644 index 000000000..d4906ee06 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_vesc.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file From 5f73dd79e63555e7fe312c320eebb71c75f241a1 Mon Sep 17 00:00:00 2001 From: vanous Date: Sat, 14 May 2022 14:42:07 +0200 Subject: [PATCH 049/110] Amazfit Band 5: enable: world clocks settings, display on lift sensitivity, configuring activity types --- .../huami/amazfitband5/AmazfitBand5Coordinator.java | 1 + .../huami/amazfitband5/AmazfitBand5Support.java | 12 ++++++++++++ app/src/main/res/xml/devicesettings_amazfitband5.xml | 10 ++++++++++ 3 files changed, 23 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java index f4ed7aae0..4616431c9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java @@ -103,6 +103,7 @@ public class AmazfitBand5Coordinator extends HuamiCoordinator { R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, + R.xml.devicesettings_world_clocks, R.xml.devicesettings_nightmode, R.xml.devicesettings_liftwrist_display_sensitivity, R.xml.devicesettings_swipeunlock, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitband5/AmazfitBand5Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitband5/AmazfitBand5Support.java index a828b6a51..6b3a410de 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitband5/AmazfitBand5Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitband5/AmazfitBand5Support.java @@ -49,4 +49,16 @@ public class AmazfitBand5Support extends MiBand5Support { public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException { return new AmazfitBand5FWHelper(uri, context); } + @Override + public boolean supportsSunriseSunsetWindHumidity() { + return true; + } + + @Override + public void phase3Initialize(TransactionBuilder builder) { + super.phase3Initialize(builder); + LOG.info("phase3Initialize..."); + setActivateDisplayOnLiftWristSensitivity(builder); // TODO? Move this to HuamiSupport? + setWorkoutActivityTypes(builder); // TODO: Supported by other bands? + } } diff --git a/app/src/main/res/xml/devicesettings_amazfitband5.xml b/app/src/main/res/xml/devicesettings_amazfitband5.xml index 0ef11beca..3ee60e7e1 100644 --- a/app/src/main/res/xml/devicesettings_amazfitband5.xml +++ b/app/src/main/res/xml/devicesettings_amazfitband5.xml @@ -20,4 +20,14 @@ android:persistent="true" android:summary="@string/bip_prefs_shotcuts_summary" android:title="@string/bip_prefs_shortcuts" /> + From b220fef74ebef352877497df52c33438c0e7cdb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 14 May 2022 14:20:28 +0100 Subject: [PATCH 050/110] Mi Band 5: Add notification vibration patterns --- .../DeviceSpecificSettingsCustomizer.java | 7 + .../DeviceSpecificSettingsFragment.java | 25 +- .../DeviceSpecificSettingsHandler.java | 8 + .../devices/huami/HuamiConst.java | 33 +++ .../devices/huami/HuamiCoordinator.java | 19 ++ .../huami/HuamiSettingsCustomizer.java | 104 +++++++ .../huami/miband5/MiBand5Coordinator.java | 1 + .../devices/miband/VibrationProfile.java | 4 + .../SonyHeadphonesSettingsCustomizer.java | 7 + .../service/devices/huami/HuamiSupport.java | 135 +++++++++- ...HuamiVibrationPatternNotificationType.java | 42 +++ .../drawable/ic_action_find_lost_device.xml | 10 +- .../res/drawable/ic_device_set_reminders.xml | 2 +- app/src/main/res/drawable/ic_phone.xml | 5 + app/src/main/res/drawable/ic_seat_normal.xml | 5 + app/src/main/res/drawable/ic_star_gray.xml | 9 + app/src/main/res/values/strings.xml | 5 + .../xml/devicesettings_miband5_vibration.xml | 253 ++++++++++++++++++ 18 files changed, 658 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiVibrationPatternNotificationType.java create mode 100644 app/src/main/res/drawable/ic_phone.xml create mode 100644 app/src/main/res/drawable/ic_seat_normal.xml create mode 100644 app/src/main/res/drawable/ic_star_gray.xml create mode 100644 app/src/main/res/xml/devicesettings_miband5_vibration.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java index 3a8ac1323..fc948131a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java @@ -20,6 +20,8 @@ import android.os.Parcelable; import androidx.preference.Preference; +import java.util.Set; + /** * A device-specific preference handler, that allows for concrete implementations to customize the preferences in * the {@link DeviceSpecificSettingsFragment}. @@ -39,4 +41,9 @@ public interface DeviceSpecificSettingsCustomizer extends Parcelable { * @param handler the {@link DeviceSpecificSettingsHandler} */ void customizeSettings(final DeviceSpecificSettingsHandler handler); + + /** + * Keys of preferences which should print its values as a summary below the preference name. + */ + Set getPreferenceKeysWithSummary(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index 4671a325d..cc7d588b1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -43,7 +43,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; @@ -806,7 +808,8 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp } } - private void setInputTypeFor(final String preferenceKey, final int editTypeFlags) { + @Override + public void setInputTypeFor(final String preferenceKey, final int editTypeFlags) { EditTextPreference textPreference = findPreference(preferenceKey); if (textPreference != null) { textPreference.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() { @@ -818,6 +821,19 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp } } + /** + * Keys of preferences which should print its values as a summary below the preference name. + */ + protected Set getPreferenceKeysWithSummary() { + final Set keysWithSummary = new HashSet<>(); + + if (deviceSpecificSettingsCustomizer != null) { + keysWithSummary.addAll(deviceSpecificSettingsCustomizer.getPreferenceKeysWithSummary()); + } + + return keysWithSummary; + } + /** * Reload the preferences in the current screen. This is needed when the user enters or exists a PreferenceScreen, * otherwise the settings won't be reloaded by the {@link SharedPreferencesChangeHandler}, as the preferences return @@ -849,7 +865,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { LOG.debug("Preference changed: {}", key); - if(key == null){ + if (key == null){ LOG.warn("Preference null, ignoring"); return; } @@ -879,6 +895,11 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp LOG.warn("Unknown preference class {}, ignoring", preference.getClass()); } + if (getPreferenceKeysWithSummary().contains(key)) { + final String summary = prefs.getString(key, preference.getSummary() != null ? preference.getSummary().toString() : ""); + preference.setSummary(summary); + } + if (deviceSpecificSettingsCustomizer != null) { deviceSpecificSettingsCustomizer.onPreferenceChange(preference, DeviceSpecificSettingsFragment.this); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsHandler.java index 47d4a4095..97917e837 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsHandler.java @@ -53,4 +53,12 @@ public interface DeviceSpecificSettingsHandler { * @param extraListener the extra listener. */ void addPreferenceHandlerFor(final String preferenceKey, Preference.OnPreferenceChangeListener extraListener); + + /** + * Sets the input type flags for an EditText preference. + * + * @param preferenceKey the preference key. + * @param editTypeFlags the edit type {@link android.text.InputType} flags. + */ + void setInputTypeFor(final String preferenceKey, final int editTypeFlags); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java index 2ec6b9f77..1b388391c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java @@ -86,6 +86,39 @@ public class HuamiConst { public static final String PREF_DEVICE_ACTION_START_NON_WEAR_SELECTION = "events_forwarding_startnonwear_action_selection"; public static final String PREF_DEVICE_ACTION_START_NON_WEAR_BROADCAST = "prefs_events_forwarding_startnonwear_broadcast"; + /** + * The suffixes match the enum {@link nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType}. + */ + // profile + public static final String PREF_HUAMI_VIBRATION_PROFILE_PREFIX = "huami_vibration_profile_"; + public static final String PREF_HUAMI_VIBRATION_PROFILE_APP_ALERTS = PREF_HUAMI_VIBRATION_PROFILE_PREFIX + "app_alerts"; + public static final String PREF_HUAMI_VIBRATION_PROFILE_INCOMING_CALL = PREF_HUAMI_VIBRATION_PROFILE_PREFIX + "incoming_call"; + public static final String PREF_HUAMI_VIBRATION_PROFILE_INCOMING_SMS = PREF_HUAMI_VIBRATION_PROFILE_PREFIX + "incoming_sms"; + public static final String PREF_HUAMI_VIBRATION_PROFILE_GOAL_NOTIFICATION = PREF_HUAMI_VIBRATION_PROFILE_PREFIX + "goal_notification"; + public static final String PREF_HUAMI_VIBRATION_PROFILE_ALARM = PREF_HUAMI_VIBRATION_PROFILE_PREFIX + "alarm"; + public static final String PREF_HUAMI_VIBRATION_PROFILE_IDLE_ALERTS = PREF_HUAMI_VIBRATION_PROFILE_PREFIX + "idle_alerts"; + public static final String PREF_HUAMI_VIBRATION_PROFILE_EVENT_REMINDER = PREF_HUAMI_VIBRATION_PROFILE_PREFIX + "event_reminder"; + public static final String PREF_HUAMI_VIBRATION_PROFILE_FIND_BAND = PREF_HUAMI_VIBRATION_PROFILE_PREFIX + "find_band"; + // count + public static final String PREF_HUAMI_VIBRATION_COUNT_PREFIX = "huami_vibration_count_"; + public static final String PREF_HUAMI_VIBRATION_COUNT_APP_ALERTS = PREF_HUAMI_VIBRATION_COUNT_PREFIX + "app_alerts"; + public static final String PREF_HUAMI_VIBRATION_COUNT_INCOMING_CALL = PREF_HUAMI_VIBRATION_COUNT_PREFIX + "incoming_call"; + public static final String PREF_HUAMI_VIBRATION_COUNT_INCOMING_SMS = PREF_HUAMI_VIBRATION_COUNT_PREFIX + "incoming_sms"; + public static final String PREF_HUAMI_VIBRATION_COUNT_GOAL_NOTIFICATION = PREF_HUAMI_VIBRATION_COUNT_PREFIX + "goal_notification"; + public static final String PREF_HUAMI_VIBRATION_COUNT_ALARM = PREF_HUAMI_VIBRATION_COUNT_PREFIX + "alarm"; + public static final String PREF_HUAMI_VIBRATION_COUNT_IDLE_ALERTS = PREF_HUAMI_VIBRATION_COUNT_PREFIX + "idle_alerts"; + public static final String PREF_HUAMI_VIBRATION_COUNT_EVENT_REMINDER = PREF_HUAMI_VIBRATION_COUNT_PREFIX + "event_reminder"; + public static final String PREF_HUAMI_VIBRATION_COUNT_FIND_BAND = PREF_HUAMI_VIBRATION_COUNT_PREFIX + "find_band"; + // try + public static final String PREF_HUAMI_VIBRATION_TRY_PREFIX = "huami_vibration_try_"; + public static final String PREF_HUAMI_VIBRATION_TRY_APP_ALERTS = PREF_HUAMI_VIBRATION_TRY_PREFIX + "app_alerts"; + public static final String PREF_HUAMI_VIBRATION_TRY_INCOMING_CALL = PREF_HUAMI_VIBRATION_TRY_PREFIX + "incoming_call"; + public static final String PREF_HUAMI_VIBRATION_TRY_INCOMING_SMS = PREF_HUAMI_VIBRATION_TRY_PREFIX + "incoming_sms"; + public static final String PREF_HUAMI_VIBRATION_TRY_GOAL_NOTIFICATION = PREF_HUAMI_VIBRATION_TRY_PREFIX + "goal_notification"; + public static final String PREF_HUAMI_VIBRATION_TRY_ALARM = PREF_HUAMI_VIBRATION_TRY_PREFIX + "alarm"; + public static final String PREF_HUAMI_VIBRATION_TRY_IDLE_ALERTS = PREF_HUAMI_VIBRATION_TRY_PREFIX + "idle_alerts"; + public static final String PREF_HUAMI_VIBRATION_TRY_EVENT_REMINDER = PREF_HUAMI_VIBRATION_TRY_PREFIX + "event_reminder"; + public static final String PREF_HUAMI_VIBRATION_TRY_FIND_BAND = PREF_HUAMI_VIBRATION_TRY_PREFIX + "find_band"; public static int toActivityKind(int rawType) { switch (rawType) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java index af54a0a2f..c19c6b18d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java @@ -43,6 +43,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.miband.DateTimeDisplay; @@ -51,11 +52,13 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2SampleProvider import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPairingActivity; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySampleDao; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { @@ -270,6 +273,17 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { return prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_BT_CONNECTED_ADVERTISEMENT, false); } + public static VibrationProfile getVibrationProfile(String deviceAddress, HuamiVibrationPatternNotificationType notificationType) { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); + final String vibrationProfileId = prefs.getString( + HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_PREFIX + notificationType.name().toLowerCase(Locale.ROOT), + VibrationProfile.ID_MEDIUM + ); + final int vibrationProfileCount = prefs.getInt(HuamiConst.PREF_HUAMI_VIBRATION_COUNT_PREFIX + notificationType.name().toLowerCase(Locale.ROOT), 2); + + return VibrationProfile.getProfile(vibrationProfileId, (short) vibrationProfileCount); + } + protected static Date getTimePreference(String key, String defaultValue, String deviceAddress) { Prefs prefs; @@ -353,4 +367,9 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { public int getReminderSlotCount() { return 22; // At least, Mi Fit still allows more } + + @Override + public DeviceSpecificSettingsCustomizer getDeviceSpecificSettingsCustomizer(final GBDevice device) { + return new HuamiSettingsCustomizer(device); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java new file mode 100644 index 000000000..fef6626d2 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java @@ -0,0 +1,104 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.devices.huami; + +import android.os.Parcel; +import android.text.InputType; +import android.widget.Toast; + +import androidx.preference.Preference; + +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType; + +public class HuamiSettingsCustomizer implements DeviceSpecificSettingsCustomizer { + final GBDevice device; + + public HuamiSettingsCustomizer(final GBDevice device) { + this.device = device; + } + + @Override + public void onPreferenceChange(final Preference preference, final DeviceSpecificSettingsHandler handler) { + // Nothing to do here + } + + @Override + public void customizeSettings(final DeviceSpecificSettingsHandler handler) { + for (HuamiVibrationPatternNotificationType notificationType : HuamiVibrationPatternNotificationType.values()) { + final String typeKey = notificationType.name().toLowerCase(Locale.ROOT); + + handler.addPreferenceHandlerFor(HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_PREFIX + typeKey); + handler.addPreferenceHandlerFor(HuamiConst.PREF_HUAMI_VIBRATION_COUNT_PREFIX + typeKey); + handler.setInputTypeFor(HuamiConst.PREF_HUAMI_VIBRATION_COUNT_PREFIX + typeKey, InputType.TYPE_CLASS_NUMBER); + + final String tryPrefKey = HuamiConst.PREF_HUAMI_VIBRATION_TRY_PREFIX + typeKey; + final Preference tryPref = handler.findPreference(tryPrefKey); + if (tryPref != null) { + tryPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(final Preference preference) { + GBApplication.deviceService().onSendConfiguration(tryPrefKey); + return true; + } + }); + } + } + } + + @Override + public Set getPreferenceKeysWithSummary() { + final Set keysWithSummary = new HashSet<>(); + + for (HuamiVibrationPatternNotificationType notificationType : HuamiVibrationPatternNotificationType.values()) { + final String typeKey = notificationType.name().toLowerCase(Locale.ROOT); + keysWithSummary.add(HuamiConst.PREF_HUAMI_VIBRATION_COUNT_PREFIX + typeKey); + } + + return keysWithSummary; + } + + public static final Creator CREATOR = new Creator() { + @Override + public HuamiSettingsCustomizer createFromParcel(final Parcel in) { + final GBDevice device = in.readParcelable(HuamiSettingsCustomizer.class.getClassLoader()); + return new HuamiSettingsCustomizer(device); + } + + @Override + public HuamiSettingsCustomizer[] newArray(final int size) { + return new HuamiSettingsCustomizer[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(final Parcel dest, final int flags) { + dest.writeParcelable(device, 0); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java index 8bf08ac85..d8bd5ac5f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java @@ -99,6 +99,7 @@ public class MiBand5Coordinator extends HuamiCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_miband5, + R.xml.devicesettings_miband5_vibration, R.xml.devicesettings_wearlocation, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java index d7505bcdc..70cbd9d3c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java @@ -79,6 +79,10 @@ public class VibrationProfile { * @param repeat how often the sequence shall be repeated */ public VibrationProfile(String id, int[] onOffSequence, short repeat) { + if (onOffSequence.length % 2 != 0) { + throw new IllegalArgumentException("Each on duration must have a subsequent off duration"); + } + this.id = id; this.repeat = repeat; this.onOffSequence = onOffSequence; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java index 3bb3148dc..0a8eb477d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java @@ -47,8 +47,10 @@ import androidx.preference.ListPreference; import androidx.preference.Preference; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Set; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; @@ -185,6 +187,11 @@ public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsC } } + @Override + public Set getPreferenceKeysWithSummary() { + return Collections.emptySet(); + } + public static final Creator CREATOR = new Creator() { @Override public SonyHeadphonesSettingsCustomizer createFromParcel(final Parcel in) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index e6d692330..a2b4b40b9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -197,6 +197,33 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_START_NON_WEAR_SELECTION; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_WOKE_UP_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_WOKE_UP_SELECTION; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_COUNT_ALARM; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_COUNT_APP_ALERTS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_COUNT_EVENT_REMINDER; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_COUNT_FIND_BAND; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_COUNT_GOAL_NOTIFICATION; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_COUNT_IDLE_ALERTS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_COUNT_INCOMING_CALL; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_COUNT_INCOMING_SMS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_COUNT_PREFIX; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_ALARM; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_APP_ALERTS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_EVENT_REMINDER; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_FIND_BAND; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_GOAL_NOTIFICATION; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_IDLE_ALERTS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_INCOMING_CALL; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_INCOMING_SMS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_PROFILE_PREFIX; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_ALARM; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_APP_ALERTS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_EVENT_REMINDER; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_FIND_BAND; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_GOAL_NOTIFICATION; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_IDLE_ALERTS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_INCOMING_CALL; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_INCOMING_SMS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_PREFIX; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.DISPLAY_ITEM_BIT_CLOCK; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY_ITEMS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_COUNT; @@ -2465,6 +2492,32 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case PREF_USER_GENDER: setUserInfo(builder); break; + case PREF_HUAMI_VIBRATION_PROFILE_APP_ALERTS: + case PREF_HUAMI_VIBRATION_PROFILE_INCOMING_CALL: + case PREF_HUAMI_VIBRATION_PROFILE_INCOMING_SMS: + case PREF_HUAMI_VIBRATION_PROFILE_GOAL_NOTIFICATION: + case PREF_HUAMI_VIBRATION_PROFILE_ALARM: + case PREF_HUAMI_VIBRATION_PROFILE_IDLE_ALERTS: + case PREF_HUAMI_VIBRATION_PROFILE_EVENT_REMINDER: + case PREF_HUAMI_VIBRATION_PROFILE_FIND_BAND: + case PREF_HUAMI_VIBRATION_COUNT_APP_ALERTS: + case PREF_HUAMI_VIBRATION_COUNT_INCOMING_CALL: + case PREF_HUAMI_VIBRATION_COUNT_INCOMING_SMS: + case PREF_HUAMI_VIBRATION_COUNT_GOAL_NOTIFICATION: + case PREF_HUAMI_VIBRATION_COUNT_ALARM: + case PREF_HUAMI_VIBRATION_COUNT_IDLE_ALERTS: + case PREF_HUAMI_VIBRATION_COUNT_EVENT_REMINDER: + case PREF_HUAMI_VIBRATION_COUNT_FIND_BAND: + case PREF_HUAMI_VIBRATION_TRY_APP_ALERTS: + case PREF_HUAMI_VIBRATION_TRY_INCOMING_CALL: + case PREF_HUAMI_VIBRATION_TRY_INCOMING_SMS: + case PREF_HUAMI_VIBRATION_TRY_GOAL_NOTIFICATION: + case PREF_HUAMI_VIBRATION_TRY_ALARM: + case PREF_HUAMI_VIBRATION_TRY_IDLE_ALERTS: + case PREF_HUAMI_VIBRATION_TRY_EVENT_REMINDER: + case PREF_HUAMI_VIBRATION_TRY_FIND_BAND: + setVibrationPattern(builder, config); + break; } builder.queue(getQueue()); } catch (IOException e) { @@ -2480,16 +2533,82 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { @Override public void onTestNewFunction() { //requestMTU(23); - /* try { - boolean test = false; - TransactionBuilder builder = performInitialized("test pattern"); - byte[] testpattern = new byte[] {0x20,0x00, (byte) 0x4b,0x64,0x00, (byte) 0x8d,0x01,0x73,0x00,0x38,0x01,0x64,0x00,0x64,0x00,0x64,0x00,0x67,0x00,0x64,0x00,0x37,0x01,0x7c,0x00,0x64,0x00,0x64,0x00,0x67,0x00,0x64,0x00,0x67,0x00,0x64,0x00,0x37,0x01,0x64,0x00,0x64,0x00,0x64,0x00, (byte) 0xe5,0x02}; - //byte[] testpattern = new byte[] {0x20,0x00, (byte) 0x00, 0,0,0,0}; - writeToChunked(builder,2, testpattern); + final TransactionBuilder builder = performInitialized("test pattern"); + final VibrationProfile profile = VibrationProfile.getProfile(VibrationProfile.ID_SHORT, (short) 2); + + setVibrationPattern(builder, HuamiVibrationPatternNotificationType.APP_ALERTS, true, profile); builder.queue(getQueue()); - } catch (Exception ignored) {} - */ + } catch (final Exception e) { + LOG.error("onTestNewFunction failed", e); + } + } + + private void setVibrationPattern(final TransactionBuilder builder, final String preferenceKey) { + // The preference key has one of the 3 prefixes + final String notificationTypeName = preferenceKey.replace(PREF_HUAMI_VIBRATION_COUNT_PREFIX, "") + .replace(PREF_HUAMI_VIBRATION_PROFILE_PREFIX, "") + .replace(PREF_HUAMI_VIBRATION_TRY_PREFIX, "") + .toUpperCase(Locale.ROOT); + final HuamiVibrationPatternNotificationType notificationType = HuamiVibrationPatternNotificationType.valueOf(notificationTypeName); + final boolean isTry = preferenceKey.startsWith(PREF_HUAMI_VIBRATION_TRY_PREFIX); + + final VibrationProfile vibrationProfile = HuamiCoordinator.getVibrationProfile(getDevice().getAddress(), notificationType); + + setVibrationPattern(builder, notificationType, isTry, vibrationProfile); + } + + /** + * Test or set a {@link VibrationProfile}. + * + * @param builder the {@link TransactionBuilder} + * @param notificationType the notification type + * @param test test the pattern (only vibrate the band, do not set it) + * @param profile the {@link VibrationProfile} + */ + private void setVibrationPattern(final TransactionBuilder builder, + final HuamiVibrationPatternNotificationType notificationType, + final boolean test, + final VibrationProfile profile) { + final int MAX_TOTAL_LENGTH_MS = 10_000; // 10 seconds, about as long as Mi Fit allows + int totalLengthMs = 0; + + // The on-off sequence, until the max total length is reached + final List onOff = new ArrayList<>(profile.getOnOffSequence().length); + + for (int c = 0; c < profile.getRepeat(); c++) { + for (int i = 0; i < profile.getOnOffSequence().length; i += 2) { + final short on = (short) profile.getOnOffSequence()[i]; + final short off = (short) profile.getOnOffSequence()[i + 1]; + + if (totalLengthMs + on + off > MAX_TOTAL_LENGTH_MS) { + LOG.warn("VibrationProfile {} too long, truncating to {} ms", profile.getId(), MAX_TOTAL_LENGTH_MS); + break; + } + + onOff.add(on); + onOff.add(off); + totalLengthMs += on + off; + } + } + + final ByteBuffer buf = ByteBuffer.allocate(3 + 2 * onOff.size()); + buf.order(ByteOrder.LITTLE_ENDIAN); + + buf.put((byte) 0x20); + buf.put(notificationType.getCode()); + byte flag = (byte) (onOff.size() / 2); + flag |= 0x40; + if (test) { + flag |= 0x80; + } + buf.put(flag); + + for (Short time : onOff) { + buf.putShort(time); + } + + writeToChunked(builder, 2, buf.array()); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiVibrationPatternNotificationType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiVibrationPatternNotificationType.java new file mode 100644 index 000000000..ba9ea0aae --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiVibrationPatternNotificationType.java @@ -0,0 +1,42 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami; + +/** + * The notification types for which vibration patterns are customizable. If these change, the + * constants in {@link nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst} need to be updated. + */ +public enum HuamiVibrationPatternNotificationType { + APP_ALERTS(0x00), + INCOMING_CALL(0x01), + INCOMING_SMS(0x02), + GOAL_NOTIFICATION(0x04), + ALARM(0x05), + IDLE_ALERTS(0x06), + EVENT_REMINDER(0x08), + FIND_BAND(0x09); + + private final byte code; + + HuamiVibrationPatternNotificationType(final int code) { + this.code = (byte) code; + } + + public byte getCode() { + return code; + } +} diff --git a/app/src/main/res/drawable/ic_action_find_lost_device.xml b/app/src/main/res/drawable/ic_action_find_lost_device.xml index 8fdf6c723..d13a11d17 100644 --- a/app/src/main/res/drawable/ic_action_find_lost_device.xml +++ b/app/src/main/res/drawable/ic_action_find_lost_device.xml @@ -1,10 +1,10 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_device_set_reminders.xml b/app/src/main/res/drawable/ic_device_set_reminders.xml index 7009a6763..aa25afa2a 100644 --- a/app/src/main/res/drawable/ic_device_set_reminders.xml +++ b/app/src/main/res/drawable/ic_device_set_reminders.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_phone.xml b/app/src/main/res/drawable/ic_phone.xml new file mode 100644 index 000000000..08b0fc27e --- /dev/null +++ b/app/src/main/res/drawable/ic_phone.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_seat_normal.xml b/app/src/main/res/drawable/ic_seat_normal.xml new file mode 100644 index 000000000..ca5626916 --- /dev/null +++ b/app/src/main/res/drawable/ic_seat_normal.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_star_gray.xml b/app/src/main/res/drawable/ic_star_gray.xml new file mode 100644 index 000000000..24d9e7985 --- /dev/null +++ b/app/src/main/res/drawable/ic_star_gray.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7cff8e280..f00cdc87e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -471,6 +471,11 @@ Low power warning Anti-loss warning Whole day HR measurement + Event reminder + Find device + Idle Alerts + Vibration Patterns + Configure the vibration patterns for different notifications once a minute every 5 minutes every 10 minutes diff --git a/app/src/main/res/xml/devicesettings_miband5_vibration.xml b/app/src/main/res/xml/devicesettings_miband5_vibration.xml new file mode 100644 index 000000000..a269b775d --- /dev/null +++ b/app/src/main/res/xml/devicesettings_miband5_vibration.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f3e5ed2bf8842cf32299b6234b9261fd9c81f9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 14 May 2022 15:15:30 +0100 Subject: [PATCH 051/110] Mi Band 5: Fix vibration patterns preference keys --- .../res/xml/devicesettings_miband5_vibration.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/res/xml/devicesettings_miband5_vibration.xml b/app/src/main/res/xml/devicesettings_miband5_vibration.xml index a269b775d..4f0332585 100644 --- a/app/src/main/res/xml/devicesettings_miband5_vibration.xml +++ b/app/src/main/res/xml/devicesettings_miband5_vibration.xml @@ -10,7 +10,7 @@ @@ -40,7 +40,7 @@ @@ -70,7 +70,7 @@ @@ -100,7 +100,7 @@ @@ -130,7 +130,7 @@ @@ -160,7 +160,7 @@ @@ -190,7 +190,7 @@ @@ -220,7 +220,7 @@ From 50346ce79844e1fa4bd58916e4d9ba81d23e2947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 14 May 2022 15:17:07 +0100 Subject: [PATCH 052/110] Amazfit Band 5: Add notification vibration patterns --- .../devices/huami/amazfitband5/AmazfitBand5Coordinator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java index 4616431c9..8d577709b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java @@ -99,6 +99,7 @@ public class AmazfitBand5Coordinator extends HuamiCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_amazfitband5, + R.xml.devicesettings_miband5_vibration, R.xml.devicesettings_wearlocation, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, From 49a787161493274928bac0ce944124da21412293 Mon Sep 17 00:00:00 2001 From: vanous Date: Sun, 15 May 2022 13:03:16 +0200 Subject: [PATCH 053/110] Sony WF 800n: new icons --- app/src/main/assets/ic_device_sony_800n.svg | 215 ++++++++++++++ .../assets/ic_device_sony_800n_disabled.svg | 268 ++++++++++++++++++ app/src/main/assets/ic_sony_wf_800n_left.svg | 95 +++++++ app/src/main/assets/ic_sony_wf_800n_right.svg | 95 +++++++ app/src/main/assets/sony_800n.svg | 76 +++++ app/src/main/assets/sony_800n_case.svg | 72 +++++ .../coordinators/SonyWFSP800NCoordinator.java | 6 +- .../gadgetbridge/model/DeviceType.java | 2 +- .../res/drawable/ic_device_sony_wf_800n.xml | 14 + .../ic_device_sony_wf_800n_disabled.xml | 15 + .../res/drawable/ic_sony_wf_800n_case.xml | 17 ++ .../res/drawable/ic_sony_wf_800n_left.xml | 39 +++ .../res/drawable/ic_sony_wf_800n_right.xml | 39 +++ 13 files changed, 949 insertions(+), 4 deletions(-) create mode 100644 app/src/main/assets/ic_device_sony_800n.svg create mode 100644 app/src/main/assets/ic_device_sony_800n_disabled.svg create mode 100644 app/src/main/assets/ic_sony_wf_800n_left.svg create mode 100644 app/src/main/assets/ic_sony_wf_800n_right.svg create mode 100644 app/src/main/assets/sony_800n.svg create mode 100644 app/src/main/assets/sony_800n_case.svg create mode 100644 app/src/main/res/drawable/ic_device_sony_wf_800n.xml create mode 100644 app/src/main/res/drawable/ic_device_sony_wf_800n_disabled.xml create mode 100644 app/src/main/res/drawable/ic_sony_wf_800n_case.xml create mode 100644 app/src/main/res/drawable/ic_sony_wf_800n_left.xml create mode 100644 app/src/main/res/drawable/ic_sony_wf_800n_right.xml diff --git a/app/src/main/assets/ic_device_sony_800n.svg b/app/src/main/assets/ic_device_sony_800n.svg new file mode 100644 index 000000000..1c8095454 --- /dev/null +++ b/app/src/main/assets/ic_device_sony_800n.svg @@ -0,0 +1,215 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/ic_device_sony_800n_disabled.svg b/app/src/main/assets/ic_device_sony_800n_disabled.svg new file mode 100644 index 000000000..e43bffb5d --- /dev/null +++ b/app/src/main/assets/ic_device_sony_800n_disabled.svg @@ -0,0 +1,268 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/ic_sony_wf_800n_left.svg b/app/src/main/assets/ic_sony_wf_800n_left.svg new file mode 100644 index 000000000..d31ea351f --- /dev/null +++ b/app/src/main/assets/ic_sony_wf_800n_left.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/ic_sony_wf_800n_right.svg b/app/src/main/assets/ic_sony_wf_800n_right.svg new file mode 100644 index 000000000..c987dbe93 --- /dev/null +++ b/app/src/main/assets/ic_sony_wf_800n_right.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/sony_800n.svg b/app/src/main/assets/sony_800n.svg new file mode 100644 index 000000000..9811d475e --- /dev/null +++ b/app/src/main/assets/sony_800n.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/assets/sony_800n_case.svg b/app/src/main/assets/sony_800n_case.svg new file mode 100644 index 000000000..3fd7343f1 --- /dev/null +++ b/app/src/main/assets/sony_800n_case.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java index 806f39e31..d021ab7c4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java @@ -53,9 +53,9 @@ public class SonyWFSP800NCoordinator extends SonyHeadphonesCoordinator { @Override public BatteryConfig[] getBatteryConfig() { - final BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_tws_case, R.string.battery_case); - final BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_galaxy_buds_l, R.string.left_earbud); - final BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_galaxy_buds_r, R.string.right_earbud); + final BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_sony_wf_800n_case, R.string.battery_case); + final BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_sony_wf_800n_left, R.string.left_earbud); + final BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_sony_wf_800n_right, R.string.right_earbud); return new BatteryConfig[]{battery1, battery2, battery3}; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index 841a9161b..0008e557c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -106,7 +106,7 @@ public enum DeviceType { GALAXY_BUDS_LIVE(419, R.drawable.ic_device_galaxy_buds_live, R.drawable.ic_device_galaxy_buds_live_disabled, R.string.devicetype_galaxybuds_live), GALAXY_BUDS(420, R.drawable.ic_device_galaxy_buds, R.drawable.ic_device_galaxy_buds_disabled, R.string.devicetype_galaxybuds), SONY_WH_1000XM3(430, R.drawable.ic_device_headphones, R.drawable.ic_device_headphones_disabled, R.string.devicetype_sony_wh_1000xm3), - SONY_WF_SP800N(431, R.drawable.ic_device_galaxy_buds, R.drawable.ic_device_galaxy_buds_disabled, R.string.devicetype_sony_wf_sp800n), + SONY_WF_SP800N(431, R.drawable.ic_device_sony_wf_800n, R.drawable.ic_device_sony_wf_800n_disabled, R.string.devicetype_sony_wf_sp800n), SONY_WH_1000XM4(432, R.drawable.ic_device_headphones, R.drawable.ic_device_headphones_disabled, R.string.devicetype_sony_wh_1000xm4), BOSE_QC35(440, R.drawable.ic_device_headphones, R.drawable.ic_device_headphones_disabled, R.string.devicetype_bose_qc35), VESC_NRF(500, R.drawable.ic_device_vesc, R.drawable.ic_device_vesc_disabled, R.string.devicetype_vesc), diff --git a/app/src/main/res/drawable/ic_device_sony_wf_800n.xml b/app/src/main/res/drawable/ic_device_sony_wf_800n.xml new file mode 100644 index 000000000..3eb7be41e --- /dev/null +++ b/app/src/main/res/drawable/ic_device_sony_wf_800n.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_sony_wf_800n_disabled.xml b/app/src/main/res/drawable/ic_device_sony_wf_800n_disabled.xml new file mode 100644 index 000000000..05d51ea7f --- /dev/null +++ b/app/src/main/res/drawable/ic_device_sony_wf_800n_disabled.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_sony_wf_800n_case.xml b/app/src/main/res/drawable/ic_sony_wf_800n_case.xml new file mode 100644 index 000000000..d03918e1d --- /dev/null +++ b/app/src/main/res/drawable/ic_sony_wf_800n_case.xml @@ -0,0 +1,17 @@ + + + + diff --git a/app/src/main/res/drawable/ic_sony_wf_800n_left.xml b/app/src/main/res/drawable/ic_sony_wf_800n_left.xml new file mode 100644 index 000000000..c65400804 --- /dev/null +++ b/app/src/main/res/drawable/ic_sony_wf_800n_left.xml @@ -0,0 +1,39 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_sony_wf_800n_right.xml b/app/src/main/res/drawable/ic_sony_wf_800n_right.xml new file mode 100644 index 000000000..e2a1d4145 --- /dev/null +++ b/app/src/main/res/drawable/ic_sony_wf_800n_right.xml @@ -0,0 +1,39 @@ + + + + + + + + From 425dfac3e9edb4bb91b8edd1d63836d403148ef8 Mon Sep 17 00:00:00 2001 From: vanous Date: Sun, 15 May 2022 15:39:48 +0200 Subject: [PATCH 054/110] Miband6: new device icon --- app/src/main/assets/ic_device_miband6.svg | 150 +++++++++++++ .../assets/ic_device_miband6_disabled.svg | 198 ++++++++++++++++++ .../gadgetbridge/model/DeviceType.java | 2 +- .../main/res/drawable/ic_device_miband6.xml | 30 +++ .../drawable/ic_device_miband6_disabled.xml | 35 ++++ 5 files changed, 414 insertions(+), 1 deletion(-) create mode 100644 app/src/main/assets/ic_device_miband6.svg create mode 100644 app/src/main/assets/ic_device_miband6_disabled.svg create mode 100644 app/src/main/res/drawable/ic_device_miband6.xml create mode 100644 app/src/main/res/drawable/ic_device_miband6_disabled.xml diff --git a/app/src/main/assets/ic_device_miband6.svg b/app/src/main/assets/ic_device_miband6.svg new file mode 100644 index 000000000..c5622af53 --- /dev/null +++ b/app/src/main/assets/ic_device_miband6.svg @@ -0,0 +1,150 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/ic_device_miband6_disabled.svg b/app/src/main/assets/ic_device_miband6_disabled.svg new file mode 100644 index 000000000..3796c8d1e --- /dev/null +++ b/app/src/main/assets/ic_device_miband6_disabled.svg @@ -0,0 +1,198 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index 0008e557c..e36839e64 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -61,7 +61,7 @@ public enum DeviceType { AMAZFITGTR2E(34, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_amazfit_gtr2e), AMAZFITGTS2E(35, R.drawable.ic_device_amazfit_bip, R.drawable.ic_device_amazfit_bip_disabled,R.string .devicetype_amazfit_gts2e), AMAZFITX(36, R.drawable.ic_device_miband2, R.drawable.ic_device_miband2_disabled, R.string.devicetype_amazfit_x), - MIBAND6(37, R.drawable.ic_device_miband2, R.drawable.ic_device_miband2_disabled, R.string.devicetype_miband6), + MIBAND6(37, R.drawable.ic_device_miband6, R.drawable.ic_device_miband6_disabled, R.string.devicetype_miband6), AMAZFITTREXPRO(38, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_amazfit_trex_pro), AMAZFITPOP(39, R.drawable.ic_device_amazfit_bip, R.drawable.ic_device_amazfit_bip_disabled, R.string.devicetype_amazfit_pop), AMAZFITPOPPRO(10040, R.drawable.ic_device_amazfit_bip, R.drawable.ic_device_amazfit_bip_disabled, R.string.devicetype_amazfit_pop_pro), diff --git a/app/src/main/res/drawable/ic_device_miband6.xml b/app/src/main/res/drawable/ic_device_miband6.xml new file mode 100644 index 000000000..89551edb6 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_miband6.xml @@ -0,0 +1,30 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_miband6_disabled.xml b/app/src/main/res/drawable/ic_device_miband6_disabled.xml new file mode 100644 index 000000000..9a841e43f --- /dev/null +++ b/app/src/main/res/drawable/ic_device_miband6_disabled.xml @@ -0,0 +1,35 @@ + + + + + + + + From 634edc0061634b46dde1b05ea39095e2e220fdc8 Mon Sep 17 00:00:00 2001 From: vanous Date: Sun, 15 May 2022 15:41:43 +0200 Subject: [PATCH 055/110] optimize icons with avocado --- .../main/res/drawable/ic_device_miband6.xml | 45 +++++----- .../drawable/ic_device_miband6_disabled.xml | 55 ++++++------- .../res/drawable/ic_device_sony_wf_800n.xml | 76 ++++++++++++++--- .../ic_device_sony_wf_800n_disabled.xml | 82 +++++++++++++++---- 4 files changed, 178 insertions(+), 80 deletions(-) diff --git a/app/src/main/res/drawable/ic_device_miband6.xml b/app/src/main/res/drawable/ic_device_miband6.xml index 89551edb6..4d59e071e 100644 --- a/app/src/main/res/drawable/ic_device_miband6.xml +++ b/app/src/main/res/drawable/ic_device_miband6.xml @@ -3,28 +3,25 @@ android:height="28.740126dp" android:viewportWidth="28.740126" android:viewportHeight="28.740126"> - - - - - + + + + + diff --git a/app/src/main/res/drawable/ic_device_miband6_disabled.xml b/app/src/main/res/drawable/ic_device_miband6_disabled.xml index 9a841e43f..6a4db7980 100644 --- a/app/src/main/res/drawable/ic_device_miband6_disabled.xml +++ b/app/src/main/res/drawable/ic_device_miband6_disabled.xml @@ -3,33 +3,30 @@ android:height="28.740126dp" android:viewportWidth="28.740126" android:viewportHeight="28.740126"> - - - - - - + + + + + + diff --git a/app/src/main/res/drawable/ic_device_sony_wf_800n.xml b/app/src/main/res/drawable/ic_device_sony_wf_800n.xml index 3eb7be41e..bb4cad64a 100644 --- a/app/src/main/res/drawable/ic_device_sony_wf_800n.xml +++ b/app/src/main/res/drawable/ic_device_sony_wf_800n.xml @@ -1,14 +1,64 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_sony_wf_800n_disabled.xml b/app/src/main/res/drawable/ic_device_sony_wf_800n_disabled.xml index 05d51ea7f..e65f781a7 100644 --- a/app/src/main/res/drawable/ic_device_sony_wf_800n_disabled.xml +++ b/app/src/main/res/drawable/ic_device_sony_wf_800n_disabled.xml @@ -1,15 +1,69 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + From b018a4b5f4fceb3b6c6f83dea49a8147c6d8e48b Mon Sep 17 00:00:00 2001 From: vanous Date: Sun, 15 May 2022 16:33:12 +0200 Subject: [PATCH 056/110] optimeze dimensions for icons --- app/src/main/res/drawable/ic_device_miband6.xml | 8 ++++---- app/src/main/res/drawable/ic_device_miband6_disabled.xml | 8 ++++---- app/src/main/res/drawable/ic_device_sony_wf_800n.xml | 8 ++++---- .../main/res/drawable/ic_device_sony_wf_800n_disabled.xml | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/app/src/main/res/drawable/ic_device_miband6.xml b/app/src/main/res/drawable/ic_device_miband6.xml index 4d59e071e..0b5700c96 100644 --- a/app/src/main/res/drawable/ic_device_miband6.xml +++ b/app/src/main/res/drawable/ic_device_miband6.xml @@ -1,8 +1,8 @@ + android:width="45sp" + android:height="45sp" + android:viewportWidth="30" + android:viewportHeight="30"> + android:width="45sp" + android:height="45sp" + android:viewportWidth="30" + android:viewportHeight="30"> + android:width="45sp" + android:height="45sp" + android:viewportWidth="30" + android:viewportHeight="30"> + android:width="45sp" + android:height="45sp" + android:viewportWidth="30" + android:viewportHeight="30"> Date: Sun, 15 May 2022 16:33:48 +0200 Subject: [PATCH 057/110] Sony overhead headphones: new device icon --- .../main/assets/ic_device_sony_overhead.svg | 140 +++++++++++++ .../ic_device_sony_overhead_disabled.svg | 192 ++++++++++++++++++ .../gadgetbridge/model/DeviceType.java | 4 +- .../res/drawable/ic_device_sony_overhead.xml | 23 +++ .../ic_device_sony_overhead_disabled.xml | 28 +++ 5 files changed, 385 insertions(+), 2 deletions(-) create mode 100644 app/src/main/assets/ic_device_sony_overhead.svg create mode 100644 app/src/main/assets/ic_device_sony_overhead_disabled.svg create mode 100644 app/src/main/res/drawable/ic_device_sony_overhead.xml create mode 100644 app/src/main/res/drawable/ic_device_sony_overhead_disabled.xml diff --git a/app/src/main/assets/ic_device_sony_overhead.svg b/app/src/main/assets/ic_device_sony_overhead.svg new file mode 100644 index 000000000..b4a7c5a4c --- /dev/null +++ b/app/src/main/assets/ic_device_sony_overhead.svg @@ -0,0 +1,140 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/ic_device_sony_overhead_disabled.svg b/app/src/main/assets/ic_device_sony_overhead_disabled.svg new file mode 100644 index 000000000..3cd7f091b --- /dev/null +++ b/app/src/main/assets/ic_device_sony_overhead_disabled.svg @@ -0,0 +1,192 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index e36839e64..ef4e95cde 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -105,9 +105,9 @@ public enum DeviceType { NOTHING_EAR1(410, R.drawable.ic_device_nothingear, R.drawable.ic_device_nothingear_disabled, R.string.devicetype_nothingear1), GALAXY_BUDS_LIVE(419, R.drawable.ic_device_galaxy_buds_live, R.drawable.ic_device_galaxy_buds_live_disabled, R.string.devicetype_galaxybuds_live), GALAXY_BUDS(420, R.drawable.ic_device_galaxy_buds, R.drawable.ic_device_galaxy_buds_disabled, R.string.devicetype_galaxybuds), - SONY_WH_1000XM3(430, R.drawable.ic_device_headphones, R.drawable.ic_device_headphones_disabled, R.string.devicetype_sony_wh_1000xm3), + SONY_WH_1000XM3(430, R.drawable.ic_device_sony_overhead, R.drawable.ic_device_sony_overhead_disabled, R.string.devicetype_sony_wh_1000xm3), SONY_WF_SP800N(431, R.drawable.ic_device_sony_wf_800n, R.drawable.ic_device_sony_wf_800n_disabled, R.string.devicetype_sony_wf_sp800n), - SONY_WH_1000XM4(432, R.drawable.ic_device_headphones, R.drawable.ic_device_headphones_disabled, R.string.devicetype_sony_wh_1000xm4), + SONY_WH_1000XM4(432, R.drawable.ic_device_sony_overhead, R.drawable.ic_device_sony_overhead_disabled, R.string.devicetype_sony_wh_1000xm4), BOSE_QC35(440, R.drawable.ic_device_headphones, R.drawable.ic_device_headphones_disabled, R.string.devicetype_bose_qc35), VESC_NRF(500, R.drawable.ic_device_vesc, R.drawable.ic_device_vesc_disabled, R.string.devicetype_vesc), VESC_HM10(501, R.drawable.ic_device_vesc, R.drawable.ic_device_vesc_disabled, R.string.devicetype_vesc), diff --git a/app/src/main/res/drawable/ic_device_sony_overhead.xml b/app/src/main/res/drawable/ic_device_sony_overhead.xml new file mode 100644 index 000000000..4162a62a1 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_sony_overhead.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_device_sony_overhead_disabled.xml b/app/src/main/res/drawable/ic_device_sony_overhead_disabled.xml new file mode 100644 index 000000000..1f2293218 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_sony_overhead_disabled.xml @@ -0,0 +1,28 @@ + + + + + + + From a5a3e57a343557ac354dd1c403d8f51e6778135d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sun, 15 May 2022 17:22:55 +0100 Subject: [PATCH 058/110] Sony Headphones: Simplify capability definition --- .../SonyHeadphonesCapabilities.java | 38 ++++++ .../headphones/SonyHeadphonesCoordinator.java | 121 ++++++++++++++++++ .../coordinators/SonyWFSP800NCoordinator.java | 39 +++--- .../SonyWH1000XM3Coordinator.java | 37 +++--- .../SonyWH1000XM4Coordinator.java | 33 ++--- .../gadgetbridge/model/BatteryConfig.java | 16 ++- .../protocol/impl/v1/SonyProtocolImplV1.java | 98 ++++++-------- .../service/TestDeviceSupport.java | 11 ++ 8 files changed, 272 insertions(+), 121 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCapabilities.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCapabilities.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCapabilities.java new file mode 100644 index 000000000..8fbf9b72e --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCapabilities.java @@ -0,0 +1,38 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones; + +public enum SonyHeadphonesCapabilities { + BatterySingle, + BatteryDual, + BatteryCase, + PowerOffFromPhone, + AmbientSoundControl, + WindNoiseReduction, + AncOptimizer, + AudioSettingsOnlyOnSbcCodec, + AudioUpsampling, + ButtonModesLeftRight, + VoiceNotifications, + AutomaticPowerOffWhenTakenOff, + AutomaticPowerOffByTime, + TouchSensorSingle, + Equalizer, + SoundPosition, + SurroundMode, + PauseWhenTakenOff +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java index 10e6a2ea1..a6b93585b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java @@ -23,7 +23,18 @@ import android.net.Uri; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.apache.commons.lang3.ArrayUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + import nodomain.freeyourgadget.gadgetbridge.GBException; +import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; @@ -32,6 +43,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; public abstract class SonyHeadphonesCoordinator extends AbstractDeviceCoordinator { @Override @@ -123,4 +135,113 @@ public abstract class SonyHeadphonesCoordinator extends AbstractDeviceCoordinato public boolean supportsFindDevice() { return false; } + + @Override + public boolean supportsPowerOff() { + return supports(SonyHeadphonesCapabilities.PowerOffFromPhone); + } + + @Override + public int getBatteryCount() { + if (supports(SonyHeadphonesCapabilities.BatterySingle)) { + if (supports(SonyHeadphonesCapabilities.BatteryDual)) { + throw new IllegalStateException("A device can't have both single and dual battery"); + } else if(supports(SonyHeadphonesCapabilities.BatteryCase)) { + throw new IllegalStateException("Devices with single battery + case are not supported by the protocol"); + } + } + + int batteryCount = 0; + + if (supports(SonyHeadphonesCapabilities.BatterySingle)) { + batteryCount += 1; + } + + if (supports(SonyHeadphonesCapabilities.BatteryCase)) { + batteryCount += 1; + } + + if (supports(SonyHeadphonesCapabilities.BatteryDual)) { + batteryCount += 2; + } + + return batteryCount; + } + + @Override + public int[] getSupportedDeviceSpecificSettings(final GBDevice device) { + final List settings = new ArrayList<>(); + + if (supports(SonyHeadphonesCapabilities.AmbientSoundControl)) { + if (supports(SonyHeadphonesCapabilities.WindNoiseReduction)) { + settings.add(R.xml.devicesettings_sony_headphones_ambient_sound_control_wind_noise_reduction); + } else { + settings.add(R.xml.devicesettings_sony_headphones_ambient_sound_control); + } + + if (supports(SonyHeadphonesCapabilities.AncOptimizer)) { + settings.add(R.xml.devicesettings_sony_headphones_anc_optimizer); + } + } + + addSettingsUnderHeader(settings, R.xml.devicesettings_header_other, new LinkedHashMap() {{ + put(SonyHeadphonesCapabilities.AudioSettingsOnlyOnSbcCodec, R.xml.devicesettings_sony_warning_wh1000xm3); + put(SonyHeadphonesCapabilities.Equalizer, R.xml.devicesettings_sony_headphones_equalizer); + put(SonyHeadphonesCapabilities.SoundPosition, R.xml.devicesettings_sony_headphones_sound_position); + put(SonyHeadphonesCapabilities.SurroundMode, R.xml.devicesettings_sony_headphones_surround_mode); + put(SonyHeadphonesCapabilities.AudioUpsampling, R.xml.devicesettings_sony_headphones_audio_upsampling); + }}); + + addSettingsUnderHeader(settings, R.xml.devicesettings_header_system, new LinkedHashMap() {{ + put(SonyHeadphonesCapabilities.ButtonModesLeftRight, R.xml.devicesettings_sony_headphones_button_modes_left_right); + put(SonyHeadphonesCapabilities.TouchSensorSingle, R.xml.devicesettings_sony_headphones_touch_sensor_single); + put(SonyHeadphonesCapabilities.PauseWhenTakenOff, R.xml.devicesettings_sony_headphones_pause_when_taken_off); + put(SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff, R.xml.devicesettings_automatic_power_off_when_taken_off); + put(SonyHeadphonesCapabilities.AutomaticPowerOffByTime, R.xml.devicesettings_automatic_power_off_by_time); + put(SonyHeadphonesCapabilities.VoiceNotifications, R.xml.devicesettings_sony_headphones_notifications_voice_guide); + }}); + + settings.add(R.xml.devicesettings_sony_headphones_device_info); + + return ArrayUtils.toPrimitive(settings.toArray(new Integer[0])); + } + + public List getCapabilities() { + return Collections.emptyList(); + } + + public boolean supports(final SonyHeadphonesCapabilities capability) { + return getCapabilities().contains(capability); + } + + /** + * Add the preference screens for capabilities under a header. The header is also only added if at least one capability is supported by the device. + * + * @param settings the list of settings to update + * @param header the header to add, if any capability supported + * @param capabilities the map of capability to preference screen + */ + private void addSettingsUnderHeader(final List settings, + final int header, + final Map capabilities) { + final Set supportedCapabilities = new HashSet<>(capabilities.keySet()); + for (SonyHeadphonesCapabilities capability : capabilities.keySet()) { + if (!supports(capability)) { + supportedCapabilities.remove(capability); + } + } + + if (supportedCapabilities.isEmpty()) { + // None of the capabilities in the map are supported + return; + } + + settings.add(header); + + for (Map.Entry capabilitiesSetting : capabilities.entrySet()) { + if (supports(capabilitiesSetting.getKey())) { + settings.add(capabilitiesSetting.getValue()); + } + } + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java index d021ab7c4..6dd9d0124 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java @@ -18,9 +18,12 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinator import androidx.annotation.NonNull; +import java.util.Arrays; +import java.util.List; + import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; @@ -41,16 +44,6 @@ public class SonyWFSP800NCoordinator extends SonyHeadphonesCoordinator { return DeviceType.SONY_WF_SP800N; } - @Override - public int getBatteryCount() { - return 3; - } - - @Override - public boolean supportsPowerOff() { - return true; - } - @Override public BatteryConfig[] getBatteryConfig() { final BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_sony_wf_800n_case, R.string.battery_case); @@ -61,17 +54,17 @@ public class SonyWFSP800NCoordinator extends SonyHeadphonesCoordinator { } @Override - public int[] getSupportedDeviceSpecificSettings(final GBDevice device) { - return new int[]{ - R.xml.devicesettings_sony_headphones_ambient_sound_control, - R.xml.devicesettings_header_other, - R.xml.devicesettings_sony_headphones_equalizer, - R.xml.devicesettings_header_system, - R.xml.devicesettings_sony_headphones_button_modes_left_right, - R.xml.devicesettings_sony_headphones_pause_when_taken_off, - R.xml.devicesettings_automatic_power_off_when_taken_off, - R.xml.devicesettings_sony_headphones_notifications_voice_guide, - R.xml.devicesettings_sony_headphones_device_info - }; + public List getCapabilities() { + return Arrays.asList( + SonyHeadphonesCapabilities.BatteryDual, + SonyHeadphonesCapabilities.BatteryCase, + SonyHeadphonesCapabilities.PowerOffFromPhone, + SonyHeadphonesCapabilities.AmbientSoundControl, + SonyHeadphonesCapabilities.Equalizer, + SonyHeadphonesCapabilities.ButtonModesLeftRight, + SonyHeadphonesCapabilities.PauseWhenTakenOff, + SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff, + SonyHeadphonesCapabilities.VoiceNotifications + ); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java index 16a9ea508..0318b40db 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM3Coordinator.java @@ -18,9 +18,11 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinator import androidx.annotation.NonNull; -import nodomain.freeyourgadget.gadgetbridge.R; +import java.util.Arrays; +import java.util.List; + +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; @@ -41,21 +43,20 @@ public class SonyWH1000XM3Coordinator extends SonyHeadphonesCoordinator { } @Override - public int[] getSupportedDeviceSpecificSettings(final GBDevice device) { - return new int[]{ - R.xml.devicesettings_sony_headphones_ambient_sound_control_wind_noise_reduction, - R.xml.devicesettings_sony_headphones_anc_optimizer, - R.xml.devicesettings_header_other, - R.xml.devicesettings_sony_warning_wh1000xm3, - R.xml.devicesettings_sony_headphones_equalizer, - R.xml.devicesettings_sony_headphones_sound_position, - R.xml.devicesettings_sony_headphones_surround_mode, - R.xml.devicesettings_sony_headphones_audio_upsampling, - R.xml.devicesettings_header_system, - R.xml.devicesettings_sony_headphones_touch_sensor_single, - R.xml.devicesettings_automatic_power_off_by_time, - R.xml.devicesettings_sony_headphones_notifications_voice_guide, - R.xml.devicesettings_sony_headphones_device_info - }; + public List getCapabilities() { + return Arrays.asList( + SonyHeadphonesCapabilities.BatterySingle, + SonyHeadphonesCapabilities.AmbientSoundControl, + SonyHeadphonesCapabilities.WindNoiseReduction, + SonyHeadphonesCapabilities.AncOptimizer, + SonyHeadphonesCapabilities.AudioSettingsOnlyOnSbcCodec, + SonyHeadphonesCapabilities.Equalizer, + SonyHeadphonesCapabilities.SoundPosition, + SonyHeadphonesCapabilities.SurroundMode, + SonyHeadphonesCapabilities.AudioUpsampling, + SonyHeadphonesCapabilities.TouchSensorSingle, + SonyHeadphonesCapabilities.AutomaticPowerOffByTime, + SonyHeadphonesCapabilities.VoiceNotifications + ); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM4Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM4Coordinator.java index fac10a307..47e846c6b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM4Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWH1000XM4Coordinator.java @@ -18,9 +18,11 @@ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinator import androidx.annotation.NonNull; -import nodomain.freeyourgadget.gadgetbridge.R; +import java.util.Arrays; +import java.util.List; + +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; @@ -41,22 +43,21 @@ public class SonyWH1000XM4Coordinator extends SonyHeadphonesCoordinator { } @Override - public int[] getSupportedDeviceSpecificSettings(final GBDevice device) { - return new int[]{ + public List getCapabilities() { + return Arrays.asList( // TODO: Function of [CUSTOM] button - R.xml.devicesettings_sony_headphones_ambient_sound_control_wind_noise_reduction, - R.xml.devicesettings_sony_headphones_anc_optimizer, - R.xml.devicesettings_header_other, - R.xml.devicesettings_sony_headphones_equalizer, - R.xml.devicesettings_sony_headphones_audio_upsampling, - R.xml.devicesettings_header_system, // TODO R.xml.devicesettings_connect_two_devices, // TODO R.xml.devicesettings_sony_headphones_speak_to_chat_with_settings, - R.xml.devicesettings_sony_headphones_touch_sensor_single, - R.xml.devicesettings_sony_headphones_pause_when_taken_off, - R.xml.devicesettings_automatic_power_off_when_taken_off, - R.xml.devicesettings_sony_headphones_notifications_voice_guide, - R.xml.devicesettings_sony_headphones_device_info - }; + SonyHeadphonesCapabilities.BatterySingle, + SonyHeadphonesCapabilities.AmbientSoundControl, + SonyHeadphonesCapabilities.WindNoiseReduction, + SonyHeadphonesCapabilities.AncOptimizer, + SonyHeadphonesCapabilities.Equalizer, + SonyHeadphonesCapabilities.AudioUpsampling, + SonyHeadphonesCapabilities.TouchSensorSingle, + SonyHeadphonesCapabilities.PauseWhenTakenOff, + SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff, + SonyHeadphonesCapabilities.VoiceNotifications + ); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryConfig.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryConfig.java index 126fffeaa..cc627b598 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryConfig.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryConfig.java @@ -17,6 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.model; +import java.util.Objects; + public class BatteryConfig { private final int batteryIndex; @@ -41,6 +43,16 @@ public class BatteryConfig { return batteryLabel; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof BatteryConfig)) return false; + BatteryConfig that = (BatteryConfig) o; + return getBatteryIndex() == that.getBatteryIndex() && getBatteryIcon() == that.getBatteryIcon() && getBatteryLabel() == that.getBatteryLabel(); + } + + @Override + public int hashCode() { + return Objects.hash(getBatteryIndex(), getBatteryIcon(), getBatteryLabel()); + } } - - diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java index 9f46600df..5c8eca4b5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/sony/headphones/protocol/impl/v1/SonyProtocolImplV1.java @@ -26,8 +26,10 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; @@ -36,6 +38,8 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInf import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdateDeviceInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControl; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AudioUpsampling; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AutomaticPowerOff; @@ -49,7 +53,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.TouchS import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.VoiceNotifications; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.deviceevents.SonyHeadphonesEnqueueRequestEvent; import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.Request; import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.MessageType; @@ -58,6 +61,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.prot import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.BatteryType; import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.NoiseCancellingOptimizerStatus; import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.VirtualSoundParam; +import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.GB; public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl { @@ -494,55 +498,36 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl { return Collections.emptyList(); } - final DeviceType deviceType = getDevice().getType(); - - final List capabilityRequests = new ArrayList<>(); + final SonyHeadphonesCoordinator coordinator = (SonyHeadphonesCoordinator) DeviceHelper.getInstance().getCoordinator(getDevice()); // Populate the init requests - // TODO: We should be determine which of these we need from the device... - switch (deviceType) { - case SONY_WH_1000XM3: - capabilityRequests.add(getFirmwareVersion()); - capabilityRequests.add(getBattery(BatteryType.SINGLE)); - capabilityRequests.add(getAudioCodec()); - capabilityRequests.add(getAmbientSoundControl()); - capabilityRequests.add(getNoiseCancellingOptimizerState()); - capabilityRequests.add(getAudioUpsampling()); - capabilityRequests.add(getVoiceNotifications()); - capabilityRequests.add(getAutomaticPowerOff()); - capabilityRequests.add(getTouchSensor()); - capabilityRequests.add(getSurroundMode()); - capabilityRequests.add(getSoundPosition()); - capabilityRequests.add(getEqualizer()); - break; - case SONY_WH_1000XM4: - capabilityRequests.add(getFirmwareVersion()); - capabilityRequests.add(getBattery(BatteryType.SINGLE)); - capabilityRequests.add(getAudioCodec()); - capabilityRequests.add(getAmbientSoundControl()); - capabilityRequests.add(getNoiseCancellingOptimizerState()); - capabilityRequests.add(getAudioUpsampling()); - capabilityRequests.add(getVoiceNotifications()); - capabilityRequests.add(getAutomaticPowerOff()); - capabilityRequests.add(getTouchSensor()); - capabilityRequests.add(getEqualizer()); - capabilityRequests.add(getPauseWhenTakenOff()); - break; - case SONY_WF_SP800N: - capabilityRequests.add(getFirmwareVersion()); - capabilityRequests.add(getBattery(BatteryType.DUAL)); - capabilityRequests.add(getBattery(BatteryType.CASE)); - capabilityRequests.add(getAudioCodec()); - capabilityRequests.add(getAmbientSoundControl()); - capabilityRequests.add(getVoiceNotifications()); - capabilityRequests.add(getAutomaticPowerOff()); - capabilityRequests.add(getEqualizer()); - capabilityRequests.add(getButtonModes()); - capabilityRequests.add(getPauseWhenTakenOff()); - break; - default: - LOG.error("Unsupported Sony device type '{}' with key '{}'", deviceType, deviceType.getKey()); - return null; + final List capabilityRequests = new ArrayList<>(); + + capabilityRequests.add(getFirmwareVersion()); + capabilityRequests.add(getAudioCodec()); + + final Map capabilityRequestMap = new LinkedHashMap() {{ + put(SonyHeadphonesCapabilities.BatterySingle, getBattery(BatteryType.SINGLE)); + put(SonyHeadphonesCapabilities.BatteryDual, getBattery(BatteryType.DUAL)); + put(SonyHeadphonesCapabilities.BatteryCase, getBattery(BatteryType.CASE)); + put(SonyHeadphonesCapabilities.AmbientSoundControl, getAmbientSoundControl()); + put(SonyHeadphonesCapabilities.AncOptimizer, getNoiseCancellingOptimizerState()); + put(SonyHeadphonesCapabilities.AudioUpsampling, getAudioUpsampling()); + put(SonyHeadphonesCapabilities.ButtonModesLeftRight, getButtonModes()); + put(SonyHeadphonesCapabilities.VoiceNotifications, getVoiceNotifications()); + put(SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff, getAutomaticPowerOff()); + put(SonyHeadphonesCapabilities.AutomaticPowerOffByTime, getAutomaticPowerOff()); + put(SonyHeadphonesCapabilities.TouchSensorSingle, getTouchSensor()); + put(SonyHeadphonesCapabilities.Equalizer, getEqualizer()); + put(SonyHeadphonesCapabilities.SoundPosition, getSoundPosition()); + put(SonyHeadphonesCapabilities.SurroundMode, getSurroundMode()); + put(SonyHeadphonesCapabilities.PauseWhenTakenOff, getPauseWhenTakenOff()); + }}; + + for (Map.Entry capabilityEntry : capabilityRequestMap.entrySet()) { + if (coordinator.supports(capabilityEntry.getKey())) { + capabilityRequests.add(capabilityEntry.getValue()); + } } return Collections.singletonList(new SonyHeadphonesEnqueueRequestEvent(capabilityRequests)); @@ -644,7 +629,7 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl { final float pressure = payload[5] / 10.0f; - if (pressure <= 0 || pressure > 1.0f) { + if (pressure <= 0 || pressure > 1.0f) { LOG.warn("Invalid Noise Cancelling Optimizer pressure: {} atm, ignoring", pressure); return Collections.emptyList(); } @@ -1076,19 +1061,8 @@ public class SonyProtocolImplV1 extends AbstractSonyProtocolImpl { } private boolean supportsWindNoiseCancelling() { - // TODO: We should be able to determine this dynamically... + final SonyHeadphonesCoordinator coordinator = (SonyHeadphonesCoordinator) DeviceHelper.getInstance().getCoordinator(getDevice()); - final DeviceType deviceType = getDevice().getType(); - - switch (deviceType) { - case SONY_WH_1000XM3: - case SONY_WH_1000XM4: - return true; - case SONY_WF_SP800N: - return false; - default: - LOG.error("Unknown Sony device type '{}' with key '{}'", deviceType, deviceType.getKey()); - return false; - } + return coordinator.supports(SonyHeadphonesCapabilities.WindNoiseReduction); } } diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java index aa71841db..ab336b28a 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java @@ -17,6 +17,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.Reminder; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WorldClock; class TestDeviceSupport extends AbstractDeviceSupport { @@ -70,6 +71,11 @@ class TestDeviceSupport extends AbstractDeviceSupport { } + @Override + public void onSetWorldClocks(ArrayList clocks) { + + } + @Override public void onSetCallState(CallSpec callSpec) { @@ -90,6 +96,11 @@ class TestDeviceSupport extends AbstractDeviceSupport { } + @Override + public void onSetPhoneVolume(float volume) { + + } + @Override public void onInstallApp(Uri uri) { From bfdc24ab879be341039cb7f78b690ecea242ff48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 14 May 2022 14:41:46 +0100 Subject: [PATCH 059/110] Add auto export and auto fetch preference dependencies --- app/src/main/res/xml/preferences.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index c0b21f207..1b2ab2787 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -337,10 +337,12 @@ android:key="auto_export_enabled" android:title="@string/pref_title_auto_export_enabled" /> Date: Sat, 14 May 2022 21:08:32 +0100 Subject: [PATCH 060/110] Huami: Move inactivity warnings and goal notification to device-specific settings --- .../gadgetbridge/GBApplication.java | 38 +++++- .../DeviceSettingsPreferenceConst.java | 1 + .../DeviceSpecificSettingsFragment.java | 4 + .../devices/huami/HuamiCoordinator.java | 34 ++--- .../amazfitband5/AmazfitBand5Coordinator.java | 2 + .../amazfitbip/AmazfitBipCoordinator.java | 2 + .../amazfitbip/AmazfitBipLiteCoordinator.java | 2 + .../amazfitbips/AmazfitBipSCoordinator.java | 2 + .../amazfitbipu/AmazfitBipUCoordinator.java | 2 + .../AmazfitBipUProCoordinator.java | 2 + .../amazfitcor/AmazfitCorCoordinator.java | 2 + .../amazfitcor2/AmazfitCor2Coordinator.java | 2 + .../amazfitgtr/AmazfitGTRCoordinator.java | 2 + .../amazfitgtr/AmazfitGTRLiteCoordinator.java | 2 + .../amazfitgtr2/AmazfitGTR2Coordinator.java | 2 + .../amazfitgtr2/AmazfitGTR2eCoordinator.java | 2 + .../amazfitgts/AmazfitGTSCoordinator.java | 2 + .../amazfitgts2/AmazfitGTS2Coordinator.java | 2 + .../AmazfitGTS2MiniCoordinator.java | 2 + .../amazfitgts2/AmazfitGTS2eCoordinator.java | 2 + .../amazfitneo/AmazfitNeoCoordinator.java | 2 + .../amazfittrex/AmazfitTRexCoordinator.java | 2 + .../AmazfitTRexProCoordinator.java | 2 + .../AmazfitVergeLCoordinator.java | 2 + .../huami/amazfitx/AmazfitXCoordinator.java | 2 + .../huami/miband2/MiBand2Coordinator.java | 2 + .../huami/miband2/MiBand2HRXCoordinator.java | 2 + .../huami/miband3/MiBand3Coordinator.java | 2 + .../huami/miband4/MiBand4Coordinator.java | 2 + .../huami/miband5/MiBand5Coordinator.java | 2 + .../huami/miband6/MiBand6Coordinator.java | 2 + .../devices/huami/zeppe/ZeppECoordinator.java | 2 + .../devices/miband/MiBandConst.java | 1 - .../miband/MiBandPreferencesActivity.java | 121 ------------------ .../service/devices/huami/HuamiSupport.java | 19 +-- app/src/main/res/drawable/ic_seat_normal.xml | 5 - .../xml/devicesettings_goal_notification.xml | 9 ++ .../res/xml/devicesettings_inactivity.xml | 9 +- .../res/xml/devicesettings_inactivity_dnd.xml | 56 ++++++++ .../devicesettings_inactivity_extended.xml | 5 +- .../xml/devicesettings_miband5_vibration.xml | 2 +- app/src/main/res/xml/miband_preferences.xml | 63 --------- 42 files changed, 200 insertions(+), 223 deletions(-) delete mode 100644 app/src/main/res/drawable/ic_seat_normal.xml create mode 100644 app/src/main/res/xml/devicesettings_goal_notification.xml create mode 100644 app/src/main/res/xml/devicesettings_inactivity_dnd.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 6523fabe9..10ac359e1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -117,7 +117,7 @@ public class GBApplication extends Application { private static SharedPreferences sharedPrefs; private static final String PREFS_VERSION = "shared_preferences_version"; //if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version - private static final int CURRENT_PREFS_VERSION = 12; + private static final int CURRENT_PREFS_VERSION = 13; private static LimitedQueue mIDSenderLookup = new LimitedQueue(16); private static Prefs prefs; @@ -1085,6 +1085,42 @@ public class GBApplication extends Application { editor.putString("inactivity_warnings_threshold", String.valueOf(prefs.getInt("inactivity_warnings_threshold", 60))); editor.putString("fitness_goal", String.valueOf(prefs.getInt("fitness_goal", 8000))); } + + if (oldVersion < 13) { + try (DBHandler db = acquireDB()) { + final DaoSession daoSession = db.getDaoSession(); + final List activeDevices = DBHelper.getActiveDevices(daoSession); + + for (Device dbDevice : activeDevices) { + final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier()); + final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit(); + + if (dbDevice.getManufacturer().equals("Huami")) { + deviceSharedPrefsEdit.putBoolean("inactivity_warnings_enable", prefs.getBoolean("inactivity_warnings_enable", false)); + deviceSharedPrefsEdit.putString("inactivity_warnings_threshold", prefs.getString("inactivity_warnings_threshold", "60")); + deviceSharedPrefsEdit.putString("inactivity_warnings_start", prefs.getString("inactivity_warnings_start", "06:00")); + deviceSharedPrefsEdit.putString("inactivity_warnings_end", prefs.getString("inactivity_warnings_end", "22:00")); + + deviceSharedPrefsEdit.putBoolean("inactivity_warnings_dnd", prefs.getBoolean("inactivity_warnings_dnd", false)); + deviceSharedPrefsEdit.putString("inactivity_warnings_dnd_start", prefs.getString("inactivity_warnings_dnd_start", "12:00")); + deviceSharedPrefsEdit.putString("inactivity_warnings_dnd_end", prefs.getString("inactivity_warnings_dnd_end", "14:00")); + + deviceSharedPrefsEdit.putBoolean("fitness_goal_notification", prefs.getBoolean("mi2_goal_notification", false)); + } + + // Not removing the first 4 preferences since they're still used by some devices (ZeTime) + editor.remove("inactivity_warnings_dnd"); + editor.remove("inactivity_warnings_dnd_start"); + editor.remove("inactivity_warnings_dnd_end"); + editor.remove("mi2_goal_notification"); + + deviceSharedPrefsEdit.apply(); + } + } catch (Exception e) { + Log.w(TAG, "error acquiring DB lock"); + } + } + editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION)); editor.apply(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index ad1aa2c91..03f2cbf7d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -190,4 +190,5 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_SOUNDS = "sounds"; public static final String PREF_AUTH_KEY = "authkey"; public static final String PREF_USER_FITNESS_GOAL = "fitness_goal"; + public static final String PREF_USER_FITNESS_GOAL_NOTIFICATION = "fitness_goal_notification"; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index cc7d588b1..a8ca0648f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -471,6 +471,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp addPreferenceHandlerFor(PREF_QC35_NOISE_CANCELLING_LEVEL); addPreferenceHandlerFor(PREF_USER_FITNESS_GOAL); + addPreferenceHandlerFor(PREF_USER_FITNESS_GOAL_NOTIFICATION); addPreferenceHandlerFor(PREF_UM25_SHOW_THRESHOLD_NOTIFICATION); addPreferenceHandlerFor(PREF_UM25_SHOW_THRESHOLD); @@ -643,6 +644,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp setInputTypeFor(DeviceSettingsPreferenceConst.PREF_FIND_PHONE_DURATION, InputType.TYPE_CLASS_NUMBER); setInputTypeFor(DeviceSettingsPreferenceConst.PREF_RESERVER_ALARMS_CALENDAR, InputType.TYPE_CLASS_NUMBER); setInputTypeFor(DeviceSettingsPreferenceConst.PREF_RESERVER_REMINDERS_CALENDAR, InputType.TYPE_CLASS_NUMBER); + setInputTypeFor(DeviceSettingsPreferenceConst.PREF_INACTIVITY_THRESHOLD, InputType.TYPE_CLASS_NUMBER); String deviceActionsFellSleepSelection = prefs.getString(PREF_DEVICE_ACTION_FELL_SLEEP_SELECTION, PREF_DEVICE_ACTION_SELECTION_OFF); final Preference deviceActionsFellSleep = findPreference(PREF_DEVICE_ACTION_FELL_SLEEP_SELECTION); @@ -827,6 +829,8 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp protected Set getPreferenceKeysWithSummary() { final Set keysWithSummary = new HashSet<>(); + keysWithSummary.add(PREF_INACTIVITY_THRESHOLD); + if (deviceSpecificSettingsCustomizer != null) { keysWithSummary.addAll(deviceSpecificSettingsCustomizer.getPreferenceKeysWithSummary()); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java index c19c6b18d..e7fa967e5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java @@ -209,9 +209,9 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { return prefs.getBoolean(HuamiConst.PREF_USE_CUSTOM_FONT, false); } - public static boolean getGoalNotification() { - Prefs prefs = GBApplication.getPrefs(); - return prefs.getBoolean(MiBandConst.PREF_MI2_GOAL_NOTIFICATION, false); + public static boolean getGoalNotification(String deviceAddress) { + SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(deviceAddress); + return prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_USER_FITNESS_GOAL_NOTIFICATION, false); } public static boolean getRotateWristToSwitchInfo(String deviceAddress) { @@ -219,35 +219,35 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { return prefs.getBoolean(MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO, false); } - public static boolean getInactivityWarnings() { - Prefs prefs = GBApplication.getPrefs(); + public static boolean getInactivityWarnings(String deviceAddress) { + SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(deviceAddress); return prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_INACTIVITY_ENABLE, false); } - public static int getInactivityWarningsThreshold() { - Prefs prefs = GBApplication.getPrefs(); + public static int getInactivityWarningsThreshold(String deviceAddress) { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); return prefs.getInt(DeviceSettingsPreferenceConst.PREF_INACTIVITY_THRESHOLD, 60); } - public static boolean getInactivityWarningsDnd() { - Prefs prefs = GBApplication.getPrefs(); + public static boolean getInactivityWarningsDnd(String deviceAddress) { + SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(deviceAddress); return prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_INACTIVITY_DND, false); } - public static Date getInactivityWarningsStart() { - return getTimePreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_START, "06:00"); + public static Date getInactivityWarningsStart(String deviceAddress) { + return getTimePreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_START, "06:00", deviceAddress); } - public static Date getInactivityWarningsEnd() { - return getTimePreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_END, "22:00"); + public static Date getInactivityWarningsEnd(String deviceAddress) { + return getTimePreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_END, "22:00", deviceAddress); } - public static Date getInactivityWarningsDndStart() { - return getTimePreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_DND_START, "12:00"); + public static Date getInactivityWarningsDndStart(String deviceAddress) { + return getTimePreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_DND_START, "12:00", deviceAddress); } - public static Date getInactivityWarningsDndEnd() { - return getTimePreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_DND_END, "14:00"); + public static Date getInactivityWarningsDndEnd(String deviceAddress) { + return getTimePreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_DND_END, "14:00", deviceAddress); } public static Date getDoNotDisturbStart(String deviceAddress) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java index 8d577709b..062c241fe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java @@ -101,12 +101,14 @@ public class AmazfitBand5Coordinator extends HuamiCoordinator { R.xml.devicesettings_amazfitband5, R.xml.devicesettings_miband5_vibration, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_world_clocks, R.xml.devicesettings_nightmode, R.xml.devicesettings_liftwrist_display_sensitivity, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_swipeunlock, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java index a1a4963b1..6e97c9f9b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java @@ -83,8 +83,10 @@ public class AmazfitBipCoordinator extends HuamiCoordinator { R.xml.devicesettings_amazfitbip, R.xml.devicesettings_timeformat, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java index d1680ea64..160d9ca27 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java @@ -72,8 +72,10 @@ public class AmazfitBipLiteCoordinator extends AmazfitBipCoordinator { R.xml.devicesettings_amazfitbip, R.xml.devicesettings_timeformat, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_bt_connected_advertisement, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java index b40541bbe..25e8919f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java @@ -99,8 +99,10 @@ public class AmazfitBipSCoordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_world_clocks, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, R.xml.devicesettings_expose_hr_thirdparty, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java index d866addcc..523c0bcf8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java @@ -111,8 +111,10 @@ public class AmazfitBipUCoordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_world_clocks, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display_sensitivity, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, R.xml.devicesettings_expose_hr_thirdparty, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java index ea0af7783..c87c8d89c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java @@ -110,8 +110,10 @@ public class AmazfitBipUProCoordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_world_clocks, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display_sensitivity, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, R.xml.devicesettings_expose_hr_thirdparty, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java index 3c4f2b13f..109fbe6bb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java @@ -90,9 +90,11 @@ public class AmazfitCorCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitcor, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java index 7adb1313b..d5a662517 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java @@ -92,9 +92,11 @@ public class AmazfitCor2Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitcor, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java index ee6d765e6..6656b5c4b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java @@ -90,8 +90,10 @@ public class AmazfitGTRCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRLiteCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRLiteCoordinator.java index a16be8fa9..8a826f832 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRLiteCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRLiteCoordinator.java @@ -91,8 +91,10 @@ public class AmazfitGTRLiteCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2Coordinator.java index 10de70a5d..d3f1804b5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2Coordinator.java @@ -96,8 +96,10 @@ public class AmazfitGTR2Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2eCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2eCoordinator.java index 9a8949877..f82dc929a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2eCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2eCoordinator.java @@ -96,8 +96,10 @@ public class AmazfitGTR2eCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java index 62ced61b0..8762b65e4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java @@ -90,8 +90,10 @@ public class AmazfitGTSCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2Coordinator.java index 9d3eb2722..6a69adfa0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2Coordinator.java @@ -96,8 +96,10 @@ public class AmazfitGTS2Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2MiniCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2MiniCoordinator.java index c94e2aef0..5ffd26c9a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2MiniCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2MiniCoordinator.java @@ -65,8 +65,10 @@ public class AmazfitGTS2MiniCoordinator extends AmazfitGTS2Coordinator { return new int[]{ R.xml.devicesettings_amazfitgts2mini, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2eCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2eCoordinator.java index 50cd462af..5788b9111 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2eCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2eCoordinator.java @@ -96,8 +96,10 @@ public class AmazfitGTS2eCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitneo/AmazfitNeoCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitneo/AmazfitNeoCoordinator.java index b94003e80..b2291dbeb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitneo/AmazfitNeoCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitneo/AmazfitNeoCoordinator.java @@ -84,8 +84,10 @@ public class AmazfitNeoCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitneo, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_bt_connected_advertisement, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrex/AmazfitTRexCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrex/AmazfitTRexCoordinator.java index 8ea939196..9baeb3065 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrex/AmazfitTRexCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrex/AmazfitTRexCoordinator.java @@ -90,8 +90,10 @@ public class AmazfitTRexCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfittrex, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrexpro/AmazfitTRexProCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrexpro/AmazfitTRexProCoordinator.java index 909d6fffd..2ac407a3a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrexpro/AmazfitTRexProCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrexpro/AmazfitTRexProCoordinator.java @@ -90,8 +90,10 @@ public class AmazfitTRexProCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfittrexpro, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitvergel/AmazfitVergeLCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitvergel/AmazfitVergeLCoordinator.java index 4817c359e..673d95af4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitvergel/AmazfitVergeLCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitvergel/AmazfitVergeLCoordinator.java @@ -91,7 +91,9 @@ public class AmazfitVergeLCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitvergel, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_timeformat, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java index 0f1437363..40e3abeac 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java @@ -93,11 +93,13 @@ public class AmazfitXCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitx, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_nightmode, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_swipeunlock, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java index fb111bd5e..4b5af567b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java @@ -84,9 +84,11 @@ public class MiBand2Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_miband2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_donotdisturb_withauto, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_rotatewrist_cycleinfo, R.xml.devicesettings_buttonactions, R.xml.devicesettings_reserve_alarms_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java index c0b70c32a..daa22a027 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java @@ -87,8 +87,10 @@ public class MiBand2HRXCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_miband2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_donotdisturb_withauto, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_rotatewrist_cycleinfo, R.xml.devicesettings_pairingkey, R.xml.devicesettings_transliteration diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java index 274277708..ab27548ac 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java @@ -103,11 +103,13 @@ public class MiBand3Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_miband3, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_nightmode, R.xml.devicesettings_donotdisturb_withauto, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_donotdisturb_lift_wrist, R.xml.devicesettings_swipeunlock, R.xml.devicesettings_sync_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java index baa08af55..c467674b1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java @@ -90,11 +90,13 @@ public class MiBand4Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_miband3, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_nightmode, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_swipeunlock, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java index d8bd5ac5f..54ee13778 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java @@ -101,12 +101,14 @@ public class MiBand5Coordinator extends HuamiCoordinator { R.xml.devicesettings_miband5, R.xml.devicesettings_miband5_vibration, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_world_clocks, R.xml.devicesettings_nightmode, R.xml.devicesettings_liftwrist_display_sensitivity, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_swipeunlock, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java index 527fb5361..386c2a3cf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java @@ -85,12 +85,14 @@ public class MiBand6Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_miband6, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, R.xml.devicesettings_world_clocks, R.xml.devicesettings_nightmode, R.xml.devicesettings_liftwrist_display_sensitivity, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_swipeunlock, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_reserve_reminders_calendar, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/zeppe/ZeppECoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/zeppe/ZeppECoordinator.java index 455a24936..862e3c012 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/zeppe/ZeppECoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/zeppe/ZeppECoordinator.java @@ -90,8 +90,10 @@ public class ZeppECoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, + R.xml.devicesettings_inactivity_dnd, R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_sync_calendar, R.xml.devicesettings_expose_hr_thirdparty, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java index 83cadd3a2..0a7345606 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java @@ -27,7 +27,6 @@ public final class MiBandConst { public static final String PREF_MIBAND_USE_HR_FOR_SLEEP_DETECTION = "mi_hr_sleep_detection"; public static final String PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS = "device_time_offset_hours"; public static final String PREF_MI2_DATEFORMAT = "mi2_dateformat"; - public static final String PREF_MI2_GOAL_NOTIFICATION = "mi2_goal_notification"; public static final String PREF_MI2_DISPLAY_ITEM_CLOCK = "clock"; public static final String PREF_MI2_DISPLAY_ITEM_STEPS = "steps"; public static final String PREF_MI2_DISPLAY_ITEM_DISTANCE = "distance"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java index 882cb0316..6353be03d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java @@ -37,16 +37,9 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_INACTIVITY_ENABLE; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_INACTIVITY_START; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_INACTIVITY_END; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_INACTIVITY_THRESHOLD; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_INACTIVITY_DND; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_INACTIVITY_DND_START; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_INACTIVITY_DND_END; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_ALARM_CLOCK; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_INCOMING_CALL; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_GOAL_NOTIFICATION; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_ADDRESS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_USE_HR_FOR_SLEEP_DETECTION; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.VIBRATION_COUNT; @@ -82,120 +75,6 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity { } }); - final Preference goalNotification = findPreference(PREF_MI2_GOAL_NOTIFICATION); - goalNotification.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - invokeLater(new Runnable() { - @Override - public void run() { - GBApplication.deviceService().onSendConfiguration(PREF_MI2_GOAL_NOTIFICATION); - } - }); - return true; - } - }); - - - final Preference inactivityWarnings = findPreference(PREF_INACTIVITY_ENABLE); - inactivityWarnings.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - invokeLater(new Runnable() { - @Override - public void run() { - GBApplication.deviceService().onSendConfiguration(PREF_INACTIVITY_ENABLE); - } - }); - return true; - } - }); - - final Preference inactivityWarningsThreshold = findPreference(PREF_INACTIVITY_THRESHOLD); - inactivityWarningsThreshold.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - invokeLater(new Runnable() { - @Override - public void run() { - GBApplication.deviceService().onSendConfiguration(PREF_INACTIVITY_THRESHOLD); - } - }); - return true; - } - }); - - final Preference inactivityWarningsStart = findPreference(PREF_INACTIVITY_START); - inactivityWarningsStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - invokeLater(new Runnable() { - @Override - public void run() { - GBApplication.deviceService().onSendConfiguration(PREF_INACTIVITY_START); - } - }); - return true; - } - }); - - final Preference inactivityWarningsEnd = findPreference(PREF_INACTIVITY_END); - inactivityWarningsEnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - invokeLater(new Runnable() { - @Override - public void run() { - GBApplication.deviceService().onSendConfiguration(PREF_INACTIVITY_END); - } - }); - return true; - } - }); - - final Preference inactivityWarningsDnd = findPreference(PREF_INACTIVITY_DND); - inactivityWarningsDnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - invokeLater(new Runnable() { - @Override - public void run() { - GBApplication.deviceService().onSendConfiguration(PREF_INACTIVITY_DND); - } - }); - return true; - } - }); - - final Preference inactivityWarningsDndStart = findPreference(PREF_INACTIVITY_DND_START); - inactivityWarningsDndStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - invokeLater(new Runnable() { - @Override - public void run() { - GBApplication.deviceService().onSendConfiguration(PREF_INACTIVITY_DND_START); - } - }); - return true; - } - }); - - final Preference inactivityWarningsDndEnd = findPreference(PREF_INACTIVITY_DND_END); - inactivityWarningsDndEnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - invokeLater(new Runnable() { - @Override - public void run() { - GBApplication.deviceService().onSendConfiguration(PREF_INACTIVITY_DND_END); - } - }); - return true; - } - }); - - final Preference fitnessGoal = findPreference(ActivityUser.PREF_USER_STEPS_GOAL); fitnessGoal.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index a2b4b40b9..86839d28b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -184,6 +184,7 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SOUNDS; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SYNC_CALENDAR; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TIMEFORMAT; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_USER_FITNESS_GOAL_NOTIFICATION; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_WEARLOCATION; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_BUTTON_ACTION_SELECTION_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_BUTTON_ACTION_SELECTION_FITNESS_APP_START; @@ -2410,7 +2411,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case MiBandConst.PREF_MI2_DATEFORMAT: setDateDisplay(builder); break; - case MiBandConst.PREF_MI2_GOAL_NOTIFICATION: + case PREF_USER_FITNESS_GOAL_NOTIFICATION: setGoalNotification(builder); break; case PREF_ACTIVATE_DISPLAY_ON_LIFT: @@ -2904,7 +2905,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } private HuamiSupport setGoalNotification(TransactionBuilder builder) { - boolean enable = HuamiCoordinator.getGoalNotification(); + boolean enable = HuamiCoordinator.getGoalNotification(gbDevice.getAddress()); LOG.info("Setting goal notification to " + enable); if (enable) { writeToConfiguration(builder,HuamiService.COMMAND_ENABLE_GOAL_NOTIFICATION); @@ -3236,23 +3237,23 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } private HuamiSupport setInactivityWarnings(TransactionBuilder builder) { - boolean enable = HuamiCoordinator.getInactivityWarnings(); + boolean enable = HuamiCoordinator.getInactivityWarnings(gbDevice.getAddress()); LOG.info("Setting inactivity warnings to " + enable); if (enable) { byte[] data = HuamiService.COMMAND_ENABLE_INACTIVITY_WARNINGS.clone(); - int threshold = HuamiCoordinator.getInactivityWarningsThreshold(); + int threshold = HuamiCoordinator.getInactivityWarningsThreshold(gbDevice.getAddress()); data[HuamiService.INACTIVITY_WARNINGS_THRESHOLD] = (byte) threshold; Calendar calendar = GregorianCalendar.getInstance(); - boolean enableDnd = HuamiCoordinator.getInactivityWarningsDnd(); + boolean enableDnd = HuamiCoordinator.getInactivityWarningsDnd(gbDevice.getAddress()); - Date intervalStart = HuamiCoordinator.getInactivityWarningsStart(); - Date intervalEnd = HuamiCoordinator.getInactivityWarningsEnd(); - Date dndStart = HuamiCoordinator.getInactivityWarningsDndStart(); - Date dndEnd = HuamiCoordinator.getInactivityWarningsDndEnd(); + Date intervalStart = HuamiCoordinator.getInactivityWarningsStart(gbDevice.getAddress()); + Date intervalEnd = HuamiCoordinator.getInactivityWarningsEnd(gbDevice.getAddress()); + Date dndStart = HuamiCoordinator.getInactivityWarningsDndStart(gbDevice.getAddress()); + Date dndEnd = HuamiCoordinator.getInactivityWarningsDndEnd(gbDevice.getAddress()); // The first interval always starts when the warnings interval starts calendar.setTime(intervalStart); diff --git a/app/src/main/res/drawable/ic_seat_normal.xml b/app/src/main/res/drawable/ic_seat_normal.xml deleted file mode 100644 index ca5626916..000000000 --- a/app/src/main/res/drawable/ic_seat_normal.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/xml/devicesettings_goal_notification.xml b/app/src/main/res/xml/devicesettings_goal_notification.xml new file mode 100644 index 000000000..143a14040 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_goal_notification.xml @@ -0,0 +1,9 @@ + + + + diff --git a/app/src/main/res/xml/devicesettings_inactivity.xml b/app/src/main/res/xml/devicesettings_inactivity.xml index b25408ee2..a5cddd42c 100644 --- a/app/src/main/res/xml/devicesettings_inactivity.xml +++ b/app/src/main/res/xml/devicesettings_inactivity.xml @@ -7,25 +7,26 @@ android:summary="@string/mi2_prefs_inactivity_warnings_summary" android:title="@string/mi2_prefs_inactivity_warnings"> - - - + android:title="@string/mi2_prefs_inactivity_warnings" + android:summary="@string/mi2_prefs_inactivity_warnings_summary" /> diff --git a/app/src/main/res/xml/devicesettings_inactivity_dnd.xml b/app/src/main/res/xml/devicesettings_inactivity_dnd.xml new file mode 100644 index 000000000..3cb86d648 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_inactivity_dnd.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/devicesettings_inactivity_extended.xml b/app/src/main/res/xml/devicesettings_inactivity_extended.xml index 966b758ec..7063b8572 100644 --- a/app/src/main/res/xml/devicesettings_inactivity_extended.xml +++ b/app/src/main/res/xml/devicesettings_inactivity_extended.xml @@ -13,7 +13,8 @@ + android:title="@string/mi2_prefs_inactivity_warnings" + android:summary="@string/mi2_prefs_inactivity_warnings_summary" /> diff --git a/app/src/main/res/xml/devicesettings_miband5_vibration.xml b/app/src/main/res/xml/devicesettings_miband5_vibration.xml index 4f0332585..e225a5130 100644 --- a/app/src/main/res/xml/devicesettings_miband5_vibration.xml +++ b/app/src/main/res/xml/devicesettings_miband5_vibration.xml @@ -161,7 +161,7 @@ diff --git a/app/src/main/res/xml/miband_preferences.xml b/app/src/main/res/xml/miband_preferences.xml index ca1ba6553..0d4ea4a79 100644 --- a/app/src/main/res/xml/miband_preferences.xml +++ b/app/src/main/res/xml/miband_preferences.xml @@ -16,12 +16,6 @@ android:maxLength="5" android:title="@string/miband_prefs_fitness_goal" /> - - - - - - - - - - - - - - - - - - - - - - Date: Sun, 15 May 2022 17:52:01 +0100 Subject: [PATCH 061/110] Huami: Distinguish between alarm and workout activity type responses --- .../devices/huami/HuamiService.java | 12 +++-- .../service/devices/huami/HuamiSupport.java | 45 ++++++++++++------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java index 9cc8245f8..d2a07bb41 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java @@ -165,10 +165,16 @@ public class HuamiService { public static final byte[] COMMAND_ENABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x01, 0, 0, 0, 0}; public static final byte[] COMMAND_DISABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x00, 0, 0, 0, 0}; - public static final byte[] COMMAND_REQUEST_ALARMS = new byte[]{0x0d}; - public static final byte[] COMMAND_REQUEST_ALARMS_WITH_TIMES = new byte[]{(byte) 0xff,0x01,0x00,0x00,0x00}; + public static final byte COMMAND_ALARMS = 0x0d; + public static final byte COMMAND_ALARMS_WITH_TIMES = 0x01; + public static final byte COMMAND_WORKOUT_ACTIVITY_TYPES = 0x11; + public static final byte COMMAND_GPS_VERSION = 0x0e; - public static final byte[] COMMAND_REQUEST_GPS_VERSION = new byte[]{0x0e}; + public static final byte[] COMMAND_REQUEST_ALARMS = new byte[]{COMMAND_ALARMS}; + public static final byte[] COMMAND_REQUEST_ALARMS_WITH_TIMES = new byte[]{(byte) 0xff, COMMAND_ALARMS_WITH_TIMES, 0x00, 0x00, 0x00}; + public static final byte[] COMMAND_REQUEST_WORKOUT_ACTIVITY_TYPES = new byte[]{(byte) 0xff, COMMAND_WORKOUT_ACTIVITY_TYPES, 0x00, 0x00, 0x00}; + + public static final byte[] COMMAND_REQUEST_GPS_VERSION = new byte[]{COMMAND_GPS_VERSION}; // The third byte controls the threshold, in minutes // The last 8 bytes represent 2 separate time intervals for the inactivity warnings diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 86839d28b..590a727aa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -225,6 +225,10 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_INCOMING_CALL; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_INCOMING_SMS; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_HUAMI_VIBRATION_TRY_PREFIX; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.COMMAND_ALARMS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.COMMAND_ALARMS_WITH_TIMES; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.COMMAND_GPS_VERSION; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.COMMAND_WORKOUT_ACTIVITY_TYPES; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.DISPLAY_ITEM_BIT_CLOCK; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY_ITEMS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_COUNT; @@ -2043,18 +2047,19 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } } - byte[] alarmConfigurationReassemblyBuffer; + byte[] reassemblyBuffer; + byte reassemblyType = 0x00; private void handleConfigurationInfo(byte[] value) { if (value == null || value.length < 4) { return; } if (value[0] == 0x10 && value[2] == 0x01) { - if (value[1] == 0x0e) { + if (value[1] == COMMAND_GPS_VERSION) { String gpsVersion = new String(value, 3, value.length - 3); LOG.info("got gps version = " + gpsVersion); gbDevice.setFirmwareVersion2(gpsVersion); - } else if (value[1] == 0x0d) { + } else if (value[1] == COMMAND_ALARMS) { LOG.info("got alarms from watch"); decodeAndUpdateAlarmStatus(value, false); } else { @@ -2062,26 +2067,38 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } } else if (value[0] == ((byte) 0x80) && value[1] == 0x01) { boolean done = false; - if (value[2] == 0x00 || value[2] == (byte) 0xc0 && (value[4] == 0x01 && value[5] == 0x00 && value[6] == 0x00 && value[7] == 0x00 && value[8] == 0x01)) { // first chunk or complete data - alarmConfigurationReassemblyBuffer = new byte[value.length - 8]; - System.arraycopy(value, 8, alarmConfigurationReassemblyBuffer, 0, alarmConfigurationReassemblyBuffer.length); + if (value[2] == 0x00 || value[2] == (byte) 0xc0) { // first chunk or complete data + reassemblyBuffer = new byte[value.length - 8]; + reassemblyType = value[4]; + System.arraycopy(value, 8, reassemblyBuffer, 0, reassemblyBuffer.length); if (value[2] == (byte) 0xc0) { done = true; } - } else if (alarmConfigurationReassemblyBuffer != null && (value[2] == 0x40 || value[2] == (byte) 0x80)) { + } else if (reassemblyBuffer != null && (value[2] == 0x40 || value[2] == (byte) 0x80)) { byte[] payload = new byte[value.length - 4]; System.arraycopy(value, 4, payload, 0, payload.length); - alarmConfigurationReassemblyBuffer = ArrayUtils.addAll(alarmConfigurationReassemblyBuffer, payload); + reassemblyBuffer = ArrayUtils.addAll(reassemblyBuffer, payload); if (value[2] == (byte) 0x80) { done = true; } } if (!done) { - LOG.info("got chunk of alarm configuration data"); + LOG.info("got chunk of configuration data for {}", String.format("0x%x", reassemblyType)); } else { LOG.info("got full/reassembled configuration data"); - decodeAndUpdateAlarmStatus(alarmConfigurationReassemblyBuffer, true); - alarmConfigurationReassemblyBuffer = null; + switch (reassemblyType) { + case COMMAND_ALARMS_WITH_TIMES: + decodeAndUpdateAlarmStatus(reassemblyBuffer, true); + break; + case COMMAND_WORKOUT_ACTIVITY_TYPES: + LOG.warn("got workout activity types, not handled"); + break; + default: + LOG.warn("got unknown chunked configuration response for {}, not handled", String.format("0x%x", reassemblyType)); + break; + } + + reassemblyBuffer = null; } } else { LOG.warn("unknown response got from configuration request " + GB.hexdump(value, 0, -1)); @@ -2535,10 +2552,8 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { public void onTestNewFunction() { //requestMTU(23); try { - final TransactionBuilder builder = performInitialized("test pattern"); - final VibrationProfile profile = VibrationProfile.getProfile(VibrationProfile.ID_SHORT, (short) 2); - - setVibrationPattern(builder, HuamiVibrationPatternNotificationType.APP_ALERTS, true, profile); + final TransactionBuilder builder = performInitialized("test request"); + writeToConfiguration(builder, HuamiService.COMMAND_REQUEST_WORKOUT_ACTIVITY_TYPES); builder.queue(getQueue()); } catch (final Exception e) { LOG.error("onTestNewFunction failed", e); From 410b74e1a25977ba17f682c67a0d366816a1c1fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sun, 15 May 2022 17:23:59 +0100 Subject: [PATCH 062/110] Mi Band 5: Increase number of reminder slots to 50 --- .../devices/huami/miband5/MiBand5Coordinator.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java index 54ee13778..0cfddda57 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java @@ -85,6 +85,11 @@ public class MiBand5Coordinator extends HuamiCoordinator { return true; } + @Override + public int getReminderSlotCount() { + return 50; // as enforced by Zepp Life + } + @Override public int getWorldClocksSlotCount() { return 20; // as enforced by Mi Fit From 4761168958f04f99084768eb178be6c85a5865bb Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 16 May 2022 10:59:03 +0200 Subject: [PATCH 063/110] Mi Band 6: enable vibration patttern settings (tested working) also rename devicesettings_miband5_vibration to devicesettings_vibrationpatterns --- .../devices/huami/amazfitband5/AmazfitBand5Coordinator.java | 2 +- .../gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java | 2 +- .../gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java | 1 + ...band5_vibration.xml => devicesettings_vibrationpatterns.xml} | 0 4 files changed, 3 insertions(+), 2 deletions(-) rename app/src/main/res/xml/{devicesettings_miband5_vibration.xml => devicesettings_vibrationpatterns.xml} (100%) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java index 062c241fe..fb75b393a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java @@ -99,7 +99,7 @@ public class AmazfitBand5Coordinator extends HuamiCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_amazfitband5, - R.xml.devicesettings_miband5_vibration, + R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_wearlocation, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java index 0cfddda57..020ae69c3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java @@ -104,7 +104,7 @@ public class MiBand5Coordinator extends HuamiCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_miband5, - R.xml.devicesettings_miband5_vibration, + R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_wearlocation, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java index 386c2a3cf..00012fa07 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java @@ -84,6 +84,7 @@ public class MiBand6Coordinator extends HuamiCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_miband6, + R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_wearlocation, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, diff --git a/app/src/main/res/xml/devicesettings_miband5_vibration.xml b/app/src/main/res/xml/devicesettings_vibrationpatterns.xml similarity index 100% rename from app/src/main/res/xml/devicesettings_miband5_vibration.xml rename to app/src/main/res/xml/devicesettings_vibrationpatterns.xml From c50c333f8b0298b9a55f71f4b914b19c50c2efb2 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 16 May 2022 11:03:10 +0200 Subject: [PATCH 064/110] Mi Band 4: enable vibration patterns --- .../gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java index c467674b1..d34634ff2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java @@ -89,6 +89,7 @@ public class MiBand4Coordinator extends HuamiCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_miband3, + R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_wearlocation, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, From b46b1278b3e7d8dc000dba7469c883db608cac46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quang=20Ng=C3=B4?= Date: Sat, 14 May 2022 00:26:24 +0700 Subject: [PATCH 065/110] Add support for Sony WF-1000XM3 --- README.md | 2 +- .../SonyWF1000XM3Coordinator.java | 74 +++++++++++++++++++ .../gadgetbridge/model/DeviceType.java | 1 + .../service/DeviceSupportFactory.java | 3 + .../gadgetbridge/util/DeviceHelper.java | 2 + app/src/main/res/values/strings.xml | 1 + 6 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java diff --git a/README.md b/README.md index 76fe04b61..11782aac9 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ vendor's servers. - PineTime (InfiniTime Firmware) - Roidmi, Roidmi 3, Mojietu 3 (Bluetooth FM Transmitters) - [SMA](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/SMA) Q2 (SMA-Q2-OSS Firmware) -- [Sony WH-1000XM3, WH-1000XM4, WF-SP800N](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Sony-Headphones) +- [Sony WH-1000XM3, WH-1000XM4, WF-SP800N, WF-1000XM3](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Sony-Headphones) - Teclast H10, H30 - TLW64 - Vibratissimo (Experimental) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java new file mode 100644 index 000000000..8341dadf8 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java @@ -0,0 +1,74 @@ +/* Copyright (C) 2022 Ngô Minh Quang + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators; + +import androidx.annotation.NonNull; + +import java.util.Arrays; +import java.util.List; + +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; + +public class SonyWF1000XM3Coordinator extends SonyHeadphonesCoordinator { + + @NonNull + @Override + public DeviceType getSupportedType(GBDeviceCandidate candidate) { + if (candidate.getName().contains("WF-1000XM3")) { + return DeviceType.SONY_WF_1000XM3; + } + + return DeviceType.UNKNOWN; + } + + @Override + public DeviceType getDeviceType() { + return DeviceType.SONY_WF_1000XM3; + } + + @Override + public BatteryConfig[] getBatteryConfig() { + final BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_tws_case, R.string.battery_case); + final BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_galaxy_buds_l, R.string.left_earbud); + final BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_galaxy_buds_r, R.string.right_earbud); + + return new BatteryConfig[]{battery1, battery2, battery3}; + } + + @Override + public List getCapabilities() { + return Arrays.asList( + SonyHeadphonesCapabilities.BatteryDual, + SonyHeadphonesCapabilities.BatteryCase, + SonyHeadphonesCapabilities.PowerOffFromPhone, + SonyHeadphonesCapabilities.AmbientSoundControl, + SonyHeadphonesCapabilities.WindNoiseReduction, + SonyHeadphonesCapabilities.Equalizer, + SonyHeadphonesCapabilities.AudioUpsampling, + SonyHeadphonesCapabilities.ButtonModesLeftRight, + SonyHeadphonesCapabilities.PauseWhenTakenOff, + SonyHeadphonesCapabilities.AutomaticPowerOffWhenTakenOff, + SonyHeadphonesCapabilities.VoiceNotifications + ); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index ef4e95cde..c2d7a780a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -108,6 +108,7 @@ public enum DeviceType { SONY_WH_1000XM3(430, R.drawable.ic_device_sony_overhead, R.drawable.ic_device_sony_overhead_disabled, R.string.devicetype_sony_wh_1000xm3), SONY_WF_SP800N(431, R.drawable.ic_device_sony_wf_800n, R.drawable.ic_device_sony_wf_800n_disabled, R.string.devicetype_sony_wf_sp800n), SONY_WH_1000XM4(432, R.drawable.ic_device_sony_overhead, R.drawable.ic_device_sony_overhead_disabled, R.string.devicetype_sony_wh_1000xm4), + SONY_WF_1000XM3(433, R.drawable.ic_device_galaxy_buds, R.drawable.ic_device_galaxy_buds_disabled, R.string.devicetype_sony_wf_1000xm3), BOSE_QC35(440, R.drawable.ic_device_headphones, R.drawable.ic_device_headphones_disabled, R.string.devicetype_bose_qc35), VESC_NRF(500, R.drawable.ic_device_vesc, R.drawable.ic_device_vesc_disabled, R.string.devicetype_vesc), VESC_HM10(501, R.drawable.ic_device_vesc, R.drawable.ic_device_vesc_disabled, R.string.devicetype_vesc), diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java index 936a4ee9d..420d558de 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java @@ -389,6 +389,9 @@ public class DeviceSupportFactory { case SONY_WF_SP800N: deviceSupport = new ServiceDeviceSupport(new SonyHeadphonesSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; + case SONY_WF_1000XM3: + deviceSupport = new ServiceDeviceSupport(new SonyHeadphonesSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); + break; case VESC_NRF: case VESC_HM10: deviceSupport = new ServiceDeviceSupport(new VescDeviceSupport(gbDevice.getType()), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java index bf7753e61..eb0429c84 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java @@ -120,6 +120,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.waspos.WaspOSCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.watch9.Watch9DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWFSP800NCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWH1000XM3Coordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWF1000XM3Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.xwatch.XWatchCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.zetime.ZeTimeCoordinator; import nodomain.freeyourgadget.gadgetbridge.entities.Device; @@ -326,6 +327,7 @@ public class DeviceHelper { result.add(new SonyWH1000XM3Coordinator()); result.add(new SonyWH1000XM4Coordinator()); result.add(new SonyWFSP800NCoordinator()); + result.add(new SonyWF1000XM3Coordinator()); result.add(new QC35Coordinator()); return result; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f00cdc87e..29ca3d806 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -996,6 +996,7 @@ Sony WH-1000XM3 Sony WH-1000XM4 Sony WF-SP800N + Sony WF-1000XM3 Choose export location General High-priority From 32230151fc839135139ad1171f48d50d44fb8a39 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 16 May 2022 14:57:55 +0200 Subject: [PATCH 066/110] draft changelog --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ec0f27c9..dc326eb45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ ### Changelog +### NEXT +* Initial Support for Sony WF-1000XM3 +* Huami: Add Toggle function for Open Tracks tracking to button actionss +* Huami: Move inactivity warnings and goal notification to device-specific settings +* Mi Band 6: set time on connect +* Mi Band 5/6, Amazfit Bip S/U/Pro: Add world clock configuration +* Mi Band 5/6: support sensitivity setting for lift wrist configuration +* Mi Band 5: Add support for configuring workout menu on device +* Mi Band 4/5/6: Add support for vibration patterns +* Mi Band 5: Increase number of reminder slots to 50 +* Amazfit Neo: Allow to disable beeps for email notifications +* Bangle.js: Fix incoming calls in release builds +* Fossil Hybrid HR: Support flexible custom menu on watch +* VESC: added battery indicator +* UM25: Add reset option to current accumulation +* UM25: Add notification on below current threshold +* Fix crash when calender is accessed but permission is denied +* Add com.asus.asusincallui to blacklist +* New icons for Sony WF 800n and Mi Band 6 + ### 0.66.0 * Add basic support for Casio GBD-H1000 * Add support for Hama Fit Track 1900 - via FitPro device support From b3ffb157331b257d9b33b7454df4249e52e11b64 Mon Sep 17 00:00:00 2001 From: Shimon Date: Mon, 2 May 2022 08:31:53 +0000 Subject: [PATCH 067/110] Translated using Weblate (Czech) Currently translated at 99.2% (1479 of 1490 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/cs/ --- app/src/main/res/values-cs/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index ef0c4a36a..803d8c9a0 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -1596,4 +1596,17 @@ AutoExport není aktivní. AutoExport zatím nebyl naplánován. E-mail + Bangle.js běží + Bangle.js Gadgetbridge + Doprovodná aplikace pro Bangle.js pro Android vytvořená na základě projektu Gadgetbridge s přidaným přístupem k internetu. + Gadgetbridge Nightly + Bangle.js Gadgetbridge + O Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + O Bangle.js Gadgetbridge + Doprovodná aplikace pro Bangle.js pro Android vytvořená na základě projektu Gadgetbridge s přidaným přístupem k internetu. + Gadgetbridge (Nightly) + Bangle.js Gadgetbridge + Bangle.js běží + O Gadgetbridge Nightly \ No newline at end of file From 69efbe5ddd7e686c5b5d03636307a2db7bb4aec0 Mon Sep 17 00:00:00 2001 From: vanous Date: Mon, 2 May 2022 17:58:01 +0000 Subject: [PATCH 068/110] Translated using Weblate (Czech) Currently translated at 100.0% (1490 of 1490 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/cs/ --- app/src/main/res/values-cs/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 803d8c9a0..e1c248853 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -1609,4 +1609,12 @@ Bangle.js Gadgetbridge Bangle.js běží O Gadgetbridge Nightly + Noční GB běží + Gadgetbridge (Noční vydání, Bez poskytovatele služeb Pebble) + O Aplikaci Gadgetbridge Noční, bez Pebble + Rozsvítit display při notifikaci + Svobodná a lokální náhrada za uzavřenou aplikaci vašich hodinek/náramku. Noční vydání Gadgetbridge. Tato verze nelze nainstalovat, máte-li již nainstalovánu jinou verzi Gadgetbridge nebo Pebble aplikace, z důvodu konfliktu v poskytovali služeb Pebble. + Gadgetbridge Noční, Bez Pebble + Svobodná a lokální náhrada za uzavřenou aplikaci vašich hodinek/náramku. Noční vydání Gadgetbridge. Tato verze má přejmenovanou službu poskytovatele Pebble pro eliminaci konfliktů poskytovatelů. Některé Pebble integrace nebudou fungovat, ale tuto verzi je možno nainstalovat paralelně k již nainstalované jiné verzi Gadgetbridge. + Noční NoPebble GB běží \ No newline at end of file From a9fdf8db67d0c3aeacd94c1436c5a5b2b8123f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vinc=C3=A8n=20PUJOL?= Date: Mon, 2 May 2022 06:47:41 +0000 Subject: [PATCH 069/110] Translated using Weblate (French) Currently translated at 98.8% (1473 of 1490 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/fr/ --- app/src/main/res/values-fr/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 05adb2646..80b59f423 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1598,4 +1598,7 @@ Temps de sommeil préféré en heures pré-configuration de la position à %s S\'allumer pour une nouvelle notification Email + Bangle.js Gadgetbridge + A propos de Bangle.js Gadgetbridge + Bangle.js Gadgetbridge \ No newline at end of file From e23499029823f4731a131f4ca8aee42b66a6d62a Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 2 May 2022 06:26:31 +0000 Subject: [PATCH 070/110] Translated using Weblate (Hebrew) Currently translated at 99.5% (1483 of 1490 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index aef1dbfbb..8b45d9f91 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -1594,4 +1594,17 @@ המיקום מוגדר מראש לכדי %s הארה עם התראות חדשות דוא״ל + Bangle.js Gadgetbridge + גרסה נסיונית של Gadgetbridge + על הגרסה הנסיונית של Gadgetbridge + Bangle.js פעיל + Bangle.js Gadgetbridge + על Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + על Bangle.js Gadgetbridge + יישומון Android מלווה ל־Bangle.js שנבנה על גבי מיזם Gadgetbridge עם תוספת של גישה לאינטרנט. + יישומון Android מלווה ל־Bangle.js שנבנה על גבי מיזם Gadgetbridge עם תוספת של גישה לאינטרנט. + Gadgetbridge (גרסה ניסיונית) + Bangle.js Gadgetbridge + Bangle.js פעיל \ No newline at end of file From 6efd2eaa7bf9d18be23a06a70b658930b35a0f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Mon, 2 May 2022 10:52:28 +0000 Subject: [PATCH 071/110] Translated using Weblate (Turkish) Currently translated at 100.0% (1490 of 1490 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/tr/ --- app/src/main/res/values-tr/strings.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 3ed1c3fc2..5c66463e6 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -1611,4 +1611,24 @@ konumu %s olarak ön ayarlama Yeni bildirimde ışığı aç E-posta + Bangle.js çalışıyor + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge Hakkında + Gadgetbridge Gecelik Hakkında + Satıcıların kapalı kaynaklı Android aygıt uygulamalarının yerine bulut gerektirmeyen copyleft özgür alternatif. Gadgetbridge gecelik sürümleri. Pebble sağlayıcısındaki bir çakışma nedeniyle Gadgetbridge veya Pebble uygulaması zaten kuruluysa bu kurulamaz. + Gecelik GB çalışıyor + Gadgetbridge Gecelik Pebble Yok + Gadgetbridge Gecelik Pebble Yok Hakkında + Gecelik PebbleYok GB çalışıyor + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge Hakkında + İnternet erişimi eklenen Gadgetbridge projesinin üzerine inşa edilmiş Bangle.js için Android yardımcı uygulaması. + Gadgetbridge Gecelik + Gadgetbridge (Gecelik, Pebble sağlayıcısı yok) + Bangle.js Gadgetbridge + Satıcıların kapalı kaynaklı Android aygıt uygulamalarının yerine bulut gerektirmeyen copyleft özgür alternatif. Gadgetbridge gecelik sürümleri. Bu sürümde, çakışmaları önlemek için Pebble sağlayıcısının adı değiştirilmiştir, bu nedenle Pebble ile ilgili bazı bütünleşmeler çalışmayacaktır, ancak mevcut bir Gadgetbridge kurulumunun yanına kurulabilir. + İnternet erişimi eklenen Gadgetbridge projesinin üzerine inşa edilmiş Bangle.js için Android yardımcı uygulaması. + Bangle.js çalışıyor + Gadgetbridge (Gecelik) \ No newline at end of file From 4fe8d4265244be9c07bacd8e8cec0378c0f0c1df Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Mon, 2 May 2022 10:49:56 +0000 Subject: [PATCH 072/110] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1490 of 1490 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/uk/ --- app/src/main/res/values-uk/strings.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 4422a3df7..2cbee6809 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1602,4 +1602,24 @@ попереднє встановлення розташування на %s Засвітлювати за нового сповіщення Е-пошта + Bangle.js Gadgetbridge + Засосунок-компаньйон Android для Bangle.js побудований на основі проєкту Gadgetbridge, з додаванням доступу до інтернету. + Bangle.js працює + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + Bangle.js працює + Gadgetbridge (Nightly) + Про Gadgetbridge Nightly + Nightly GB працює + Gadgetbridge (Nightly, без постачальника Pebble) + Gadgetbridge Nightly без Pebble + Про Gadgetbridge Nightly без Pebble + Nightly NoPebble GB працює + Про Bangle.js Gadgetbridge + Про Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + Засосунок-компаньйон Android для Bangle.js побудований на основі проєкту Gadgetbridge, з додаванням доступу до інтернету. + Gadgetbridge Nightly + Безхмарна вільна з копілефт ліцензією заміна власницьких застосунків для пристроїв Android. Випуски Gadgetbridge Nightly. Його не можна встановити, якщо у вас уже встановлено застосунок Gadgetbridge або Pebble через конфлікт у постачальника Pebble. + Безхмарна вільна з копілефт ліцензією заміна власницьких застосунків для пристроїв Android. Випуски Gadgetbridge Nightly. У цій версії постачальник Pebble перейменований для запобігання конфліктів, тому деякі інтеграції, пов\'язані з Pebble, не працюватимуть, але його можна встановити разом із наявним установленим Gadgetbridge. \ No newline at end of file From c3be9b436a1a3b5fcb102be75e05fcf235b94b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Mon, 2 May 2022 05:41:56 +0000 Subject: [PATCH 073/110] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1490 of 1490 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index ab20c7d41..815375e0a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1600,4 +1600,24 @@ 预设位置为 %s 有新通知时亮起 电子邮件 + Bangle.js 的 Android 配套应用程序构建在 Gadgetbridge 项目之上,增加了 Internet 访问。 + Bangle.js 正在运行 + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + 关于 Bangle.js Gadgetbridge + Bangle.js 的 Android 配套应用程序构建在 Gadgetbridge 项目之上,增加了 Internet 访问。 + Bangle.js 正在运行 + Gadgetbridge (每夜编译版本) + Gadgetbridge 每夜编译版本 + 关于 Gadgetbridge 每夜编译版本 + 每夜编译版本的 GB 正在运行 + Gadgetbridge 每夜编译版本,无 Pebble + 无 Pebble 的每夜编译版 GB 正在运行 + 关于 Gadgetbridge 每夜编译版本,无 Pebble + 供应商提供的闭源 Android 小工具应用程序的无云无版权库替代品。 Gadgetbridge 的夜间版本。 此版本重命名了 Pebble 提供程序以防止冲突,因此某些与 Pebble 相关的集成将不起作用,但它可以与现有的 Gadgetbridge 安装一起安装。 + Gadgetbridge (每夜编译版本,无 Pebble 服务商) + Bangle.js Gadgetbridge + 关于 Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + 服务商提供的闭源 Android 小工具应用程序的无云无版本的替代品。 Gadgetbridge 的每夜编译版本。 如果您已经安装了 Gadgetbridge 或 Pebble 应用程序,则无法安装它,因为 Pebble 提供程序存在冲突。 \ No newline at end of file From b446d57eb031bd9b388bb467d8f2a186718d5cec Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Sat, 7 May 2022 12:39:44 +0000 Subject: [PATCH 074/110] Translated using Weblate (Hebrew) Currently translated at 100.0% (1490 of 1490 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 8b45d9f91..ca53cbbd6 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -1607,4 +1607,11 @@ Gadgetbridge (גרסה ניסיונית) Bangle.js Gadgetbridge Bangle.js פעיל + GB במהדורה לילית פעיל + על מהדורה לילית של Gadgetbridge בלי Pebble + GB ללא Pebble במהדורה לילית פעיל + חלופה חופשית ונטולת ענן ליישומוני הגאדג׳טים הסגורים ל־Android מהיצרנים. מהדורות ליליות של Gadgetbridge. אי אפשר להתקין אם כבר יש לך את היישומונים Gadgetbridge או Pebble מותקנים עקב סתירה בספק ה־Pebble. + מהדורה לילית של Gadgetbridge בלי Pebble + Gadgetbridge (מהדורה לילית, בלי ספק Pebble) + חלופה חופשית ונטולת ענן ליישומוני הגאדג׳טים הסגורים ל־Android מהיצרנים. מהדורות ליליות של Gadgetbridge. במהדורה זו שמו של ספק ה־Pebble השתנה כדי למנוע סתירות, לכן כמה מהשילובים מול Pebble לא יעבדו אך ניתן להתקין אותו לצד התקנה קיימת של Gadgetbridge. \ No newline at end of file From 6dd7da97100767891ec37a44e9c3209ee6e1f9c0 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Mon, 9 May 2022 15:27:29 +0000 Subject: [PATCH 075/110] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1491 of 1491 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/uk/ --- app/src/main/res/values-uk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 2cbee6809..eee7255f6 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1622,4 +1622,5 @@ Gadgetbridge Nightly Безхмарна вільна з копілефт ліцензією заміна власницьких застосунків для пристроїв Android. Випуски Gadgetbridge Nightly. Його не можна встановити, якщо у вас уже встановлено застосунок Gadgetbridge або Pebble через конфлікт у постачальника Pebble. Безхмарна вільна з копілефт ліцензією заміна власницьких застосунків для пристроїв Android. Випуски Gadgetbridge Nightly. У цій версії постачальник Pebble перейменований для запобігання конфліктів, тому деякі інтеграції, пов\'язані з Pebble, не працюватимуть, але його можна встановити разом із наявним установленим Gadgetbridge. + Перемкнути стеження фітнес-застосунку \ No newline at end of file From cbc11baa5d36ce4221a1370bc4eaf125cd27f0c1 Mon Sep 17 00:00:00 2001 From: nautilusx Date: Mon, 9 May 2022 16:11:36 +0000 Subject: [PATCH 076/110] Translated using Weblate (German) Currently translated at 100.0% (1494 of 1494 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/de/ --- app/src/main/res/values-de/strings.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e0dc57876..0da11a744 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1603,4 +1603,28 @@ Letzter autom. Export: %1$s Standort ermittelt nicht möglich. Wahrscheinlich ein Problem des neueren Android-Berechtigungssystems. Höchstwahrscheinlich funktioniert der autom. Export jetzt nicht. E-Mail + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + Android-Begleit-App für Bangle.js, die auf dem Gadgetbridge-Projekt aufbaut, mit zusätzlichem Internetzugang. + Bangle.js läuft + Android-Begleit-App für Bangle.js, die auf dem Gadgetbridge-Projekt aufbaut, mit zusätzlichem Internetzugang. + Gadgetbridge (Nightly) + Gadgetbridge Nightly + Über Gadgetbridge Nightly + Cloudloser und freier quelloffener Ersatz für Closed-Source Android-Gadget-Apps von Anbietern. Nächtliche Veröffentlichungen von Gadgetbridge. Es kann nicht installiert werden, wenn du bereits die Gadgetbridge- oder die Pebble-App installiert hast, da es einen Konflikt mit dem Pebble-Anbieter gibt. + Nightly GB läuft + Gadgetbridge (Nightly, kein Pebble-Anbieter) + Gadgetbridge Nightly kein Pebble + Über Gadgetbridge Nightly kein Pebble + Nightly kein Pebble GB läuft + Empfindlichkeit + Normal + Empfindlich + Bangle.js Gadgetbridge + Über Bangle.js Gadgetbridge + Cloudloser und freier quelloffener Ersatz für Closed-Source Android-Gadget-Apps von Anbietern. Nächtliche Veröffentlichungen von Gadgetbridge. Bei dieser Version wurde der Pebble-Provider umbenannt, um Konflikte zu vermeiden. Daher werden einige Pebble-bezogene Integrationen nicht funktionieren, aber sie kann neben einer bestehenden Gadgetbridge-Installation installiert werden. + Bangle.js Gadgetbridge + Bangle.js läuft + Über Bangle.js Gadgetbridge + Fitness-App-Tracking umschalten \ No newline at end of file From 6015e5c931564ab444f6cc7f671234584070379a Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 9 May 2022 18:16:34 +0000 Subject: [PATCH 077/110] Translated using Weblate (Hebrew) Currently translated at 100.0% (1494 of 1494 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index ca53cbbd6..ef51230cc 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -1614,4 +1614,8 @@ מהדורה לילית של Gadgetbridge בלי Pebble Gadgetbridge (מהדורה לילית, בלי ספק Pebble) חלופה חופשית ונטולת ענן ליישומוני הגאדג׳טים הסגורים ל־Android מהיצרנים. מהדורות ליליות של Gadgetbridge. במהדורה זו שמו של ספק ה־Pebble השתנה כדי למנוע סתירות, לכן כמה מהשילובים מול Pebble לא יעבדו אך ניתן להתקין אותו לצד התקנה קיימת של Gadgetbridge. + רגישות + רגילה + רגישה + החלפת מצב מעקב ביישומון חיטוב \ No newline at end of file From b72bec94d957e11422538923f3b57e51f7fae497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Mon, 9 May 2022 18:14:06 +0000 Subject: [PATCH 078/110] Translated using Weblate (Turkish) Currently translated at 100.0% (1494 of 1494 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/tr/ --- app/src/main/res/values-tr/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 5c66463e6..0695aedd6 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -1631,4 +1631,8 @@ İnternet erişimi eklenen Gadgetbridge projesinin üzerine inşa edilmiş Bangle.js için Android yardımcı uygulaması. Bangle.js çalışıyor Gadgetbridge (Gecelik) + Hassasiyet + Normal + Hassas + Fitness Uygulaması İzlemesini Değiştir \ No newline at end of file From 1f0764cc81ff91a19fd0c33c17f24d59113beb0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Tue, 10 May 2022 01:46:39 +0000 Subject: [PATCH 079/110] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1494 of 1494 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 815375e0a..1f076e7a4 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1620,4 +1620,8 @@ 关于 Bangle.js Gadgetbridge Bangle.js Gadgetbridge 服务商提供的闭源 Android 小工具应用程序的无云无版本的替代品。 Gadgetbridge 的每夜编译版本。 如果您已经安装了 Gadgetbridge 或 Pebble 应用程序,则无法安装它,因为 Pebble 提供程序存在冲突。 + 敏感度 + 正常 + 敏感 + 切换健身应用跟踪 \ No newline at end of file From 7f5989d88aca443b6cb169c407af9449e1f608af Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Tue, 10 May 2022 15:40:22 +0000 Subject: [PATCH 080/110] Translated using Weblate (Hebrew) Currently translated at 100.0% (1503 of 1503 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index ef51230cc..97d29b1ea 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -1618,4 +1618,13 @@ רגילה רגישה החלפת מצב מעקב ביישומון חיטוב + אין מקומות פנויים + למכשיר אין עוד מקומות פנויים לשעוני העולם (סך כל המקומות: %1$s) + אזור זמן + תווית + שעוני העולם + הגדרת שעונים לאזורי זמן אחרים + למחוק את השעון העולמי\? + מחיקת ‚%1$s’ + פרטי השעון העולמי \ No newline at end of file From 0fea491ff67b778555bae3532ca2a7050a79995c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 10 May 2022 18:36:45 +0000 Subject: [PATCH 081/110] Translated using Weblate (Turkish) Currently translated at 100.0% (1503 of 1503 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/tr/ --- app/src/main/res/values-tr/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 0695aedd6..9bac6eb7c 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -1635,4 +1635,13 @@ Normal Hassas Fitness Uygulaması İzlemesini Değiştir + Dünya Saatleri + Diğer saat dilimleri için saatleri yapılandırın + \'%1$s\' sil + Dünya saatini silmek istediğinizden emin misiniz\? + Boş yuva yok + Dünya saati ayrıntıları + Aygıtta dünya saatleri için boş yuva yok (toplam yuva: %1$s) + Saat Dilimi + Etiket \ No newline at end of file From d5bc4dcce235ddda94957a49bac1763f00d04b60 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 10 May 2022 15:06:32 +0000 Subject: [PATCH 082/110] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1503 of 1503 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/uk/ --- app/src/main/res/values-uk/strings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index eee7255f6..bd2d9da07 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1623,4 +1623,16 @@ Безхмарна вільна з копілефт ліцензією заміна власницьких застосунків для пристроїв Android. Випуски Gadgetbridge Nightly. Його не можна встановити, якщо у вас уже встановлено застосунок Gadgetbridge або Pebble через конфлікт у постачальника Pebble. Безхмарна вільна з копілефт ліцензією заміна власницьких застосунків для пристроїв Android. Випуски Gadgetbridge Nightly. У цій версії постачальник Pebble перейменований для запобігання конфліктів, тому деякі інтеграції, пов\'язані з Pebble, не працюватимуть, але його можна встановити разом із наявним установленим Gadgetbridge. Перемкнути стеження фітнес-застосунку + Видалити«%1$s» + Ви впевнені, що хочете видалити світовий годинник\? + Пристрій не має вільних комірок для світових годинників (загальна кількість комірок: %1$s) + Чутливість + Звичайно + Чутливо + Світовий час + Налаштувати годинник для інших часових поясів + Подробиці світового годинника + Немає вільних комірок + Часовий пояс + Мітка \ No newline at end of file From dfc69c3ea548d93a68bee0b58b77e65856ad4888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Tue, 10 May 2022 16:22:46 +0000 Subject: [PATCH 083/110] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1503 of 1503 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 1f076e7a4..cf975e870 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1624,4 +1624,13 @@ 正常 敏感 切换健身应用跟踪 + 您确定想要删除此世界时钟? + 没有可用的位置 + 此设备已经没有可用的位置放置世界时钟了(总可用位置:%1$s) + 时区 + 标签 + 世界时钟详情 + 为其他时区配置时钟 + 删除\'%1$s\' + 世界时钟 \ No newline at end of file From 2e3ff80d766374f14598e01e2a5eb80d3976c7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vinc=C3=A8n=20PUJOL?= Date: Fri, 13 May 2022 11:52:57 +0000 Subject: [PATCH 084/110] Translated using Weblate (French) Currently translated at 98.6% (1488 of 1509 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/fr/ --- app/src/main/res/values-fr/strings.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 80b59f423..e73fea645 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1601,4 +1601,19 @@ Temps de sommeil préféré en heures Bangle.js Gadgetbridge A propos de Bangle.js Gadgetbridge Bangle.js Gadgetbridge + Application complémentaire Android pour Bangle.js élaborée sur la base du projet Gadgetbridge, avec des fonctionnalités Internet supplémentaires. + Bangle.js pour Gadgetbridge + Bangle.js pour Gadgetbridge + A propos de Gatgetbridge Nightly + A propos de Bangle.js pour Gadgetbridge + A propos de Gadgetbridge Nightly sans Pebble + Remplaçant autonome et sous licence libre pour remplacer les applications propriétaires des fabricants. Version Nightly de Gadgetbridge. Ne peut pas être installé si vous avez déja Gadgetbridge ou Pebble d\'installé, en raison d\'un conflit avec l\'application Pebble. + Gadgetbridage (Nightly, pas defournisseur Pebble) + Gadgetbridge Nightly Sans Pebble + GB Nightly en fonctionnement + Bangle.js en fonctionnement + Application complémentaire Android pour Bangle.js élaborée sur la base du projet Gadgetbridge, avec des fonctionnalités Internet supplémentaires. + Bangle.js en fonctionnement + Gadgetbridge (version Nightly) + Gadgetbrigde version Nightly \ No newline at end of file From 4ccbb636e5f32fb1c4ecc37c4194fcfdfc0b7069 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Thu, 12 May 2022 10:43:17 +0000 Subject: [PATCH 085/110] Translated using Weblate (Hebrew) Currently translated at 100.0% (1509 of 1509 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 97d29b1ea..d4c1deaf2 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -1009,7 +1009,7 @@ להשתמש באירועי המכשיר כדי לגרור פעולות ושידורי Android יוגה קפיצה בחבל - אליפטיקל + אליפטיקל עם ידיות רכיבה בתוך מבנה שחייה במים פתוחים החלת מסנן @@ -1627,4 +1627,10 @@ למחוק את השעון העולמי\? מחיקת ‚%1$s’ פרטי השעון העולמי + ריצה בחוץ + סגנון חופשי + רכיבת אופניים בחוץ + אליפטיקל בלי ידיות + נא לבחור את סוגי הפעילות להצגה במסך האימון + סוגי פעילות אימון \ No newline at end of file From ba33f8d247e0796fbbaa82c44aa029ff137e87cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Thu, 12 May 2022 18:43:45 +0000 Subject: [PATCH 086/110] Translated using Weblate (Turkish) Currently translated at 100.0% (1509 of 1509 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/tr/ --- app/src/main/res/values-tr/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 9bac6eb7c..63c11f3bf 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -1644,4 +1644,10 @@ Aygıtta dünya saatleri için boş yuva yok (toplam yuva: %1$s) Saat Dilimi Etiket + Serbest Stil + Eliptik Bisiklet + Egzersiz Etkinlik Türleri + Açık Havada Bisiklet Sürme + Egzersizler ekranında görüntülenecek etkinlik türlerini seçin + Açık Havada Koşu \ No newline at end of file From 43fcc4e079bdc6cd76a98cf030791e709925473f Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Thu, 12 May 2022 21:08:50 +0000 Subject: [PATCH 087/110] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1509 of 1509 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/uk/ --- app/src/main/res/values-uk/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index bd2d9da07..f2f03e4c8 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1635,4 +1635,10 @@ Немає вільних комірок Часовий пояс Мітка + Типи тренувань + Біг надворі + Виберіть які типи активності показувати на екрані тренувань + Фристайл + Велоїзда надворі + Еліптичний \ No newline at end of file From 5c14ddcb7511a5b0c4f112d6def2f3a69dd7fa70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Thu, 12 May 2022 10:19:13 +0000 Subject: [PATCH 088/110] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1509 of 1509 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index cf975e870..0d753b2df 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1633,4 +1633,10 @@ 为其他时区配置时钟 删除\'%1$s\' 世界时钟 + 锻炼活动类型 + 选择要在锻炼屏幕上显示的活动类型 + 椭圆机 + 自由式 + 户外跑步 + 户外单车 \ No newline at end of file From 4491c93a031b85438cf42541f1a3e84c4da3b5b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Fern=C3=A1ndez=20D=C3=ADaz?= Date: Sat, 14 May 2022 09:47:39 +0000 Subject: [PATCH 089/110] Translated using Weblate (Spanish) Currently translated at 99.0% (1494 of 1509 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/es/ --- app/src/main/res/values-es/strings.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index bf85b9cd1..7cddb3f44 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1600,4 +1600,28 @@ No se ha podido entender la ubicación. Probablemente un problema del nuevo sistema de permisos de Android. Lo más probable es que la autoexportación no funcione ahora. Encender al recibir una notificación nueva Correo electrónico + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + Acerca de Bangle.js Gadgetbridge + Aplicación complementaria de Android para Bangle.js construida sobre el proyecto Gadgetbridge, con acceso a Internet añadido. + Bangle.js ejecutándose + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + Acerca de Bangle.js Gadgetbridge + Aplicación complementaria de Android para Bangle.js construida sobre el proyecto Gadgetbridge, con acceso a Internet añadido. + Bangle.js ejecutándose + Gadgetbridge (Nightly) + Gadgetbridge Nightly + Acerca de Gadgetbridge Nightly + Reemplazo libre y sin copias de las aplicaciones de código cerrado para Android de los vendedores. Versiones nightly de Gadgetbridge. No se puede instalar si ya tiene instalada la aplicación de Gadgetbridge o la de Pebble, debido a un conflicto en el proveedor de Pebble. + GB Nightly ejecutándose + Gadgetbridge (Nightly, Sin proveedor de Pebble) + Gadgetbridge Nightly sin Pebble + Acerca de Gadgetbridge Nightly sin Pebble + Reemplazo libre y sin copias de las aplicaciones de código cerrado para Android de los vendedores. Versiones nightly de Gadgetbridge. Esta versión tiene el proveedor de Pebble renombrado para evitar conflictos, por lo que algunas integraciones relacionadas con Pebble no funcionarán, pero se puede instalar junto a la instalación existente de Gadgetbridge. + GB Nightly sin Pebble ejecutándose + Relojes mundiales + Configurar los relojes para otras zonas horarias + Eliminar \'%1$s\' + ¿Está seguro de que quiere eliminar el reloj mundial\? \ No newline at end of file From b8e490703cd1125ce51b1c8efab6edcd0a517204 Mon Sep 17 00:00:00 2001 From: vanous Date: Sat, 14 May 2022 14:28:22 +0000 Subject: [PATCH 090/110] Translated using Weblate (Czech) Currently translated at 100.0% (1514 of 1514 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/cs/ --- app/src/main/res/values-cs/strings.xml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index e1c248853..c86c56640 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -1521,7 +1521,7 @@ Přeskočit zpět Zápis (commit) %s Zapauzování - Přepnout přehrávání + Zapnout/vypnout přehrávání Odeslat vysílání (broadcast) Deaktivováno Předchozí skladba @@ -1617,4 +1617,28 @@ Gadgetbridge Noční, Bez Pebble Svobodná a lokální náhrada za uzavřenou aplikaci vašich hodinek/náramku. Noční vydání Gadgetbridge. Tato verze má přejmenovanou službu poskytovatele Pebble pro eliminaci konfliktů poskytovatelů. Některé Pebble integrace nebudou fungovat, ale tuto verzi je možno nainstalovat paralelně k již nainstalované jiné verzi Gadgetbridge. Noční NoPebble GB běží + Upozornění na nečinnost + Vzory vibrací + Eliptický trenér + Události + Typy tréninkových aktivit + Najít zařízení + Citlivost + Výběr typů aktivit, které se mají zobrazit na obrazovce tréninků + Citlivé + Normální + Venkovní běh + Venkovní cyklistika + Konfigurace vibračních vzorů pro různá oznámení + Zapnout/vypnout Sledování Sportovní aplikací + Volný styl + Opravdu chcete smazat položku světových hodin\? + Zařízení nemá žádná volná místa pro světové hodiny (celkový počet slotů: %1$s) + Časové pásmo + Titulek + Podrobnosti světových hodin + Světové hodiny + Konfigurace hodin pro jiná časová pásma + Odstranit \'%1$s\' + Žádné volné místo \ No newline at end of file From 39c25e3c507722c0d24d56b1db74574555822988 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Sat, 14 May 2022 20:50:51 +0000 Subject: [PATCH 091/110] Translated using Weblate (Hebrew) Currently translated at 100.0% (1514 of 1514 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index d4c1deaf2..6ff0704b2 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -1633,4 +1633,9 @@ אליפטיקל בלי ידיות נא לבחור את סוגי הפעילות להצגה במסך האימון סוגי פעילות אימון + תבניות רטט + הגדרת תבניות רטט להתראות השונות + מתזכר אירועים + התראות בטלה + איתור המכשיר \ No newline at end of file From 94049a4da8777c34f83411562977fb05ea3abe06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Sat, 14 May 2022 15:07:03 +0000 Subject: [PATCH 092/110] Translated using Weblate (Turkish) Currently translated at 100.0% (1514 of 1514 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/tr/ --- app/src/main/res/values-tr/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 63c11f3bf..d71be1eb9 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -1650,4 +1650,9 @@ Açık Havada Bisiklet Sürme Egzersizler ekranında görüntülenecek etkinlik türlerini seçin Açık Havada Koşu + Boşta Kalma Uyarıları + Titreşim Modelleri + Etkinlik hatırlatıcı + Aygıt bul + Farklı bildirimler için titreşim modellerini yapılandırın \ No newline at end of file From a9fec4fddb0ac0b78fa9b3a58db0429079a18739 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Sat, 14 May 2022 16:14:57 +0000 Subject: [PATCH 093/110] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1514 of 1514 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/uk/ --- app/src/main/res/values-uk/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index f2f03e4c8..ce7d58456 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1641,4 +1641,9 @@ Фристайл Велоїзда надворі Еліптичний + Сповіщення про простій + Нагадування про події + Знайти пристрій + Шаблони вібрацій + Налаштуйте шаблони вібрації для різних сповіщень \ No newline at end of file From bc81678859351c27263e5fb51260797a3fbf4182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Sat, 14 May 2022 17:36:11 +0000 Subject: [PATCH 094/110] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1514 of 1514 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 0d753b2df..42884263c 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1639,4 +1639,9 @@ 自由式 户外跑步 户外单车 + 查找设备 + 为不同的通知配置振动模式 + 事件提醒 + 空闲警报 + 振动模式 \ No newline at end of file From dd1b16ea8e76f024d21afb44d38dfe335f8b21e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Mon, 16 May 2022 12:36:56 +0000 Subject: [PATCH 095/110] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1515 of 1515 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 42884263c..00a378699 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1644,4 +1644,5 @@ 事件提醒 空闲警报 振动模式 + Sony WF-1000XM3 \ No newline at end of file From 65ebdb6ff8cdf00dd62f2c8fe2e4364d53176e0a Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 16 May 2022 16:05:04 +0200 Subject: [PATCH 096/110] Amazfit Bip U/Pro: Enable vibration pattern settings --- CHANGELOG.md | 2 +- .../devices/huami/amazfitbipu/AmazfitBipUCoordinator.java | 1 + .../devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc326eb45..9667605e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ * Mi Band 5/6, Amazfit Bip S/U/Pro: Add world clock configuration * Mi Band 5/6: support sensitivity setting for lift wrist configuration * Mi Band 5: Add support for configuring workout menu on device -* Mi Band 4/5/6: Add support for vibration patterns +* Mi Band 4/5/6, Amazfit Bip U/Pro: Add support for vibration patterns * Mi Band 5: Increase number of reminder slots to 50 * Amazfit Neo: Allow to disable beeps for email notifications * Bangle.js: Fix incoming calls in release builds diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java index 523c0bcf8..e6c131318 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java @@ -107,6 +107,7 @@ public class AmazfitBipUCoordinator extends HuamiCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_amazfitbipu, + R.xml.devicesettings_vibrationpatterns, //R.xml.devicesettings_canned_dismisscall_16, R.xml.devicesettings_timeformat, R.xml.devicesettings_world_clocks, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java index c87c8d89c..56b3de59d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java @@ -107,6 +107,7 @@ public class AmazfitBipUProCoordinator extends HuamiCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_amazfitbipupro, + R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_timeformat, R.xml.devicesettings_world_clocks, R.xml.devicesettings_wearlocation, From 9ca3fff101cfd2d40796d8cd83b79e7d53fd0792 Mon Sep 17 00:00:00 2001 From: mvn23 Date: Sun, 15 May 2022 16:51:41 +0200 Subject: [PATCH 097/110] Add support for native `Do Not Disturb` call/SMS functionality on Fossil watches --- .../freeyourgadget/gadgetbridge/GBApplication.java | 6 ++---- .../externalevents/PhoneCallReceiver.java | 10 ++++++++-- .../gadgetbridge/externalevents/SMSReceiver.java | 10 ++++++++-- .../gadgetbridge/impl/GBDeviceService.java | 3 ++- .../gadgetbridge/model/CallSpec.java | 1 + .../gadgetbridge/model/DeviceService.java | 1 + .../service/DeviceCommunicationService.java | 2 ++ .../adapter/fossil_hr/FossilHRWatchAdapter.java | 6 +++--- .../notification/PlayCallNotificationRequest.java | 14 ++++++++------ 9 files changed, 35 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 10ac359e1..f746608d3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -438,10 +438,8 @@ public class GBApplication extends Application { @TargetApi(Build.VERSION_CODES.M) public static int getGrantedInterruptionFilter() { - if (prefs.getBoolean("notification_filter", false) && GBApplication.isRunningMarshmallowOrLater()) { - if (notificationManager.isNotificationPolicyAccessGranted()) { - return notificationManager.getCurrentInterruptionFilter(); - } + if (GBApplication.isRunningMarshmallowOrLater() && notificationManager.isNotificationPolicyAccessGranted()) { + return notificationManager.getCurrentInterruptionFilter(); } return NotificationManager.INTERRUPTION_FILTER_ALL; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java index 027772269..d4922d543 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java @@ -107,22 +107,28 @@ public class PhoneCallReceiver extends BroadcastReceiver { if ("never".equals(prefs.getString("notification_mode_calls", "always"))) { return; } + int dndSuppressed = 0; switch (GBApplication.getGrantedInterruptionFilter()) { case NotificationManager.INTERRUPTION_FILTER_ALL: break; case NotificationManager.INTERRUPTION_FILTER_ALARMS: case NotificationManager.INTERRUPTION_FILTER_NONE: - return; + dndSuppressed = 1; + break; case NotificationManager.INTERRUPTION_FILTER_PRIORITY: if (GBApplication.isPriorityNumber(Policy.PRIORITY_CATEGORY_CALLS, mSavedNumber)) { break; } // FIXME: Handle Repeat callers if it is enabled in Do Not Disturb - return; + dndSuppressed = 1; + } + if (prefs.getBoolean("notification_filter", false) && dndSuppressed == 1) { + return; } CallSpec callSpec = new CallSpec(); callSpec.number = mSavedNumber; callSpec.command = callCommand; + callSpec.dndSuppressed = dndSuppressed; GBApplication.deviceService().onSetCallState(callSpec); } mLastState = state; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java index 7065c39bb..6d1812133 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java @@ -87,18 +87,24 @@ public class SMSReceiver extends BroadcastReceiver { dismissAllAction.type = NotificationSpec.Action.TYPE_SYNTECTIC_DISMISS_ALL; notificationSpec.attachedActions.add(dismissAllAction); + int dndSuppressed = 0; switch (GBApplication.getGrantedInterruptionFilter()) { case NotificationManager.INTERRUPTION_FILTER_ALL: break; case NotificationManager.INTERRUPTION_FILTER_ALARMS: case NotificationManager.INTERRUPTION_FILTER_NONE: - return; + dndSuppressed = 1; + break; case NotificationManager.INTERRUPTION_FILTER_PRIORITY: if (GBApplication.isPriorityNumber(Policy.PRIORITY_CATEGORY_MESSAGES, notificationSpec.phoneNumber)) { break; } - return; + dndSuppressed = 1; } + if (prefs.getBoolean("notification_filter", false) && dndSuppressed == 1) { + return; + } + notificationSpec.dndSuppressed = dndSuppressed; GBApplication.deviceService().onNotification(notificationSpec); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index 15f842bb7..d0f12cc73 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -201,7 +201,8 @@ public class GBDeviceService implements DeviceService { Intent intent = createIntent().setAction(ACTION_CALLSTATE) .putExtra(EXTRA_CALL_PHONENUMBER, callSpec.number) .putExtra(EXTRA_CALL_DISPLAYNAME, callSpec.name) - .putExtra(EXTRA_CALL_COMMAND, callSpec.command); + .putExtra(EXTRA_CALL_COMMAND, callSpec.command) + .putExtra(EXTRA_CALL_DNDSUPPRESSED, callSpec.dndSuppressed); invokeService(intent); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CallSpec.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CallSpec.java index 817ba872c..97a4efd94 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CallSpec.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CallSpec.java @@ -28,4 +28,5 @@ public class CallSpec { public String number; public String name; public int command; + public int dndSuppressed; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index edb88e8b6..bd22e9af3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -91,6 +91,7 @@ public interface DeviceService extends EventHandler { String EXTRA_CALL_COMMAND = "call_command"; String EXTRA_CALL_PHONENUMBER = "call_phonenumber"; String EXTRA_CALL_DISPLAYNAME = "call_displayname"; + String EXTRA_CALL_DNDSUPPRESSED = "call_dndsuppressed"; String EXTRA_CANNEDMESSAGES = "cannedmessages"; String EXTRA_CANNEDMESSAGES_TYPE = "cannedmessages_type"; String EXTRA_MUSIC_ARTIST = "music_artist"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 0708899dd..d83db85c6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -141,6 +141,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CAL import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_TYPE; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_COMMAND; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_DISPLAYNAME; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_DNDSUPPRESSED; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_PHONENUMBER; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CANNEDMESSAGES; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CANNEDMESSAGES_TYPE; @@ -511,6 +512,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere callSpec.command = intent.getIntExtra(EXTRA_CALL_COMMAND, CallSpec.CALL_UNDEFINED); callSpec.number = intent.getStringExtra(EXTRA_CALL_PHONENUMBER); callSpec.name = sanitizeNotifText(intent.getStringExtra(EXTRA_CALL_DISPLAYNAME)); + callSpec.dndSuppressed = intent.getIntExtra(EXTRA_CALL_DNDSUPPRESSED, 0); mDeviceSupport.onSetCallState(callSpec); break; case ACTION_SETCANNEDMESSAGES: diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index 3f17f3029..bdd0a63f6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -1157,10 +1157,10 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { boolean quickRepliesEnabled = quickReplies.length > 0 && callSpec.number != null && callSpec.number.matches("^\\+(?:[0-9] ?){6,14}[0-9]$"); if (callSpec.command == CallSpec.CALL_INCOMING) { currentCallSpec = callSpec; - queueWrite(new PlayCallNotificationRequest(StringUtils.getFirstOf(callSpec.name, callSpec.number), true, quickRepliesEnabled, this)); + queueWrite(new PlayCallNotificationRequest(StringUtils.getFirstOf(callSpec.name, callSpec.number), true, quickRepliesEnabled, callSpec.dndSuppressed, this)); } else { currentCallSpec = null; - queueWrite(new PlayCallNotificationRequest(StringUtils.getFirstOf(callSpec.name, callSpec.number), false, quickRepliesEnabled, this)); + queueWrite(new PlayCallNotificationRequest(StringUtils.getFirstOf(callSpec.name, callSpec.number), false, quickRepliesEnabled, callSpec.dndSuppressed, this)); } } @@ -1616,7 +1616,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { private void handleCallRequest(byte[] value) { boolean acceptCall = value[7] == (byte) 0x00; - queueWrite(new PlayCallNotificationRequest("", false, false, this)); + queueWrite(new PlayCallNotificationRequest("", false, false, 0,this)); GBDeviceEventCallControl callControlEvent = new GBDeviceEventCallControl(); callControlEvent.event = acceptCall ? GBDeviceEventCallControl.Event.START : GBDeviceEventCallControl.Event.REJECT; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java index 15d2d0994..64906aa85 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/notification/PlayCallNotificationRequest.java @@ -24,18 +24,20 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.foss public class PlayCallNotificationRequest extends PlayNotificationRequest { private final static int MESSAGE_ID_CALL = 1; - private static int notificationFlags(boolean callStart, boolean quickReplies) { + private static int notificationFlags(boolean callStart, boolean quickReplies, int dndSuppressed) { + int flags = 0; if (callStart && quickReplies) { - return 0b00111000; + flags = 0b00111000; } else if (callStart) { - return 0b00011000; + flags = 0b00011000; } else { - return 0b00000010; + flags = 0b00000010; } + return (flags | dndSuppressed); } - public PlayCallNotificationRequest(String number, boolean callStart, boolean quickReplies, FossilWatchAdapter adapter) { - super(callStart ? NotificationType.INCOMING_CALL : NotificationType.DISMISS_NOTIFICATION, notificationFlags(callStart, quickReplies), + public PlayCallNotificationRequest(String number, boolean callStart, boolean quickReplies, int dndSuppressed, FossilWatchAdapter adapter) { + super(callStart ? NotificationType.INCOMING_CALL : NotificationType.DISMISS_NOTIFICATION, notificationFlags(callStart, quickReplies, dndSuppressed), ByteBuffer.wrap(new byte[]{(byte) 0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}).order(ByteOrder.LITTLE_ENDIAN).getInt(), number, "Incoming Call", MESSAGE_ID_CALL, adapter); } From ed6b2e44b9bf04fc7e15dde04586ada3a8fd28a8 Mon Sep 17 00:00:00 2001 From: theghostofheathledger Date: Tue, 17 May 2022 11:55:29 +0200 Subject: [PATCH 098/110] Add com.samsung.android.incallui to handleCallNotification blacklist --- .../gadgetbridge/externalevents/NotificationListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index 16e9c34b1..547afd723 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -494,7 +494,7 @@ public class NotificationListener extends NotificationListenerService { private void handleCallNotification(StatusBarNotification sbn) { String app = sbn.getPackageName(); LOG.debug("got call from: " + app); - if (app.equals("com.android.dialer") || app.equals("com.android.incallui") || app.equals("com.google.android.dialer") || app.equals("com.asus.asusincallui")) { + if (app.equals("com.android.dialer") || app.equals("com.android.incallui") || app.equals("com.google.android.dialer") || app.equals("com.asus.asusincallui") || app.equals("com.samsung.android.incallui")) { LOG.debug("Ignoring non-voip call"); return; } From 948db604e5ec45a47f2d198816f8cc803703d86e Mon Sep 17 00:00:00 2001 From: vanous Date: Tue, 17 May 2022 22:18:49 +0200 Subject: [PATCH 099/110] Add support for Galaxy Buds Pro - add generic coordinator and settings customizer for Galaxy Buds - add Prefs to the DeviceSpecificSettingsCustomizer - edit Changelog --- CHANGELOG.md | 7 +- app/src/main/assets/buds_pro_case.svg | 51 ++++ app/src/main/assets/buds_pro_left.svg | 67 +++++ app/src/main/assets/buds_pro_right.svg | 73 +++++ .../main/assets/ic_device_galaxy_buds_pro.svg | 147 ++++++++++ .../ic_device_galaxy_buds_pro_disabled.svg | 200 ++++++++++++++ .../DeviceSettingsPreferenceConst.java | 17 ++ .../DeviceSpecificSettingsCustomizer.java | 5 +- .../DeviceSpecificSettingsFragment.java | 20 +- .../GalaxyBudsDeviceCoordinator.java | 108 +------- .../GalaxyBudsGenericCoordinator.java | 114 ++++++++ .../GalaxyBudsLiveDeviceCoordinator.java | 107 +------- .../GalaxyBudsProDeviceCoordinator.java | 57 ++++ .../GalaxyBudsSettingsCustomizer.java | 241 +++++++++++++++++ .../huami/HuamiSettingsCustomizer.java | 4 +- .../SonyHeadphonesSettingsCustomizer.java | 3 +- .../gadgetbridge/model/DeviceType.java | 1 + .../service/DeviceSupportFactory.java | 3 + .../galaxy_buds/GalaxyBudsIOThread.java | 3 +- .../galaxy_buds/GalaxyBudsProtocol.java | 253 ++++++++++++++++-- .../gadgetbridge/util/DeviceHelper.java | 2 + .../main/res/drawable/ic_buds_pro_case.xml | 3 + .../main/res/drawable/ic_buds_pro_left.xml | 17 ++ .../main/res/drawable/ic_buds_pro_right.xml | 17 ++ .../drawable/ic_device_galaxy_buds_pro.xml | 31 +++ .../ic_device_galaxy_buds_pro_disabled.xml | 36 +++ app/src/main/res/drawable/ic_switch_right.xml | 10 + app/src/main/res/values/arrays.xml | 89 +++++- app/src/main/res/values/strings.xml | 40 +++ app/src/main/res/values/values.xml | 5 - .../res/xml/devicesettings_galaxy_buds.xml | 15 +- .../xml/devicesettings_galaxy_buds_live.xml | 4 +- .../xml/devicesettings_galaxy_buds_pro.xml | 239 +++++++++++++++++ 33 files changed, 1719 insertions(+), 270 deletions(-) create mode 100644 app/src/main/assets/buds_pro_case.svg create mode 100644 app/src/main/assets/buds_pro_left.svg create mode 100644 app/src/main/assets/buds_pro_right.svg create mode 100644 app/src/main/assets/ic_device_galaxy_buds_pro.svg create mode 100644 app/src/main/assets/ic_device_galaxy_buds_pro_disabled.svg create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsGenericCoordinator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java create mode 100644 app/src/main/res/drawable/ic_buds_pro_case.xml create mode 100644 app/src/main/res/drawable/ic_buds_pro_left.xml create mode 100644 app/src/main/res/drawable/ic_buds_pro_right.xml create mode 100644 app/src/main/res/drawable/ic_device_galaxy_buds_pro.xml create mode 100644 app/src/main/res/drawable/ic_device_galaxy_buds_pro_disabled.xml create mode 100644 app/src/main/res/drawable/ic_switch_right.xml create mode 100644 app/src/main/res/xml/devicesettings_galaxy_buds_pro.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 9667605e8..f78cd5ee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ### NEXT * Initial Support for Sony WF-1000XM3 -* Huami: Add Toggle function for Open Tracks tracking to button actionss +* Initial Support for Galaxy Buds Pro +* Huami: Add Toggle function for Open Tracks tracking to button actions * Huami: Move inactivity warnings and goal notification to device-specific settings * Mi Band 6: set time on connect * Mi Band 5/6, Amazfit Bip S/U/Pro: Add world clock configuration @@ -16,9 +17,9 @@ * VESC: added battery indicator * UM25: Add reset option to current accumulation * UM25: Add notification on below current threshold -* Fix crash when calender is accessed but permission is denied +* Fix crash when calendar is accessed but permission is denied * Add com.asus.asusincallui to blacklist -* New icons for Sony WF 800n and Mi Band 6 +* New icons for Sony overhead headphones, Sony WF 800n and Mi Band 6 ### 0.66.0 * Add basic support for Casio GBD-H1000 diff --git a/app/src/main/assets/buds_pro_case.svg b/app/src/main/assets/buds_pro_case.svg new file mode 100644 index 000000000..985c459da --- /dev/null +++ b/app/src/main/assets/buds_pro_case.svg @@ -0,0 +1,51 @@ + + + + + + + + + + diff --git a/app/src/main/assets/buds_pro_left.svg b/app/src/main/assets/buds_pro_left.svg new file mode 100644 index 000000000..3fcbe9457 --- /dev/null +++ b/app/src/main/assets/buds_pro_left.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/buds_pro_right.svg b/app/src/main/assets/buds_pro_right.svg new file mode 100644 index 000000000..cd0075f58 --- /dev/null +++ b/app/src/main/assets/buds_pro_right.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/ic_device_galaxy_buds_pro.svg b/app/src/main/assets/ic_device_galaxy_buds_pro.svg new file mode 100644 index 000000000..17cdc49e8 --- /dev/null +++ b/app/src/main/assets/ic_device_galaxy_buds_pro.svg @@ -0,0 +1,147 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/ic_device_galaxy_buds_pro_disabled.svg b/app/src/main/assets/ic_device_galaxy_buds_pro_disabled.svg new file mode 100644 index 000000000..4f40a69bd --- /dev/null +++ b/app/src/main/assets/ic_device_galaxy_buds_pro_disabled.svg @@ -0,0 +1,200 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index 03f2cbf7d..1e59059d2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -139,8 +139,25 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_GALAXY_BUDS_EQUALIZER_MODE = "pref_galaxy_buds_equalizer_mode"; public static final String PREF_GALAXY_BUDS_TOUCH_LEFT = "pref_galaxy_buds_touch_left"; public static final String PREF_GALAXY_BUDS_TOUCH_RIGHT = "pref_galaxy_buds_touch_right"; + public static final String PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH = "pref_galaxy_buds_touch_right_switch"; + public static final String PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH = "pref_galaxy_buds_touch_left_switch"; public static final String PREF_GALAXY_BUDS_LIVE_ANC = "pref_galaxy_buds_live_anc"; public static final String PREF_GALAXY_BUDS_PRESSURE_RELIEF = "pref_galaxy_buds_live_pressure_relief"; + public static final String PREF_GALAXY_BUDS_AMBIENT_SOUND = "pref_galaxy_buds_ambient_sound"; + public static final String PREF_GALAXY_BUDS_PRO_NOISE_CONTROL="pref_galaxy_buds_pro_noise_control"; + public static final String PREF_GALAXY_PRO_DOUBLE_TAP_EDGE ="pref_galaxy_pro_double_tap_edge"; + public static final String PREF_GALAXY_BUDS_PRO_IN_EAR_DETECTION ="pref_galaxy_buds_pro_in_ear_detection"; + public static final String PREF_GALAXY_BUDS_PRO_VOICE_DETECT ="pref_galaxy_buds_pro_voice_detect"; + public static final String PREF_GALAXY_BUDS_PRO_VOICE_DETECT_DURATION ="pref_galaxy_buds_pro_voice_detect_duration"; + public static final String PREF_GALAXY_BUDS_PRO_BALANCE="pref_galaxy_buds_pro_balance"; + public static final String PREF_GALAXY_BUDS_PRO_READ_NOTIFICATIONS_OUTLOUD ="pref_galaxy_buds_pro_read_notifications_outloud"; + public static final String PREF_GALAXY_BUDS_AMBIENT_MODE_DURING_CALL ="pref_galaxy_buds_ambient_mode_during_call"; + public static final String PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_RIGHT ="pref_galaxy_buds_pro_ambient_volume_right"; + public static final String PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_LEFT="pref_galaxy_buds_pro_ambient_volume_left"; + public static final String PREF_GALAXY_BUDS_PRO_AMBIENT_SOUND_TONE ="pref_galaxy_buds_pro_ambient_sound_tone"; + public static final String PREFS_NOISE_CONTROL_WITH_ONE_EARBUD ="pref_galaxy_buds_noise_controls_with_one_earbud"; + public static final String PREF_GALAXY_BUDS_PRO_ANC_LEVEL="pref_galaxy_buds_pro_anc_level"; + public static final String PREFS_GALAXY_BUDS_SEAMLESS_CONNECTION="prefs_galaxy_buds_seamless_connection"; public static final String PREF_SONY_AUDIO_CODEC = "pref_sony_audio_codec"; public static final String PREF_SONY_AMBIENT_SOUND_CONTROL = "pref_sony_ambient_sound_control"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java index fc948131a..40516ec96 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsCustomizer.java @@ -21,6 +21,7 @@ import android.os.Parcelable; import androidx.preference.Preference; import java.util.Set; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; /** * A device-specific preference handler, that allows for concrete implementations to customize the preferences in @@ -37,10 +38,10 @@ public interface DeviceSpecificSettingsCustomizer extends Parcelable { /** * Customize the settings on the {@link DeviceSpecificSettingsFragment}. - * * @param handler the {@link DeviceSpecificSettingsHandler} + * @param prefs the {@link android.content.SharedPreferences} */ - void customizeSettings(final DeviceSpecificSettingsHandler handler); + void customizeSettings(final DeviceSpecificSettingsHandler handler, Prefs prefs); /** * Keys of preferences which should print its values as a summary below the preference name. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index a8ca0648f..d4271d269 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -431,7 +431,6 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp addPreferenceHandlerFor(PREF_NOTHING_EAR1_INEAR); addPreferenceHandlerFor(PREF_NOTHING_EAR1_AUDIOMODE); - addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_MODE); addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_VOICE_FOCUS); addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_VOLUME); addPreferenceHandlerFor(PREF_GALAXY_BUDS_LOCK_TOUCH); @@ -443,6 +442,23 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp addPreferenceHandlerFor(PREF_GALAXY_BUDS_TOUCH_RIGHT); addPreferenceHandlerFor(PREF_GALAXY_BUDS_LIVE_ANC); addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRESSURE_RELIEF); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_ANC_LEVEL); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_SOUND); + addPreferenceHandlerFor(PREF_GALAXY_PRO_DOUBLE_TAP_EDGE); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_IN_EAR_DETECTION); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_VOICE_DETECT); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_VOICE_DETECT_DURATION); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_BALANCE); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_READ_NOTIFICATIONS_OUTLOUD); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_MODE_DURING_CALL); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_RIGHT); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_LEFT); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_PRO_AMBIENT_SOUND_TONE); + addPreferenceHandlerFor(PREFS_NOISE_CONTROL_WITH_ONE_EARBUD); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_AMBIENT_MODE); + addPreferenceHandlerFor(PREFS_GALAXY_BUDS_SEAMLESS_CONNECTION); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH); + addPreferenceHandlerFor(PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH); addPreferenceHandlerFor(PREF_SONY_AMBIENT_SOUND_CONTROL); addPreferenceHandlerFor(PREF_SONY_FOCUS_VOICE); @@ -731,7 +747,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp } if (deviceSpecificSettingsCustomizer != null) { - deviceSpecificSettingsCustomizer.customizeSettings(this); + deviceSpecificSettingsCustomizer.customizeSettings(this, prefs); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java index 2149a3d97..c26965570 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java @@ -1,26 +1,14 @@ package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; -import android.app.Activity; -import android.content.Context; -import android.net.Uri; - import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; -import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; -import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; -import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; -public class GalaxyBudsDeviceCoordinator extends AbstractDeviceCoordinator { +public class GalaxyBudsDeviceCoordinator extends GalaxyBudsGenericCoordinator { @NonNull @Override @@ -53,100 +41,6 @@ public class GalaxyBudsDeviceCoordinator extends AbstractDeviceCoordinator { return new BatteryConfig[]{battery1, battery2}; } - @Override - public int getBondingStyle() { - return BONDING_STYLE_BOND; - } - - @Nullable - @Override - public Class getPairingActivity() { - return null; - } - - @Override - public boolean supportsActivityDataFetching() { - return false; - } - - @Override - public boolean supportsActivityTracking() { - return false; - } - - @Override - public SampleProvider getSampleProvider(GBDevice - device, DaoSession session) { - return null; - } - - @Override - public InstallHandler findInstallHandler(Uri uri, Context context) { - return null; - } - - @Override - public boolean supportsScreenshots() { - return false; - } - - @Override - public int getAlarmSlotCount() { - return 0; - } - - @Override - public boolean supportsSmartWakeup(GBDevice device) { - return false; - } - - @Override - public boolean supportsHeartRateMeasurement(GBDevice device) { - return false; - } - - @Override - public String getManufacturer() { - return "Samsung"; - } - - @Override - public boolean supportsAppsManagement() { - return false; - } - - @Override - public Class getAppsManagementActivity() { - return null; - } - - @Override - public boolean supportsCalendarEvents() { - return false; - } - - @Override - public boolean supportsRealtimeData() { - return false; - } - - @Override - public boolean supportsWeather() { - return false; - } - - @Override - public boolean supportsFindDevice() { - return true; - } - - @Override - protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device - device, @NonNull DaoSession session) throws GBException { - - } - - @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsGenericCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsGenericCoordinator.java new file mode 100644 index 000000000..78400c621 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsGenericCoordinator.java @@ -0,0 +1,114 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; + +import android.app.Activity; +import android.content.Context; +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import nodomain.freeyourgadget.gadgetbridge.GBException; +import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; +import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.Device; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; + +public abstract class GalaxyBudsGenericCoordinator extends AbstractDeviceCoordinator { + + @Override + public int getBondingStyle() { + return BONDING_STYLE_BOND; + } + + @Nullable + @Override + public Class getPairingActivity() { + return null; + } + + @Override + public boolean supportsActivityDataFetching() { + return false; + } + + @Override + public boolean supportsActivityTracking() { + return false; + } + + @Override + public SampleProvider getSampleProvider(GBDevice + device, DaoSession session) { + return null; + } + + @Override + public InstallHandler findInstallHandler(Uri uri, Context context) { + return null; + } + + @Override + public boolean supportsScreenshots() { + return false; + } + + @Override + public int getAlarmSlotCount() { + return 0; + } + + @Override + public boolean supportsSmartWakeup(GBDevice device) { + return false; + } + + @Override + public boolean supportsHeartRateMeasurement(GBDevice device) { + return false; + } + + @Override + public String getManufacturer() { + return "Samsung"; + } + + @Override + public boolean supportsAppsManagement() { + return false; + } + + @Override + public Class getAppsManagementActivity() { + return null; + } + + @Override + public boolean supportsCalendarEvents() { + return false; + } + + @Override + public boolean supportsRealtimeData() { + return false; + } + + @Override + public boolean supportsWeather() { + return false; + } + + @Override + public boolean supportsFindDevice() { + return true; + } + + @Override + protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device + device, @NonNull DaoSession session) throws GBException { + + } + +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java index 1b1f85b67..5d9cff134 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java @@ -1,26 +1,14 @@ package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; -import android.app.Activity; -import android.content.Context; -import android.net.Uri; - import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; -import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; -import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; -import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; -public class GalaxyBudsLiveDeviceCoordinator extends AbstractDeviceCoordinator { +public class GalaxyBudsLiveDeviceCoordinator extends GalaxyBudsGenericCoordinator { @NonNull @Override @@ -54,99 +42,6 @@ public class GalaxyBudsLiveDeviceCoordinator extends AbstractDeviceCoordinator { return new BatteryConfig[]{battery1, battery2, battery3}; } - @Override - public int getBondingStyle() { - return BONDING_STYLE_BOND; - } - - @Nullable - @Override - public Class getPairingActivity() { - return null; - } - - @Override - public boolean supportsActivityDataFetching() { - return false; - } - - @Override - public boolean supportsActivityTracking() { - return false; - } - - @Override - public SampleProvider getSampleProvider(GBDevice - device, DaoSession session) { - return null; - } - - @Override - public InstallHandler findInstallHandler(Uri uri, Context context) { - return null; - } - - @Override - public boolean supportsScreenshots() { - return false; - } - - @Override - public int getAlarmSlotCount() { - return 0; - } - - @Override - public boolean supportsSmartWakeup(GBDevice device) { - return false; - } - - @Override - public boolean supportsHeartRateMeasurement(GBDevice device) { - return false; - } - - @Override - public String getManufacturer() { - return "Samsung"; - } - - @Override - public boolean supportsAppsManagement() { - return false; - } - - @Override - public Class getAppsManagementActivity() { - return null; - } - - @Override - public boolean supportsCalendarEvents() { - return false; - } - - @Override - public boolean supportsRealtimeData() { - return false; - } - - @Override - public boolean supportsWeather() { - return false; - } - - @Override - public boolean supportsFindDevice() { - return true; - } - - @Override - protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device - device, @NonNull DaoSession session) throws GBException { - - } - @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java new file mode 100644 index 000000000..f3966a285 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java @@ -0,0 +1,57 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; + +import androidx.annotation.NonNull; + +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; +import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesSettingsCustomizer; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; + +public class GalaxyBudsProDeviceCoordinator extends GalaxyBudsGenericCoordinator { + + @NonNull + @Override + public DeviceType getSupportedType(GBDeviceCandidate candidate) { + + String name = candidate.getName(); + + if (name != null && ( + name.startsWith("Galaxy Buds Pro (") + )) { + return DeviceType.GALAXY_BUDS_PRO; + } + return DeviceType.UNKNOWN; + } + + @Override + public DeviceSpecificSettingsCustomizer getDeviceSpecificSettingsCustomizer(final GBDevice device) { + return new GalaxyBudsSettingsCustomizer(device); + } + @Override + public DeviceType getDeviceType() { + return DeviceType.GALAXY_BUDS_PRO; + } + + @Override + public int getBatteryCount() { + return 3; + } + + @Override + public BatteryConfig[] getBatteryConfig() { + BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_buds_pro_case, R.string.battery_case); + BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_buds_pro_left, R.string.left_earbud); + BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_buds_pro_right, R.string.right_earbud); + return new BatteryConfig[]{battery1, battery2, battery3}; + } + + @Override + public int[] getSupportedDeviceSpecificSettings(GBDevice device) { + return new int[]{ + R.xml.devicesettings_galaxy_buds_pro, + }; + } +} \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java new file mode 100644 index 000000000..29a5d20e7 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsSettingsCustomizer.java @@ -0,0 +1,241 @@ +/* Copyright (C) 2021 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds; + +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOLUME; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_ANC_LEVEL; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_BALANCE; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_NOISE_CONTROL; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_RIGHT; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH; + +import android.os.Parcel; + +import androidx.preference.Preference; + +import java.util.Collections; +import java.util.Set; + +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; + +public class GalaxyBudsSettingsCustomizer implements DeviceSpecificSettingsCustomizer { + + final GBDevice device; + + public GalaxyBudsSettingsCustomizer(final GBDevice device) { + this.device = device; + } + + @Override + public void onPreferenceChange(final Preference preference, final DeviceSpecificSettingsHandler handler) { + } + + @Override + public void customizeSettings(final DeviceSpecificSettingsHandler handler, Prefs prefs) { + + final Preference pref_galaxy_buds_pro_balance = handler.findPreference(PREF_GALAXY_BUDS_PRO_BALANCE); + if (pref_galaxy_buds_pro_balance != null) { + pref_galaxy_buds_pro_balance.setSummary(String.valueOf((prefs.getInt(PREF_GALAXY_BUDS_PRO_BALANCE, 16) - 16))); + + pref_galaxy_buds_pro_balance.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + String newValue = String.valueOf((int) newVal - 16); + pref_galaxy_buds_pro_balance.setSummary(newValue); + handler.notifyPreferenceChanged(PREF_GALAXY_BUDS_PRO_BALANCE); + return true; + } + }); + } + + final Preference pref_galaxy_buds_pro_noise_control = handler.findPreference(PREF_GALAXY_BUDS_PRO_NOISE_CONTROL); + String pref_galaxy_buds_pro_noise_control_value = prefs.getString(PREF_GALAXY_BUDS_PRO_NOISE_CONTROL, "0"); + final Preference pref_galaxy_buds_pro_anc_level = handler.findPreference(PREF_GALAXY_BUDS_PRO_ANC_LEVEL); + final Preference pref_galaxy_buds_ambient_volume = handler.findPreference(PREF_GALAXY_BUDS_AMBIENT_VOLUME); + + if (pref_galaxy_buds_pro_noise_control != null) { + + switch (pref_galaxy_buds_pro_noise_control_value) { + case "0": + pref_galaxy_buds_pro_anc_level.setEnabled(false); + pref_galaxy_buds_ambient_volume.setEnabled(false); + break; + case "1": + pref_galaxy_buds_pro_anc_level.setEnabled(true); + pref_galaxy_buds_ambient_volume.setEnabled(false); + break; + case "2": + pref_galaxy_buds_pro_anc_level.setEnabled(false); + pref_galaxy_buds_ambient_volume.setEnabled(true); + break; + } + + pref_galaxy_buds_pro_noise_control.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + handler.notifyPreferenceChanged(PREF_GALAXY_BUDS_PRO_NOISE_CONTROL); + switch (newVal.toString()) { + case "0": + pref_galaxy_buds_pro_anc_level.setEnabled(false); + pref_galaxy_buds_ambient_volume.setEnabled(false); + break; + case "1": + pref_galaxy_buds_pro_anc_level.setEnabled(true); + pref_galaxy_buds_ambient_volume.setEnabled(false); + break; + case "2": + pref_galaxy_buds_pro_anc_level.setEnabled(false); + pref_galaxy_buds_ambient_volume.setEnabled(true); + break; + } + + return true; + } + }); + } + + + final Preference pref_galaxy_buds_touch_right = handler.findPreference(PREF_GALAXY_BUDS_TOUCH_RIGHT); + String pref_galaxy_buds_touch_right_value = prefs.getString(PREF_GALAXY_BUDS_TOUCH_RIGHT, "1"); + final Preference pref_galaxy_buds_touch_right_switch = handler.findPreference(PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH); + + if (pref_galaxy_buds_touch_right != null) { + + switch (pref_galaxy_buds_touch_right_value) { + case "2": + pref_galaxy_buds_touch_right_switch.setEnabled(true); + break; + default: + pref_galaxy_buds_touch_right_switch.setEnabled(false); + } + + pref_galaxy_buds_touch_right.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + handler.notifyPreferenceChanged(PREF_GALAXY_BUDS_TOUCH_RIGHT); + switch (newVal.toString()) { + case "2": + pref_galaxy_buds_touch_right_switch.setEnabled(true); + break; + default: + pref_galaxy_buds_touch_right_switch.setEnabled(false); + + } + + return true; + } + }); + } + + final Preference pref_galaxy_buds_touch_left = handler.findPreference(PREF_GALAXY_BUDS_TOUCH_LEFT); + String pref_galaxy_buds_touch_left_value = prefs.getString(PREF_GALAXY_BUDS_TOUCH_LEFT, "1"); + final Preference pref_galaxy_buds_touch_left_switch = handler.findPreference(PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH); + + if (pref_galaxy_buds_touch_left != null) { + + switch (pref_galaxy_buds_touch_left_value) { + case "2": + pref_galaxy_buds_touch_left_switch.setEnabled(true); + break; + default: + pref_galaxy_buds_touch_left_switch.setEnabled(false); + } + + pref_galaxy_buds_touch_left.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + handler.notifyPreferenceChanged(PREF_GALAXY_BUDS_TOUCH_LEFT); + switch (newVal.toString()) { + case "2": + pref_galaxy_buds_touch_left_switch.setEnabled(true); + break; + default: + pref_galaxy_buds_touch_left_switch.setEnabled(false); + + } + + return true; + } + }); + } + + +/* + final Preference pref_galaxy_buds_ambient_mode = handler.findPreference(PREF_GALAXY_BUDS_AMBIENT_SOUND); + boolean is_pref_galaxy_buds_ambient_mode_enabled = prefs.getBoolean(PREF_GALAXY_BUDS_AMBIENT_SOUND, false); + final Preference pref_galaxy_buds_ambient_voice_focus_preference = handler.findPreference(PREF_GALAXY_BUDS_AMBIENT_VOICE_FOCUS_PREFERENCE); + + if (pref_galaxy_buds_ambient_mode != null) { + if (is_pref_galaxy_buds_ambient_mode_enabled) { + pref_galaxy_buds_ambient_voice_focus_preference.setEnabled(true); + } else { + pref_galaxy_buds_ambient_voice_focus_preference.setEnabled(false); + } + + + pref_galaxy_buds_ambient_mode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + handler.notifyPreferenceChanged(PREF_GALAXY_BUDS_AMBIENT_SOUND); + if ((boolean) newVal) { + pref_galaxy_buds_ambient_voice_focus_preference.setEnabled(true); + } else { + pref_galaxy_buds_ambient_voice_focus_preference.setEnabled(false); + } + + return true; + } + }); + } + + */ + } + + @Override + public Set getPreferenceKeysWithSummary() { + return Collections.emptySet(); + } + + + public static final Creator CREATOR = new Creator() { + @Override + public GalaxyBudsSettingsCustomizer createFromParcel(final Parcel in) { + final GBDevice device = in.readParcelable(GalaxyBudsSettingsCustomizer.class.getClassLoader()); + return new GalaxyBudsSettingsCustomizer(device); + } + + @Override + public GalaxyBudsSettingsCustomizer[] newArray(final int size) { + return new GalaxyBudsSettingsCustomizer[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(final Parcel dest, final int flags) { + dest.writeParcelable(device, 0); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java index fef6626d2..566283399 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiSettingsCustomizer.java @@ -18,7 +18,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.huami; import android.os.Parcel; import android.text.InputType; -import android.widget.Toast; import androidx.preference.Preference; @@ -31,6 +30,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpec import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class HuamiSettingsCustomizer implements DeviceSpecificSettingsCustomizer { final GBDevice device; @@ -45,7 +45,7 @@ public class HuamiSettingsCustomizer implements DeviceSpecificSettingsCustomizer } @Override - public void customizeSettings(final DeviceSpecificSettingsHandler handler) { + public void customizeSettings(final DeviceSpecificSettingsHandler handler, Prefs prefs) { for (HuamiVibrationPatternNotificationType notificationType : HuamiVibrationPatternNotificationType.values()) { final String typeKey = notificationType.name().toLowerCase(Locale.ROOT); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java index 0a8eb477d..7744b4a15 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesSettingsCustomizer.java @@ -59,6 +59,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.Ambien import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.protocol.impl.v1.params.NoiseCancellingOptimizerStatus; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsCustomizer { private ProgressDialog ancOptimizerProgressDialog; @@ -116,7 +117,7 @@ public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsC } @Override - public void customizeSettings(final DeviceSpecificSettingsHandler handler) { + public void customizeSettings(final DeviceSpecificSettingsHandler handler, Prefs prefs) { // Only enable the focus on voice check and voice level slider if the ambient sound control mode is ambient sound final ListPreference ambientSoundControl = handler.findPreference(PREF_SONY_AMBIENT_SOUND_CONTROL); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index c2d7a780a..f9bacf8fe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -103,6 +103,7 @@ public enum DeviceType { UM25(350, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_um25), DOMYOS_T540(400, R.drawable.ic_device_lovetoy, R.drawable.ic_device_lovetoy_disabled, R.string.devicetype_domyos_t540), NOTHING_EAR1(410, R.drawable.ic_device_nothingear, R.drawable.ic_device_nothingear_disabled, R.string.devicetype_nothingear1), + GALAXY_BUDS_PRO(418, R.drawable.ic_device_galaxy_buds_pro, R.drawable.ic_device_galaxy_buds_pro_disabled, R.string.devicetype_galaxybuds_pro), GALAXY_BUDS_LIVE(419, R.drawable.ic_device_galaxy_buds_live, R.drawable.ic_device_galaxy_buds_live_disabled, R.string.devicetype_galaxybuds_live), GALAXY_BUDS(420, R.drawable.ic_device_galaxy_buds, R.drawable.ic_device_galaxy_buds_disabled, R.string.devicetype_galaxybuds), SONY_WH_1000XM3(430, R.drawable.ic_device_sony_overhead, R.drawable.ic_device_sony_overhead_disabled, R.string.devicetype_sony_wh_1000xm3), diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java index 420d558de..0172aef6c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java @@ -380,6 +380,9 @@ public class DeviceSupportFactory { case GALAXY_BUDS_LIVE: deviceSupport = new ServiceDeviceSupport(new GalaxyBudsDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; + case GALAXY_BUDS_PRO: + deviceSupport = new ServiceDeviceSupport(new GalaxyBudsDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); + break; case SONY_WH_1000XM3: deviceSupport = new ServiceDeviceSupport(new SonyHeadphonesSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsIOThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsIOThread.java index 7d8aca91d..22dfbb3e7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsIOThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsIOThread.java @@ -31,7 +31,8 @@ public class GalaxyBudsIOThread extends BtClassicIoThread { if (gbDevice.getType().equals(DeviceType.GALAXY_BUDS)) { return galaxyBudsProtocol.UUID_GALAXY_BUDS_DEVICE_CTRL; } - if (gbDevice.getType().equals(DeviceType.GALAXY_BUDS_LIVE)) { + if (gbDevice.getType().equals(DeviceType.GALAXY_BUDS_LIVE) + || gbDevice.getType().equals(DeviceType.GALAXY_BUDS_PRO)) { return galaxyBudsProtocol.UUID_GALAXY_BUDS_LIVE_DEVICE_CTRL; } return galaxyBudsProtocol.UUID_GALAXY_BUDS_DEVICE_CTRL; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsProtocol.java index aaa2a2a4b..cfde9aa50 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/galaxy_buds/GalaxyBudsProtocol.java @@ -8,6 +8,8 @@ import android.content.SharedPreferences; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; @@ -16,7 +18,6 @@ import java.util.List; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; @@ -32,18 +33,19 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { final UUID UUID_GALAXY_BUDS_DEVICE_CTRL = UUID.fromString("00001102-0000-1000-8000-00805f9b34fd"); final UUID UUID_GALAXY_BUDS_LIVE_DEVICE_CTRL = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); - private static final byte SOMBuds = (byte) 0xFE; - private static final byte EOMBuds = (byte) 0xEE; - private static final byte SOMPlus = (byte) 0xFD; - private static final byte EOMPlus = (byte) 0xDD; + private static final byte SOM_BUDS = (byte) 0xFE; + private static final byte EOM_BUDS = (byte) 0xEE; + private static final byte SOM_BUDS_PLUS = (byte) 0xFD; + private static final byte EOM_BUDS_PLUS = (byte) 0xDD; - private byte SOM = SOMBuds; - private byte EOM = EOMBuds; + private byte StartOfMessage = SOM_BUDS; + private byte EndOfMessage = EOM_BUDS; private boolean isFirstExchange = true; //incoming private static final byte battery_status = (byte) 0x60; + private static final byte battery_status2 = (byte) 0x61; //outgoing @@ -52,11 +54,14 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { private static final byte set_ambient_mode = (byte) 0x80; //0x0/0x1 private static final byte set_ambient_volume = (byte) 0x84; // 0x1-0x5 + private static final byte set_ambient_voice_focus = (byte) 0x85; // 0x0/0x1 private static final byte set_lock_touch = (byte) 0x90; // 0x0/0x1 - private static final byte set_game_mode = (byte) 0x87; // 0x0/0x2 no idea if this is doing anything - private static final byte set_equalizer = (byte) 0x86; // 0x0/0x1 + private static final byte set_game_mode = (byte) 0x87; // 0x0/0x2 no idea if this is doing anything... + // this is sent dynamically based on whether the current running app is a game or not + + private static final byte set_equalizer = (byte) 0x86; private static final byte set_reset = (byte) 0x50; @@ -69,9 +74,86 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { //Live private static final byte set_automatic_noise_cancelling = (byte) 0x98; //0x0/0x1 - private static final byte set_live_game_mode = (byte) 0x85; // 0x0/0x1 no idea if this is doing anything private static final byte set_pressure_relief = (byte) 0x9f; //0x0/0x1 + //Live and Pro + private static final byte set_live_pro_game_mode = (byte) 0x85; // 0x0/0x1 no idea if this is doing anything + + //Pro + // Comments thanks to phh as per https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/2642#issuecomment-445962 + + private static final byte set_spatial_audio_control = (byte) 0xc3; //0x0/0x1 + // takes a boolean '1' or '0' to enable or disable 360 Audio (probably useless until someone + // manage to send Dolby Atmos to the headset). 360 audio is a feature where (Shown only on Samsung rom) + + private static final byte set_outside_double_tap = (byte) 0x95; //0x0/0x1 + // This is an option in "Labs", to detect double tap even when not taped on touch pad (so I presume it's using accelerometer) + + private static final byte set_adjust_sound_sync = (byte) 0x85; //0x0/0x1 + // This is an option in "Labs" available only on Samsung ROM, exposed to the user as "automatic game mode". + // This is used in confunction with GAME_MODE. My guess is that this says to the ear buds + // "yes, I know that the reported latency might change on the fly, I'm fine with that". + + private static final byte set_detect_conversations = (byte) 0x7a; //0x0/0x1 + // This is called "Voice detect -- Noise controls and sound settings go back to the previous state + // when your voice isn't detected for 10 seconds". This triggers the feature that when you talk, + // the ear buds automatically go into "ambient sound" mode, and enhance the sound of your interlocutor + + private static final byte set_detect_conversations_duration = (byte) 0x7b; //0x0/0x1/0x2 + // Takes {0,1,2}: 0 means 5 seconds, 1 means 10 seconds, 2 means 15s. This is the duration after + // which the ear buds go back to ANC after switching to ambient sound when the user talks. + + private static final byte set_ambient_mode_during_calls = (byte) 0x8b; //0x0/0x1 + // "Use ambient sound during calls" + + private static final byte set_noise_controls_with_one_earbud = (byte) 0x6f; //0x0/0x1 + // "Noise controls with one earbud" in Accessibility menu. I'm not exactly sure what it means, + // my guess is that it allows ANC even if only one earbuds is in-ear + + private static final byte set_balance = (byte) 0x8f; + // takes value in 0-32 range, it is used to change left/right balance + + private static final byte extra_high_ambient = (byte) 0x96; //0x0/0x1 + // "Maximize ambient sound volume"/"Amplify sounds from your surroundings so you can stay aware of what's going on around you. + + private static final byte set_seamless_connection = (byte) 0xaf; //0x0/0x1 + // It is used to allow the ear buds to roam across devices, like devices being allowed to take ear buds "focus". + + private static final byte set_voice_wake_up = (byte) 0x97; //0x0/0x1 + // Enables "Hey Bixby" wake up word. Shown only on Samsung ROM + + private static final byte set_speak_seamlessly = (byte) 0x7d; //0x0/0x1 + // "After Voice wake up, you can say the command you want right away without waiting for sound feedback." + + private static final byte voice_wake_up_language = (byte) 0x99; + // Language for "Hey bixby" wakeup - 1 = "de-DE", 2 = "en-GB", 3 = "en-US", 4 = "es-ES", 5 = "fr-FR", 6 = "it-IT", 7 = "ko-KR", 8 = "pt-BR", 9 = "zh-CN" + + private static final byte set_voice_noti_status = (byte) 0xa4; //0x0/0x1 + // I have no idea why it does that. It sends "1" when it starts reading notification aloud, and "0" when it finished. + + private static final byte set_noise_controls = (byte) 0x78; //Takes 0/1/2. + // 0 is Ambient Sound and ANC OFF, 1 is ANC on, 2 is Ambient sound ON + + private static final byte set_mute_earbud = (byte) 0xa2; + // Takes two booleans (left then right). This is used in conjuction with FIND_MY_EARBUDS_START to alternate between tweeting the left and the right earbud + + private static final byte set_customize_ambient_sound = (byte) 0x82; + //one byte for left volume 0-4, one byte for right volume 0-4, and one byte 0-4 for ambient sound tone from "soft" to "clear" + + private static final byte set_noise_reduction_level = (byte) 0x83; + // 1 means High noise reduction, 0 low noise reduction. + + private static final byte set_touch_and_hold_noise_controls = (byte) 0x79; + // Takes either 3 booleans or 6 booleans depending on earbuds revision. + // It is used when long press on touchpad is set in SET_TOUCHPAD_OPTION to "Switch noise control", + // to control whether the long press switches between ANC on <=> Ambient sound on, or to anc+ambient off, + // or ambient <=> off or anc <=> off, and when it's 6 bytes, it can have different behavior between right and left earbud. + + private static final byte voice_wake_up_event = (byte) 0x9a; + // Just a reponse. It's a ACK for when received "Hey bixby" command ? + + private static final byte in_ear_detection = (byte) 0x6e; + @Override public GBDeviceEvent[] decodeResponse(byte[] responseData) { List devEvts = new ArrayList<>(); @@ -90,12 +172,12 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { byte type = 0; byte sof = incoming.get(); - if (sof != SOM) { + if (sof != StartOfMessage) { LOG.error("Error in message, wrong start of frame: " + hexdump(responseData)); return null; } - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { length = (int) (incoming.get() & 0xff); type = incoming.get(); } else { @@ -130,9 +212,9 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { byte[] encodeMessage(byte command) { ByteBuffer msgBuf = ByteBuffer.allocate(7); msgBuf.order(ByteOrder.LITTLE_ENDIAN); - msgBuf.put(SOM); + msgBuf.put(StartOfMessage); byte size = 0x3; - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { msgBuf.put((byte) size); msgBuf.put((byte) 0x0); //0x0 for sending } else { @@ -141,7 +223,7 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { } msgBuf.put((byte) command); //command id msgBuf.putShort((short) crc16_ccitt(new byte[]{command})); - msgBuf.put(EOM); + msgBuf.put(EndOfMessage); LOG.debug("DEBUG: " + hexdump(msgBuf.array())); return msgBuf.array(); } @@ -149,9 +231,9 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { byte[] encodeMessage(byte command, byte parameter) { ByteBuffer msgBuf = ByteBuffer.allocate(8); msgBuf.order(ByteOrder.LITTLE_ENDIAN); - msgBuf.put(SOM); + msgBuf.put(StartOfMessage); byte size = 0x4; - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { msgBuf.put((byte) size); msgBuf.put((byte) 0x0); //0x0 for sending } else { @@ -161,7 +243,7 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { msgBuf.put((byte) command); //command id msgBuf.put((byte) parameter); msgBuf.putShort((short) crc16_ccitt(new byte[]{command, parameter})); - msgBuf.put(EOM); + msgBuf.put(EndOfMessage); LOG.debug("DEBUG: " + hexdump(msgBuf.array())); return msgBuf.array(); } @@ -169,9 +251,9 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { byte[] encodeMessage(byte command, byte parameter, byte value) { ByteBuffer msgBuf = ByteBuffer.allocate(9); msgBuf.order(ByteOrder.LITTLE_ENDIAN); - msgBuf.put(SOM); + msgBuf.put(StartOfMessage); byte size = 0x5; - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { msgBuf.put((byte) size); msgBuf.put((byte) 0x0); //0x0 for sending } else { @@ -182,11 +264,43 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { msgBuf.put((byte) parameter); msgBuf.put((byte) value); msgBuf.putShort((short) crc16_ccitt(new byte[]{command, parameter, value})); - msgBuf.put(EOM); + msgBuf.put(EndOfMessage); LOG.debug("DEBUG: " + hexdump(msgBuf.array())); return msgBuf.array(); } + byte[] encodeMessage(byte command, byte[] payload) { + byte payload_size = (byte) (3 + payload.length); + ByteBuffer msgBuf = ByteBuffer.allocate(4 + payload_size); + msgBuf.order(ByteOrder.LITTLE_ENDIAN); + msgBuf.put(StartOfMessage); + + if (StartOfMessage == SOM_BUDS_PLUS) { + msgBuf.put((byte) payload_size); + msgBuf.put((byte) 0x0); //0x0 for sending + } else { + msgBuf.put((byte) 0x0); //0x0 for sending + msgBuf.put((byte) payload_size); //size + } + msgBuf.put((byte) command); + msgBuf.put(payload); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + try { + outputStream.write(command); + outputStream.write(payload); + } catch (IOException e) { + LOG.warn("Assembling message failed: " + e.getMessage()); + } + + msgBuf.putShort((short) crc16_ccitt(outputStream.toByteArray())); + msgBuf.put(EndOfMessage); + LOG.debug("DEBUG: " + hexdump(msgBuf.array())); + return msgBuf.array(); + } + + @Override public byte[] encodeFindDevice(boolean start) { byte command = (byte) (start ? find_device_start : find_device_stop); @@ -213,23 +327,76 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); switch (config) { + case DeviceSettingsPreferenceConst.PREF_GALAXY_PRO_DOUBLE_TAP_EDGE: + byte outside_double_tap = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_PRO_DOUBLE_TAP_EDGE, false) ? 0x01 : 0x00); + return encodeMessage(set_outside_double_tap, outside_double_tap); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_VOICE_DETECT: + byte detect_conversations = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_VOICE_DETECT, false) ? 0x01 : 0x00); + return encodeMessage(set_detect_conversations, detect_conversations); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_VOICE_DETECT_DURATION: + String voice_detect_duration = prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_VOICE_DETECT_DURATION, "1"); + byte voice_detect_duration_b = (byte) Integer.parseInt(voice_detect_duration); + return encodeMessage(set_detect_conversations_duration, voice_detect_duration_b); + + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_MODE_DURING_CALL: + byte ambient_mode_during_calls = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_MODE_DURING_CALL, false) ? 0x01 : 0x00); + return encodeMessage(set_ambient_mode_during_calls, ambient_mode_during_calls); + + case DeviceSettingsPreferenceConst.PREFS_NOISE_CONTROL_WITH_ONE_EARBUD: + byte noise_controls_with_one_earbud = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREFS_NOISE_CONTROL_WITH_ONE_EARBUD, false) ? 0x01 : 0x00); + return encodeMessage(set_noise_controls_with_one_earbud, noise_controls_with_one_earbud); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_IN_EAR_DETECTION: + byte ear_detection = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_IN_EAR_DETECTION, false) ? 0x01 : 0x00); + return encodeMessage(in_ear_detection, ear_detection); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_BALANCE: + int hearing_enhancements = prefs.getInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_BALANCE, 16); + return encodeMessage(set_balance, (byte) hearing_enhancements); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_NOISE_CONTROL: + int noise_controls = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_NOISE_CONTROL, "0")); + return encodeMessage(set_noise_controls, (byte) noise_controls); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_ANC_LEVEL: + int anc_level = Integer.parseInt(prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_ANC_LEVEL, "0")); + return encodeMessage(set_noise_reduction_level, (byte) anc_level); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_SOUND: + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_RIGHT: + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_LEFT: + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_SOUND_TONE: + byte ambient_sound = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_SOUND, true) ? (byte) 1 : (byte) 0; + int ambient_right = prefs.getInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_RIGHT, 1); + int ambient_left = prefs.getInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_VOLUME_LEFT, 1); + int sound_tone = prefs.getInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_PRO_AMBIENT_SOUND_TONE, 1); + return encodeMessage(set_customize_ambient_sound, new byte[]{ambient_sound, (byte) ambient_left, (byte) ambient_right, (byte) sound_tone}); + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_MODE: byte enable_ambient = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_MODE, false) ? 0x01 : 0x00); return encodeMessage(set_ambient_mode, enable_ambient); + + case DeviceSettingsPreferenceConst.PREFS_GALAXY_BUDS_SEAMLESS_CONNECTION: + byte seamless_switch = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREFS_GALAXY_BUDS_SEAMLESS_CONNECTION, false) ? 0x01 : 0x00); + return encodeMessage(set_seamless_connection, seamless_switch); + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOICE_FOCUS: byte enable_voice = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOICE_FOCUS, false) ? 0x01 : 0x00); return encodeMessage(set_ambient_voice_focus, enable_voice); case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOLUME: int ambient_volume = prefs.getInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOLUME, 0); - byte ambient_volume_byte = (byte) (ambient_volume + 1); //seek bar is 0-4, we need 1-5 + byte ambient_volume_byte = (byte) (ambient_volume); return encodeMessage(set_ambient_volume, ambient_volume_byte); case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_LOCK_TOUCH: byte set_lock = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_LOCK_TOUCH, false) ? 0x01 : 0x00); return encodeMessage(set_lock_touch, set_lock); case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_GAME_MODE: - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { byte game_mode = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_GAME_MODE, false) ? 0x1 : 0x00); - return encodeMessage(set_live_game_mode, game_mode); + return encodeMessage(set_live_pro_game_mode, game_mode); } else { byte game_mode = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_GAME_MODE, false) ? 0x2 : 0x00); return encodeMessage(set_game_mode, game_mode); @@ -246,7 +413,7 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { } String equalizer_mode = prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_EQUALIZER_MODE, "0"); - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { return encodeMessage(set_equalizer, (byte) (Integer.parseInt(equalizer_mode))); } else { byte mode = (byte) (Integer.parseInt(equalizer_mode) + dolby); @@ -261,6 +428,22 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { byte touchmode_right = (byte) Integer.parseInt(touch_right); return encodeMessage(set_touchpad_options, touchmode_left, touchmode_right); + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH: + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH: + String touch_right_switch = prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH, "1"); + String touch_left_switch = prefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH, "1"); + byte[] touch_right_switch_b = encode_touch_switch(touch_right_switch); + byte[] touch_left_switch_b = encode_touch_switch(touch_left_switch); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try { + outputStream.write(touch_left_switch_b); + outputStream.write(touch_right_switch_b); + } catch (IOException e) { + LOG.warn("Assembling message failed: " + e.getMessage()); + } + return encodeMessage(set_touch_and_hold_noise_controls, outputStream.toByteArray()); + + case DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_LIVE_ANC: byte enable_anc = (byte) (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_LIVE_ANC, false) ? 0x1 : 0x00); return encodeMessage(set_automatic_noise_cancelling, enable_anc); @@ -304,7 +487,7 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { deviceEvents.add(evBattery2); - if (SOM == SOMPlus) { + if (StartOfMessage == SOM_BUDS_PLUS) { GBDeviceEventBatteryInfo evBattery3 = new GBDeviceEventBatteryInfo(); // reorder for the non OG version evBattery1.batteryIndex = 1; //left @@ -320,11 +503,23 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol { return deviceEvents; } + private byte[] encode_touch_switch(String input) { + switch (input) { + case "1": + return new byte[]{0x1, 0x0, 0x1}; + case "2": + return new byte[]{0x0, 0x1, 0x1}; + default: + return new byte[]{0x1, 0x1, 0x0}; + } + } + protected GalaxyBudsProtocol(GBDevice device) { super(device); - if (device.getType().equals(DeviceType.GALAXY_BUDS_LIVE)) { - SOM = SOMPlus; - EOM = EOMPlus; + if (device.getType().equals(DeviceType.GALAXY_BUDS_LIVE) + || device.getType().equals(DeviceType.GALAXY_BUDS_PRO)) { + StartOfMessage = SOM_BUDS_PLUS; + EndOfMessage = EOM_BUDS_PLUS; } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java index eb0429c84..3328e952c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java @@ -51,6 +51,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.casio.gbx100.CasioGBX100Devi import nodomain.freeyourgadget.gadgetbridge.devices.domyos.DomyosT540Cooridnator; import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBudsDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBudsLiveDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBudsProDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.EXRIZUK8Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.MakibesF68Coordinator; @@ -323,6 +324,7 @@ public class DeviceHelper { result.add(new Ear1Coordinator()); result.add(new GalaxyBudsDeviceCoordinator()); result.add(new GalaxyBudsLiveDeviceCoordinator()); + result.add(new GalaxyBudsProDeviceCoordinator()); result.add(new VescCoordinator()); result.add(new SonyWH1000XM3Coordinator()); result.add(new SonyWH1000XM4Coordinator()); diff --git a/app/src/main/res/drawable/ic_buds_pro_case.xml b/app/src/main/res/drawable/ic_buds_pro_case.xml new file mode 100644 index 000000000..769645bac --- /dev/null +++ b/app/src/main/res/drawable/ic_buds_pro_case.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/drawable/ic_buds_pro_left.xml b/app/src/main/res/drawable/ic_buds_pro_left.xml new file mode 100644 index 000000000..12af00c73 --- /dev/null +++ b/app/src/main/res/drawable/ic_buds_pro_left.xml @@ -0,0 +1,17 @@ + + + + diff --git a/app/src/main/res/drawable/ic_buds_pro_right.xml b/app/src/main/res/drawable/ic_buds_pro_right.xml new file mode 100644 index 000000000..0304040bb --- /dev/null +++ b/app/src/main/res/drawable/ic_buds_pro_right.xml @@ -0,0 +1,17 @@ + + + + diff --git a/app/src/main/res/drawable/ic_device_galaxy_buds_pro.xml b/app/src/main/res/drawable/ic_device_galaxy_buds_pro.xml new file mode 100644 index 000000000..4b5b21950 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_galaxy_buds_pro.xml @@ -0,0 +1,31 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_galaxy_buds_pro_disabled.xml b/app/src/main/res/drawable/ic_device_galaxy_buds_pro_disabled.xml new file mode 100644 index 000000000..9d9584b39 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_galaxy_buds_pro_disabled.xml @@ -0,0 +1,36 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_switch_right.xml b/app/src/main/res/drawable/ic_switch_right.xml new file mode 100644 index 000000000..3fbf74610 --- /dev/null +++ b/app/src/main/res/drawable/ic_switch_right.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 73cea0d25..aa3c82889 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1957,10 +1957,85 @@ 5 - + + 0 + 1 + 2 + + + + @string/off + @string/prefs_active_noise_cancelling + @string/prefs_ambient_sound + + + + 0 + 1 + + + + @string/prefs_active_noise_cancelling_level_low + @string/prefs_active_noise_cancelling_level_high + + + + + @string/pref_switch_noise_control + @string/pref_title_touch_voice_assistant + @string/pref_media_volumedown + @string/pref_title_touch_spotify + + + + @string/pref_switch_noise_control + @string/pref_title_touch_voice_assistant + @string/pref_media_volumeup + @string/pref_title_touch_spotify + + + + 2 + 1 + 3 + 4 + + + + @string/pref_switch_controls_anc_ambient + @string/pref_switch_controls_anc_off + @string/pref_switch_controls_ambient_off + + + + 0 + 1 + 2 + + + + @string/pref_voice_detect_duration_5 + @string/pref_voice_detect_duration_10 + @string/pref_voice_detect_duration_15 + + + + 0 + 1 + 2 + + + @string/pref_title_touch_voice_assistant @string/pref_title_touch_quick_ambient - @string/pref_title_touch_volume + @string/pref_media_volumedown + @string/pref_title_touch_ambient + + + + @string/pref_title_touch_voice_assistant + @string/pref_title_touch_quick_ambient + @string/pref_media_volumeup @string/pref_title_touch_ambient @@ -1971,10 +2046,16 @@ 3 - + @string/pref_title_touch_voice_assistant @string/pref_title_touch_anc - @string/pref_title_touch_volume + @string/pref_media_volumedown + + + + @string/pref_title_touch_voice_assistant + @string/pref_title_touch_anc + @string/pref_media_volumeup diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 29ca3d806..32f0ddada 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1411,8 +1411,10 @@ Nothing Ear (1) Galaxy Buds Galaxy Buds Live + Galaxy Buds Pro Play/pause the music depending if you wear the earbuds In-Ear detection + Play calls through your earbuds when they are in your ears Audio mode Equalizer Preset Normal @@ -1430,22 +1432,60 @@ Touch Lock Disable touch events Experimental + Seamless connection switch + Switches the buds between paired devices automatically Ambient volume + Ambient Volume Left + Ambient Volume Right Voice Focus Make voice stand out Ambient Sound + Customize Ambient Sound + Ambient Sound during call + Hear own voice during call Ambient Mode + Ambient Sound Options Active Noise Cancelling + Active Noise Cancelling Level + High + Low Block noises of the surroundings Pressure relief with ambient sound Prevent feeling of pressure in ears when not using Active Noise Cancelling Left Right + Switch control left + Switch control right Touch Options Battery case Left earbud Right earbud Audio Codec + Voice Assistant + Active Noise Cancelling + Quick Ambient Sound + Volume + Ambient Sound + Spotify + Switch Noise Control + Noise Control with one earbud + Allow noise control when using one earbud only + Ambient Sound Tone + From Soft to Clear + Balance + Noise cancelling ←→ Ambient + Noise cancelling ←→ Off + Ambient ←→ Off + Noise control + Voice detect + Enable Ambient sound and lower playback automatically after voice has been detected + Double tap edge + Detect double tap even when not taped on touch pad + End after quiet for: + 5 seconds + 10 seconds + 15 seconds + Ambient Sound Control Device Information Mode diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml index e71663e87..994aa41ee 100644 --- a/app/src/main/res/values/values.xml +++ b/app/src/main/res/values/values.xml @@ -113,11 +113,6 @@ FITNESS_CONTROL_START FITNESS_CONTROL_STOP FITNESS_CONTROL_TOGGLE - Voice Assistant - Active Noise Cancelling - Quick Ambient Sound - Volume - Ambient Sound system light diff --git a/app/src/main/res/xml/devicesettings_galaxy_buds.xml b/app/src/main/res/xml/devicesettings_galaxy_buds.xml index a86a87a72..a44eb570f 100644 --- a/app/src/main/res/xml/devicesettings_galaxy_buds.xml +++ b/app/src/main/res/xml/devicesettings_galaxy_buds.xml @@ -1,5 +1,6 @@ - + + android:max="5" + android:title="@string/prefs_ambient_volume" + app:min="1" + app:showSeekBarValue="true" /> @@ -75,7 +78,7 @@ android:title="@string/prefs_touch_lock" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 428af7f21e6001b778e393b40f7a3a77add2bb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sun, 15 May 2022 22:15:10 +0100 Subject: [PATCH 100/110] Huami/Mi Band: Move heart rate monitoring to device-specific settings --- .../gadgetbridge/GBApplication.java | 26 ++++++++++++++++++- .../DeviceSettingsPreferenceConst.java | 3 +++ .../DeviceSpecificSettingsFragment.java | 22 ++++++++++++++++ .../devices/huami/HuamiCoordinator.java | 5 ++++ .../amazfitband5/AmazfitBand5Coordinator.java | 1 + .../amazfitbip/AmazfitBipCoordinator.java | 1 + .../amazfitbip/AmazfitBipLiteCoordinator.java | 1 + .../amazfitbips/AmazfitBipSCoordinator.java | 1 + .../amazfitbipu/AmazfitBipUCoordinator.java | 1 + .../AmazfitBipUProCoordinator.java | 1 + .../amazfitcor/AmazfitCorCoordinator.java | 1 + .../amazfitcor2/AmazfitCor2Coordinator.java | 1 + .../amazfitgtr/AmazfitGTRCoordinator.java | 1 + .../amazfitgtr/AmazfitGTRLiteCoordinator.java | 1 + .../amazfitgtr2/AmazfitGTR2Coordinator.java | 1 + .../amazfitgtr2/AmazfitGTR2eCoordinator.java | 1 + .../amazfitgts/AmazfitGTSCoordinator.java | 1 + .../amazfitgts2/AmazfitGTS2Coordinator.java | 1 + .../AmazfitGTS2MiniCoordinator.java | 1 + .../amazfitgts2/AmazfitGTS2eCoordinator.java | 1 + .../amazfitneo/AmazfitNeoCoordinator.java | 1 + .../amazfittrex/AmazfitTRexCoordinator.java | 1 + .../AmazfitTRexProCoordinator.java | 1 + .../AmazfitVergeLCoordinator.java | 1 + .../huami/amazfitx/AmazfitXCoordinator.java | 1 + .../huami/miband2/MiBand2Coordinator.java | 1 + .../huami/miband2/MiBand2HRXCoordinator.java | 1 + .../huami/miband3/MiBand3Coordinator.java | 1 + .../huami/miband4/MiBand4Coordinator.java | 1 + .../huami/miband5/MiBand5Coordinator.java | 1 + .../huami/miband6/MiBand6Coordinator.java | 1 + .../devices/huami/zeppe/ZeppECoordinator.java | 1 + .../devices/miband/MiBandConst.java | 1 - .../devices/miband/MiBandCoordinator.java | 7 ++--- .../miband/MiBandPreferencesActivity.java | 19 -------------- .../service/devices/huami/HuamiSupport.java | 6 +---- app/src/main/res/values/strings.xml | 2 ++ .../xml/devicesettings_heartrate_sleep.xml | 25 ++++++++++++++++++ app/src/main/res/xml/miband_preferences.xml | 13 ---------- 39 files changed, 115 insertions(+), 42 deletions(-) create mode 100644 app/src/main/res/xml/devicesettings_heartrate_sleep.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index f746608d3..085370cb4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -117,7 +117,7 @@ public class GBApplication extends Application { private static SharedPreferences sharedPrefs; private static final String PREFS_VERSION = "shared_preferences_version"; //if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version - private static final int CURRENT_PREFS_VERSION = 13; + private static final int CURRENT_PREFS_VERSION = 14; private static LimitedQueue mIDSenderLookup = new LimitedQueue(16); private static Prefs prefs; @@ -1119,6 +1119,30 @@ public class GBApplication extends Application { } } + if (oldVersion < 14) { + try (DBHandler db = acquireDB()) { + final DaoSession daoSession = db.getDaoSession(); + final List activeDevices = DBHelper.getActiveDevices(daoSession); + + for (Device dbDevice : activeDevices) { + final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier()); + final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit(); + + if (DeviceType.MIBAND.equals(dbDevice.getType()) || dbDevice.getManufacturer().equals("Huami")) { + deviceSharedPrefsEdit.putBoolean("heartrate_sleep_detection", prefs.getBoolean("mi_hr_sleep_detection", false)); + deviceSharedPrefsEdit.putString("heartrate_measurement_interval", prefs.getString("heartrate_measurement_interval", "0")); + } + + // Not removing heartrate_measurement_interval since it's still used by some devices (ZeTime) + editor.remove("mi_hr_sleep_detection"); + + deviceSharedPrefsEdit.apply(); + } + } catch (Exception e) { + Log.w(TAG, "error acquiring DB lock"); + } + } + editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION)); editor.apply(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index 1e59059d2..f4ba54ea1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -83,6 +83,9 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_INACTIVITY_DND_START = "inactivity_warnings_dnd_start"; public static final String PREF_INACTIVITY_DND_END = "inactivity_warnings_dnd_end"; + public static final String PREF_HEARTRATE_USE_FOR_SLEEP_DETECTION = "heartrate_sleep_detection"; + public static final String PREF_HEARTRATE_MEASUREMENT_INTERVAL = "heartrate_measurement_interval"; + public static final String PREF_AUTOHEARTRATE_SWITCH = "pref_autoheartrate_switch"; public static final String PREF_AUTOHEARTRATE_SLEEP = "pref_autoheartrate_sleep"; public static final String PREF_AUTOHEARTRATE_INTERVAL = "pref_autoheartrate_interval"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index d4271d269..31d6290b6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -344,6 +344,28 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp }); } + final Preference enableHeartrateSleepSupport = findPreference(PREF_HEARTRATE_USE_FOR_SLEEP_DETECTION); + if (enableHeartrateSleepSupport != null) { + enableHeartrateSleepSupport.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onEnableHeartRateSleepSupport(Boolean.TRUE.equals(newVal)); + return true; + } + }); + } + + final Preference heartrateMeasurementInterval = findPreference(PREF_HEARTRATE_MEASUREMENT_INTERVAL); + if (heartrateMeasurementInterval != null) { + heartrateMeasurementInterval.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + GBApplication.deviceService().onSetHeartRateMeasurementInterval(Integer.parseInt((String) newVal)); + return true; + } + }); + } + addPreferenceHandlerFor(PREF_SWIPE_UNLOCK); addPreferenceHandlerFor(PREF_MI2_DATEFORMAT); addPreferenceHandlerFor(PREF_DATEFORMAT); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java index e7fa967e5..11a4a0d39 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java @@ -268,6 +268,11 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { return prefs.getBoolean(HuamiConst.PREF_EXPOSE_HR_THIRDPARTY, false); } + public static int getHeartRateMeasurementInterval(String deviceAddress) { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); + return GBApplication.getPrefs().getInt(DeviceSettingsPreferenceConst.PREF_HEARTRATE_MEASUREMENT_INTERVAL, 0) / 60; + } + public static boolean getBtConnectedAdvertising(String deviceAddress) { Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); return prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_BT_CONNECTED_ADVERTISEMENT, false); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java index fb75b393a..735bda426 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitband5/AmazfitBand5Coordinator.java @@ -101,6 +101,7 @@ public class AmazfitBand5Coordinator extends HuamiCoordinator { R.xml.devicesettings_amazfitband5, R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java index 6e97c9f9b..b8b354ccb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipCoordinator.java @@ -83,6 +83,7 @@ public class AmazfitBipCoordinator extends HuamiCoordinator { R.xml.devicesettings_amazfitbip, R.xml.devicesettings_timeformat, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java index 160d9ca27..fb7b31bf2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipLiteCoordinator.java @@ -72,6 +72,7 @@ public class AmazfitBipLiteCoordinator extends AmazfitBipCoordinator { R.xml.devicesettings_amazfitbip, R.xml.devicesettings_timeformat, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java index 25e8919f1..78bd9565b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbips/AmazfitBipSCoordinator.java @@ -99,6 +99,7 @@ public class AmazfitBipSCoordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_world_clocks, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java index e6c131318..faa3dc412 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipu/AmazfitBipUCoordinator.java @@ -112,6 +112,7 @@ public class AmazfitBipUCoordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_world_clocks, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display_sensitivity, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java index 56b3de59d..6a090b402 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbipupro/AmazfitBipUProCoordinator.java @@ -111,6 +111,7 @@ public class AmazfitBipUProCoordinator extends HuamiCoordinator { R.xml.devicesettings_timeformat, R.xml.devicesettings_world_clocks, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_liftwrist_display_sensitivity, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java index 109fbe6bb..182271c79 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorCoordinator.java @@ -90,6 +90,7 @@ public class AmazfitCorCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitcor, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_custom_emoji_font, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java index d5a662517..1dddcbec4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor2/AmazfitCor2Coordinator.java @@ -92,6 +92,7 @@ public class AmazfitCor2Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitcor, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_custom_emoji_font, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java index 6656b5c4b..fcc9a73bf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRCoordinator.java @@ -90,6 +90,7 @@ public class AmazfitGTRCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRLiteCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRLiteCoordinator.java index 8a826f832..09393a27b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRLiteCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr/AmazfitGTRLiteCoordinator.java @@ -91,6 +91,7 @@ public class AmazfitGTRLiteCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2Coordinator.java index d3f1804b5..3f715a697 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2Coordinator.java @@ -96,6 +96,7 @@ public class AmazfitGTR2Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2eCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2eCoordinator.java index f82dc929a..9e82c84cb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2eCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgtr2/AmazfitGTR2eCoordinator.java @@ -96,6 +96,7 @@ public class AmazfitGTR2eCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java index 8762b65e4..718823260 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts/AmazfitGTSCoordinator.java @@ -90,6 +90,7 @@ public class AmazfitGTSCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2Coordinator.java index 6a69adfa0..d50344dd4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2Coordinator.java @@ -96,6 +96,7 @@ public class AmazfitGTS2Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2MiniCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2MiniCoordinator.java index 5ffd26c9a..dacfb8928 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2MiniCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2MiniCoordinator.java @@ -65,6 +65,7 @@ public class AmazfitGTS2MiniCoordinator extends AmazfitGTS2Coordinator { return new int[]{ R.xml.devicesettings_amazfitgts2mini, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2eCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2eCoordinator.java index 5788b9111..8f3b7685e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2eCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitgts2/AmazfitGTS2eCoordinator.java @@ -96,6 +96,7 @@ public class AmazfitGTS2eCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitneo/AmazfitNeoCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitneo/AmazfitNeoCoordinator.java index b2291dbeb..96af7d957 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitneo/AmazfitNeoCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitneo/AmazfitNeoCoordinator.java @@ -84,6 +84,7 @@ public class AmazfitNeoCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitneo, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrex/AmazfitTRexCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrex/AmazfitTRexCoordinator.java index 9baeb3065..fd3e34ffd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrex/AmazfitTRexCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrex/AmazfitTRexCoordinator.java @@ -90,6 +90,7 @@ public class AmazfitTRexCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfittrex, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrexpro/AmazfitTRexProCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrexpro/AmazfitTRexProCoordinator.java index 2ac407a3a..f4c459761 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrexpro/AmazfitTRexProCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfittrexpro/AmazfitTRexProCoordinator.java @@ -90,6 +90,7 @@ public class AmazfitTRexProCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfittrexpro, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitvergel/AmazfitVergeLCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitvergel/AmazfitVergeLCoordinator.java index 673d95af4..453799751 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitvergel/AmazfitVergeLCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitvergel/AmazfitVergeLCoordinator.java @@ -91,6 +91,7 @@ public class AmazfitVergeLCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitvergel, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_inactivity_dnd, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java index 40e3abeac..57fc256f9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java @@ -93,6 +93,7 @@ public class AmazfitXCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitx, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java index 4b5af567b..8602af164 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java @@ -84,6 +84,7 @@ public class MiBand2Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_miband2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_donotdisturb_withauto, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java index daa22a027..a912f5b1d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java @@ -87,6 +87,7 @@ public class MiBand2HRXCoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_miband2, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_donotdisturb_withauto, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java index ab27548ac..4ad87437f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Coordinator.java @@ -103,6 +103,7 @@ public class MiBand3Coordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_miband3, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_dateformat, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java index d34634ff2..83e9730a3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband4/MiBand4Coordinator.java @@ -91,6 +91,7 @@ public class MiBand4Coordinator extends HuamiCoordinator { R.xml.devicesettings_miband3, R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java index 020ae69c3..57d9531af 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java @@ -106,6 +106,7 @@ public class MiBand5Coordinator extends HuamiCoordinator { R.xml.devicesettings_miband5, R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java index 00012fa07..bb70de28c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java @@ -86,6 +86,7 @@ public class MiBand6Coordinator extends HuamiCoordinator { R.xml.devicesettings_miband6, R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/zeppe/ZeppECoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/zeppe/ZeppECoordinator.java index 862e3c012..c8c8358ff 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/zeppe/ZeppECoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/zeppe/ZeppECoordinator.java @@ -90,6 +90,7 @@ public class ZeppECoordinator extends HuamiCoordinator { return new int[]{ R.xml.devicesettings_amazfitgtsgtr, R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_goal_notification, R.xml.devicesettings_timeformat, R.xml.devicesettings_liftwrist_display, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java index 0a7345606..e605f28fa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java @@ -24,7 +24,6 @@ public final class MiBandConst { public static final String PREF_MIBAND_ADDRESS = "development_miaddr"; // FIXME: should be prefixed mi_ public static final String PREF_MIBAND_ALARMS = "mi_alarms"; public static final String PREF_MIBAND_DONT_ACK_TRANSFER = "mi_dont_ack_transfer"; - public static final String PREF_MIBAND_USE_HR_FOR_SLEEP_DETECTION = "mi_hr_sleep_detection"; public static final String PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS = "device_time_offset_hours"; public static final String PREF_MI2_DATEFORMAT = "mi2_dateformat"; public static final String PREF_MI2_DISPLAY_ITEM_CLOCK = "clock"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java index de579f243..79f8af5c4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java @@ -245,9 +245,9 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator { return prefs.getInt(MiBandConst.PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS, 0); } - public static boolean getHeartrateSleepSupport(String miBandAddress) throws IllegalArgumentException { - Prefs prefs = GBApplication.getPrefs(); - return prefs.getBoolean(MiBandConst.PREF_MIBAND_USE_HR_FOR_SLEEP_DETECTION, false); + public static boolean getHeartrateSleepSupport(String deviceAddress) throws IllegalArgumentException { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); + return prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_HEARTRATE_USE_FOR_SLEEP_DETECTION, false); } public static int getReservedAlarmSlots(String miBandAddress) throws IllegalArgumentException { @@ -265,6 +265,7 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator { public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ R.xml.devicesettings_wearlocation, + R.xml.devicesettings_heartrate_sleep, R.xml.devicesettings_lowlatency_fwupdate, R.xml.devicesettings_reserve_alarms_calendar, R.xml.devicesettings_fake_timeoffset diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java index 6353be03d..6d6f6d9b2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java @@ -41,7 +41,6 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_ALARM_CLOCK; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_INCOMING_CALL; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_ADDRESS; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_USE_HR_FOR_SLEEP_DETECTION; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.VIBRATION_COUNT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.getNotificationPrefKey; import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_NAME; @@ -57,24 +56,6 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity { Prefs prefs = GBApplication.getPrefs(); - final Preference enableHeartrateSleepSupport = findPreference(PREF_MIBAND_USE_HR_FOR_SLEEP_DETECTION); - enableHeartrateSleepSupport.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - GBApplication.deviceService().onEnableHeartRateSleepSupport(Boolean.TRUE.equals(newVal)); - return true; - } - }); - - final Preference heartrateMeasurementInterval = findPreference("heartrate_measurement_interval"); - heartrateMeasurementInterval.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - GBApplication.deviceService().onSetHeartRateMeasurementInterval(Integer.parseInt((String) newVal)); - return true; - } - }); - final Preference fitnessGoal = findPreference(ActivityUser.PREF_USER_STEPS_GOAL); fitnessGoal.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 590a727aa..006cf6290 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -3679,16 +3679,12 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { setHeartrateSleepSupport(builder); setDisconnectNotification(builder); setExposeHRThridParty(builder); - setHeartrateMeasurementInterval(builder, getHeartRateMeasurementInterval()); + setHeartrateMeasurementInterval(builder, HuamiCoordinator.getHeartRateMeasurementInterval(getDevice().getAddress())); sendReminders(builder); setWorldClocks(builder); requestAlarms(builder); } - private int getHeartRateMeasurementInterval() { - return GBApplication.getPrefs().getInt("heartrate_measurement_interval", 0) / 60; - } - public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException { return new MiBand2FWHelper(uri, context); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 32f0ddada..bd5c99c3c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -683,6 +683,8 @@ The band will vibrate when you have been inactive for a while Inactivity threshold (in minutes) Disable inactivity warnings for a time interval + Heart Rate Monitoring + Configure heart rate monitoring Start time End time Activate display upon lift during Do Not Disturb diff --git a/app/src/main/res/xml/devicesettings_heartrate_sleep.xml b/app/src/main/res/xml/devicesettings_heartrate_sleep.xml new file mode 100644 index 000000000..9cc3d09b6 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_heartrate_sleep.xml @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/app/src/main/res/xml/miband_preferences.xml b/app/src/main/res/xml/miband_preferences.xml index 0d4ea4a79..b4e5bf91f 100644 --- a/app/src/main/res/xml/miband_preferences.xml +++ b/app/src/main/res/xml/miband_preferences.xml @@ -16,19 +16,6 @@ android:maxLength="5" android:title="@string/miband_prefs_fitness_goal" /> - - - - Date: Mon, 16 May 2022 17:42:02 +0100 Subject: [PATCH 101/110] Mi Band 5: Add HR activity monitoring, HR alerts, stress monitoring --- .../DeviceSettingsPreferenceConst.java | 4 ++ .../DeviceSpecificSettingsFragment.java | 38 +++++++++++- .../devices/huami/HuamiCoordinator.java | 20 ++++++ .../huami/miband5/MiBand5Coordinator.java | 2 +- .../service/devices/huami/HuamiSupport.java | 49 +++++++++++++++ app/src/main/res/drawable/ic_mood_bad.xml | 5 ++ app/src/main/res/drawable/ic_warning_gray.xml | 5 ++ app/src/main/res/values/arrays.xml | 28 +++++++++ app/src/main/res/values/strings.xml | 19 ++++++ .../heartrate_sleep_alert_activity_stress.xml | 62 +++++++++++++++++++ 10 files changed, 228 insertions(+), 4 deletions(-) create mode 100644 app/src/main/res/drawable/ic_mood_bad.xml create mode 100644 app/src/main/res/drawable/ic_warning_gray.xml create mode 100644 app/src/main/res/xml/heartrate_sleep_alert_activity_stress.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index f4ba54ea1..a083c1724 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -85,6 +85,10 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_HEARTRATE_USE_FOR_SLEEP_DETECTION = "heartrate_sleep_detection"; public static final String PREF_HEARTRATE_MEASUREMENT_INTERVAL = "heartrate_measurement_interval"; + public static final String PREF_HEARTRATE_ACTIVITY_MONITORING = "heartrate_activity_monitoring"; + public static final String PREF_HEARTRATE_ALERT_ENABLED = "heartrate_alert_enabled"; + public static final String PREF_HEARTRATE_ALERT_THRESHOLD = "heartrate_alert_threshold"; + public static final String PREF_HEARTRATE_STRESS_MONITORING = "heartrate_stress_monitoring"; public static final String PREF_AUTOHEARTRATE_SWITCH = "pref_autoheartrate_switch"; public static final String PREF_AUTOHEARTRATE_SLEEP = "pref_autoheartrate_sleep"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index 31d6290b6..efe23cbca 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -355,15 +355,43 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp }); } - final Preference heartrateMeasurementInterval = findPreference(PREF_HEARTRATE_MEASUREMENT_INTERVAL); + final ListPreference heartrateMeasurementInterval = findPreference(PREF_HEARTRATE_MEASUREMENT_INTERVAL); if (heartrateMeasurementInterval != null) { + final SwitchPreference activityMonitoring = findPreference(PREF_HEARTRATE_ACTIVITY_MONITORING); + final SwitchPreference heartrateAlertEnabled = findPreference(PREF_HEARTRATE_ALERT_ENABLED); + final SwitchPreference stressMonitoring = findPreference(PREF_HEARTRATE_STRESS_MONITORING); + heartrateMeasurementInterval.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { + public boolean onPreferenceChange(final Preference preference, final Object newVal) { GBApplication.deviceService().onSetHeartRateMeasurementInterval(Integer.parseInt((String) newVal)); + + final boolean isMeasurementIntervalEnabled = !newVal.equals("0"); + + if (activityMonitoring != null) { + activityMonitoring.setEnabled(isMeasurementIntervalEnabled); + } + if (heartrateAlertEnabled != null) { + heartrateAlertEnabled.setEnabled(isMeasurementIntervalEnabled); + } + if (stressMonitoring != null) { + stressMonitoring.setEnabled(isMeasurementIntervalEnabled); + } + return true; } }); + + final boolean isMeasurementIntervalEnabled = !heartrateMeasurementInterval.getValue().equals("0"); + + if (activityMonitoring != null) { + activityMonitoring.setEnabled(isMeasurementIntervalEnabled); + } + if (heartrateAlertEnabled != null) { + heartrateAlertEnabled.setEnabled(isMeasurementIntervalEnabled); + } + if (stressMonitoring != null) { + stressMonitoring.setEnabled(isMeasurementIntervalEnabled); + } } addPreferenceHandlerFor(PREF_SWIPE_UNLOCK); @@ -416,6 +444,10 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp addPreferenceHandlerFor(PREF_AUTOHEARTRATE_INTERVAL); addPreferenceHandlerFor(PREF_AUTOHEARTRATE_START); addPreferenceHandlerFor(PREF_AUTOHEARTRATE_END); + addPreferenceHandlerFor(PREF_HEARTRATE_ACTIVITY_MONITORING); + addPreferenceHandlerFor(PREF_HEARTRATE_ALERT_THRESHOLD); + addPreferenceHandlerFor(PREF_HEARTRATE_ALERT_ENABLED); + addPreferenceHandlerFor(PREF_HEARTRATE_STRESS_MONITORING); addPreferenceHandlerFor(PREF_DO_NOT_DISTURB_NOAUTO); addPreferenceHandlerFor(PREF_DO_NOT_DISTURB_NOAUTO_START); addPreferenceHandlerFor(PREF_DO_NOT_DISTURB_NOAUTO_END); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java index 11a4a0d39..42575cf63 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java @@ -273,6 +273,26 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { return GBApplication.getPrefs().getInt(DeviceSettingsPreferenceConst.PREF_HEARTRATE_MEASUREMENT_INTERVAL, 0) / 60; } + public static boolean getHeartrateActivityMonitoring(String deviceAddress) throws IllegalArgumentException { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); + return prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_HEARTRATE_ACTIVITY_MONITORING, false); + } + + public static boolean getHeartrateAlert(String deviceAddress) throws IllegalArgumentException { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); + return prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_HEARTRATE_ALERT_ENABLED, false); + } + + public static int getHeartrateAlertThreshold(String deviceAddress) throws IllegalArgumentException { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); + return prefs.getInt(DeviceSettingsPreferenceConst.PREF_HEARTRATE_ALERT_THRESHOLD, 150); + } + + public static boolean getHeartrateStressMonitoring(String deviceAddress) throws IllegalArgumentException { + Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); + return prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_HEARTRATE_STRESS_MONITORING, false); + } + public static boolean getBtConnectedAdvertising(String deviceAddress) { Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress)); return prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_BT_CONNECTED_ADVERTISEMENT, false); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java index 57d9531af..edf442680 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java @@ -106,7 +106,7 @@ public class MiBand5Coordinator extends HuamiCoordinator { R.xml.devicesettings_miband5, R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_wearlocation, - R.xml.devicesettings_heartrate_sleep, + R.xml.heartrate_sleep_alert_activity_stress, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 006cf6290..a74f3079d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -171,6 +171,10 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DO_NOT_DISTURB_START; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DO_NOT_DISTURB_END; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DO_NOT_DISTURB_LIFT_WRIST; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HEARTRATE_ACTIVITY_MONITORING; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HEARTRATE_ALERT_ENABLED; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HEARTRATE_ALERT_THRESHOLD; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HEARTRATE_STRESS_MONITORING; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_INACTIVITY_ENABLE; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_INACTIVITY_START; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_INACTIVITY_END; @@ -230,6 +234,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.CO import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.COMMAND_GPS_VERSION; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.COMMAND_WORKOUT_ACTIVITY_TYPES; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.DISPLAY_ITEM_BIT_CLOCK; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY_ITEMS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_COUNT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_PROFILE; @@ -679,6 +684,37 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return this; } + private HuamiSupport setHeartrateActivityMonitoring(TransactionBuilder builder) { + final boolean enableHrActivityMonitoring = HuamiCoordinator.getHeartrateActivityMonitoring(gbDevice.getAddress()); + final byte[] cmd = {ENDPOINT_DISPLAY, 0x22, 0x00, (byte) (enableHrActivityMonitoring ? 0x01 : 0x00)}; + writeToConfiguration(builder, cmd); + return this; + } + + private HuamiSupport setHeartrateAlert(TransactionBuilder builder) { + final boolean enableHrAlert = HuamiCoordinator.getHeartrateAlert(gbDevice.getAddress()); + final int hrAlertThreshold = HuamiCoordinator.getHeartrateAlertThreshold(gbDevice.getAddress()); + + final byte[] cmd = { + ENDPOINT_DISPLAY, + 0x1a, + 0x00, + (byte) (enableHrAlert ? 0x01 : 0x00), + (byte) hrAlertThreshold + }; + + writeToConfiguration(builder, cmd); + + return this; + } + + private HuamiSupport setHeartrateStressMonitoring(TransactionBuilder builder) { + final boolean enableHrStressMonitoring = HuamiCoordinator.getHeartrateStressMonitoring(gbDevice.getAddress()); + final byte[] cmd = new byte[] {(byte) 0xfe, 0x06, 0x00, (byte) (enableHrStressMonitoring ? 0x01 : 0x00)}; + writeToConfiguration(builder, cmd); + return this; + } + private HuamiSupport setHeartrateMeasurementInterval(TransactionBuilder builder, int minutes) { if (characteristicHRControlPoint != null) { builder.notify(characteristicHRControlPoint, true); @@ -2536,6 +2572,16 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case PREF_HUAMI_VIBRATION_TRY_FIND_BAND: setVibrationPattern(builder, config); break; + case PREF_HEARTRATE_ACTIVITY_MONITORING: + setHeartrateActivityMonitoring(builder); + break; + case PREF_HEARTRATE_ALERT_ENABLED: + case PREF_HEARTRATE_ALERT_THRESHOLD: + setHeartrateAlert(builder); + break; + case PREF_HEARTRATE_STRESS_MONITORING: + setHeartrateStressMonitoring(builder); + break; } builder.queue(getQueue()); } catch (IOException e) { @@ -3677,6 +3723,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { setGoalNotification(builder); setInactivityWarnings(builder); setHeartrateSleepSupport(builder); + setHeartrateActivityMonitoring(builder); + setHeartrateAlert(builder); + setHeartrateStressMonitoring(builder); setDisconnectNotification(builder); setExposeHRThridParty(builder); setHeartrateMeasurementInterval(builder, HuamiCoordinator.getHeartRateMeasurementInterval(getDevice().getAddress())); diff --git a/app/src/main/res/drawable/ic_mood_bad.xml b/app/src/main/res/drawable/ic_mood_bad.xml new file mode 100644 index 000000000..7548a5887 --- /dev/null +++ b/app/src/main/res/drawable/ic_mood_bad.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_warning_gray.xml b/app/src/main/res/drawable/ic_warning_gray.xml new file mode 100644 index 000000000..98ce89163 --- /dev/null +++ b/app/src/main/res/drawable/ic_warning_gray.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index aa3c82889..f9d8d1377 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1581,6 +1581,34 @@ 3600 + + @string/heartrate_bpm_100 + @string/heartrate_bpm_105 + @string/heartrate_bpm_110 + @string/heartrate_bpm_112 + @string/heartrate_bpm_120 + @string/heartrate_bpm_125 + @string/heartrate_bpm_130 + @string/heartrate_bpm_135 + @string/heartrate_bpm_140 + @string/heartrate_bpm_145 + @string/heartrate_bpm_150 + + + + 100 + 105 + 110 + 112 + 120 + 125 + 130 + 135 + 140 + 145 + 150 + + @string/off @string/interval_five_minutes diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bd5c99c3c..895419d9c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -482,6 +482,17 @@ every 15 minutes every 30 minutes every 45 minutes + 100 bpm + 105 bpm + 110 bpm + 112 bpm + 120 bpm + 125 bpm + 130 bpm + 135 bpm + 140 bpm + 145 bpm + 150 bpm once an hour Speed zones Total minutes @@ -538,6 +549,13 @@ Do some activity and synchronize device. About to transfer %1$s of data starting from %2$s Daily step target + Heart rate alert (experimental) + Vibrate the band when the heart rate is over a threshold, without any obvious physical activity in the last 10 minutes. This feature is experimental, and was not extensively tested. + Heart rate alert threshold + Stress monitoring + Monitor stress level while resting + Activity monitoring + Automatically increase the heart rate detection frequency when the band detects physical exercise, to increase heart rate capture accuracy. Error executing \'%1$s\' Your activity (ALPHA) Cannot connect: %1$s @@ -685,6 +703,7 @@ Disable inactivity warnings for a time interval Heart Rate Monitoring Configure heart rate monitoring + Configure heart rate monitoring and alert thresholds Start time End time Activate display upon lift during Do Not Disturb diff --git a/app/src/main/res/xml/heartrate_sleep_alert_activity_stress.xml b/app/src/main/res/xml/heartrate_sleep_alert_activity_stress.xml new file mode 100644 index 000000000..7abecfa16 --- /dev/null +++ b/app/src/main/res/xml/heartrate_sleep_alert_activity_stress.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + From 569cd59dd5821e2f8a26842eaa80d617dd7f0548 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Mon, 16 May 2022 13:05:32 +0000 Subject: [PATCH 102/110] Translated using Weblate (Hebrew) Currently translated at 100.0% (1515 of 1515 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 6ff0704b2..e9c790f96 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -1638,4 +1638,5 @@ מתזכר אירועים התראות בטלה איתור המכשיר + Sony WF-1000XM3 \ No newline at end of file From 0d9259a351ec39031148869c755933f7f599e0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Mon, 16 May 2022 19:42:21 +0000 Subject: [PATCH 103/110] Translated using Weblate (Turkish) Currently translated at 100.0% (1515 of 1515 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/tr/ --- app/src/main/res/values-tr/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index d71be1eb9..759fecacc 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -1655,4 +1655,5 @@ Etkinlik hatırlatıcı Aygıt bul Farklı bildirimler için titreşim modellerini yapılandırın + Sony WF-1000XM3 \ No newline at end of file From 34d2daf9df52a32818fbb9f95e9c9022bac98e1e Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Mon, 16 May 2022 21:24:33 +0000 Subject: [PATCH 104/110] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1515 of 1515 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/uk/ --- app/src/main/res/values-uk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index ce7d58456..eff7401af 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1646,4 +1646,5 @@ Знайти пристрій Шаблони вібрацій Налаштуйте шаблони вібрації для різних сповіщень + Sony WF-1000XM3 \ No newline at end of file From 9ef6c05af1a470a850c3db08eae202d45c4b014b Mon Sep 17 00:00:00 2001 From: arjan-s Date: Mon, 16 May 2022 13:29:49 +0000 Subject: [PATCH 105/110] Translated using Weblate (Dutch) Currently translated at 100.0% (1515 of 1515 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nl/ --- app/src/main/res/values-nl/strings.xml | 45 ++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 9f26eba66..037c21543 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -1595,4 +1595,49 @@ Positie ingesteld op %s Scherm oplichten bij nieuwe melding E-mail + Evenement-herinnering + Zoek apparaat + Inactiviteitswaarschuwingen + Trillingspatronen + Configureer de trillingspatronen voor verschillende meldingen + Klokken configureren voor andere tijdzones + Verwijder \'%1$s\' + Weet je zeker dat je de wereldklok wilt verwijderen\? + Geen vrije plekken + Het apparaat heeft geen vrije slots voor wereldklokken (totaal aantal slots: %1$s) + Tijdzone + Label + Details wereldklok + Soorten trainingsactiviteiten + Kies de activiteitstypes om op het workouts-scherm weer te geven + Normaal + Gevoelig + Buiten fietsen + Crosstrainer + Sony WF-1000XM3 + Gadgetbridge Nightly Geen Pebble + Buiten hardlopen + Over Gadgetbridge Nightly + Gadgetbridge (Nightly, geen Pebble-provider) + Nightly NoPebble GB actief + Freestyle + Fitness-app-tracking in-/uitschakelen + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + Over Bangle.js Gadgetbridge + Android-app voor Bangle.js gebouwd bovenop het Gadgetbridge-project, met toegevoegde internettoegang. + Bangle.js actief + Bangle.js Gadgetbridge + Bangle.js Gadgetbridge + Over Bangle.js Gadgetbridge + Android-app voor Bangle.js gebouwd bovenop het Gadgetbridge-project, met toegevoegde internettoegang. + Bangle.js actief + Gadgetbridge (Nightly) + Gadgetbridge Nightly + Cloudless copyleft libre-vervanging voor closed source Android-gadget-apps van leveranciers. Nightly releases van Gadgetbridge. Het kan niet worden geïnstalleerd als je de Gadgetbridge- of de Pebble-app al hebt geïnstalleerd, vanwege een conflict in de Pebble-provider. + Nightly GB actief + Over Gadgetbridge Nightly No Pebble + Cloudloze copyleft libre-vervanging voor closed source Android-gadget-apps van leveranciers. Nightly releases van Gadgetbridge. Deze versie heeft de naam van de Pebble-provider hernoemd om conflicten te voorkomen, dus sommige Pebble-gerelateerde integraties zullen niet werken, maar het kan naast de bestaande Gadgetbridge-installatie worden geïnstalleerd. + Wereldklokken + Gevoeligheid \ No newline at end of file From c5b4763fbfc0fde45c7ba96932c7c5a8d5890552 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 17 May 2022 21:12:41 +0000 Subject: [PATCH 106/110] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1554 of 1554 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/uk/ --- app/src/main/res/values-uk/strings.xml | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index eff7401af..a8102ff04 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1647,4 +1647,43 @@ Шаблони вібрацій Налаштуйте шаблони вібрації для різних сповіщень Sony WF-1000XM3 + Galaxy Buds Pro + Відтворення викликів через навушники, коли вони у ваших вухах + Автоматичне перемикає навушники між пов\'язаними пристроями + Гучність навколишнього середовища зліва + Налаштування навколишнього звуку + Навколишній звук під час виклику + Активний рівень пригнічення шуму + Високий + Перемикання елемента керування ліворуч + Перемикання елемента керування праворуч + Активне пригнічення шуму + Гучність + Від м’якого до чистого + Пригнічення шуму ←→ Вимкнено + Навколишнє середовище ←→ Вимкнено + Контроль шуму + Виявлення голосу + Подвійний дотик краю + Завершення після тиші за: + 15 секунд + Гучність навколишнього середовища вправо + Чути власний голос під час виклику + Плавне перемикання з\'єднання + Параметри навколишнього звуку + Голосовий помічник + Низький + Керування шумом за допомогою одного навушника + Швидкий навколишній звук + Spotify + Перемикання керування шумом + Навколишній звук + Дозволити контроль шуму під час використання лише одного навушника + Баланс + Тон навколишнього звуку + Пригнічення шуму ←→ Навколишнє середовище + Увімкнути навколишній звук і автоматичне стишення відтворення після виявлення голосу + Виявлення подвійного дотику, навіть якщо він не під\'єднаний до сенсорної панелі + 10 секунд + 5 секунд \ No newline at end of file From 18f4d62009bc48e11f3392e203f3eaeb6de0acf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=91=E4=B8=BE?= Date: Wed, 18 May 2022 01:52:35 +0000 Subject: [PATCH 107/110] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1554 of 1554 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/zh_Hans/ --- app/src/main/res/values-zh-rCN/strings.xml | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 00a378699..c366beafa 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1645,4 +1645,43 @@ 空闲警报 振动模式 Sony WF-1000XM3 + 环境声音选项 + 安静多久后结束: + 5秒 + 10秒 + 15秒 + Galaxy Buds Pro + 右侧环境音量 + 自定义环境音 + 环境音声调 + 无缝连接开关 + 当耳塞在你的耳朵里时,通过耳塞接听电话 + 在配对设备之间自动切换耳机 + 左侧环境音量 + 通话期间的环境音 + 主动降噪级别 + + + 左侧开关控制 + 在通话过程中听到自己的声音 + 右侧开关控制 + 主动降噪 + 音量 + 环境音 + Spotify + 切换噪声控制 + 单个耳塞的噪音控制 + 只使用一个耳塞的情况下允许使用噪音控制 + 语音助理 + 快速环境音效 + 从柔软到清晰 + 环境音 ←→ 关闭 + 启用环境音,并在检测到语音后自动降低播放音量 + 双击边缘 + 即使没有触摸板上按下也进行双击检测 + 平衡 + 降噪 ←→ 环境 + 降噪 ←→ 关闭 + 噪音控制 + 语音检测 \ No newline at end of file From 21fbcfa530a023598145c1fbb35f764cff6387aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Tue, 17 May 2022 21:32:55 +0000 Subject: [PATCH 108/110] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 87.6% (1362 of 1554 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/nb_NO/ --- app/src/main/res/values-nb-rNO/strings.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index a4ec29f47..323584de5 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -1596,4 +1596,21 @@ Forsto ikke plassering. Antagelig er dette et tilgangsproblem i Android. Mest sannsynlig fungerer ikke auto-eksport nå. forhåndsinnstiller posisjon til %s Slå på lys ved nye merknader + Omgivelseslyd + Balanse + Utendørssykling + Utendørsløping + Lavt + Spotify + Høy + Stemmeassistent + Lydstyrke + Aktiv lydkansellering + Støykontroll + 5 sekunder + 10 sekunder + 15 sekunder + Normal + Sensitiv + E-post \ No newline at end of file From 79d5c246a2261b479f37711afce626756ff25bd6 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Wed, 18 May 2022 10:41:30 +0200 Subject: [PATCH 109/110] Mi Band 6: enable new settings --- CHANGELOG.md | 3 ++- .../gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f78cd5ee3..d1b446111 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,14 @@ * Initial Support for Sony WF-1000XM3 * Initial Support for Galaxy Buds Pro * Huami: Add Toggle function for Open Tracks tracking to button actions -* Huami: Move inactivity warnings and goal notification to device-specific settings +* Huami: Move inactivity warnings, goal notification and HR monitoring to device-specific settings * Mi Band 6: set time on connect * Mi Band 5/6, Amazfit Bip S/U/Pro: Add world clock configuration * Mi Band 5/6: support sensitivity setting for lift wrist configuration * Mi Band 5: Add support for configuring workout menu on device * Mi Band 4/5/6, Amazfit Bip U/Pro: Add support for vibration patterns * Mi Band 5: Increase number of reminder slots to 50 +* Mi Band 5/6: Add setting for HR activity monitoring, HR alerts, stress monitoring * Amazfit Neo: Allow to disable beeps for email notifications * Bangle.js: Fix incoming calls in release builds * Fossil Hybrid HR: Support flexible custom menu on watch diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java index bb70de28c..8b3e2ead4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband6/MiBand6Coordinator.java @@ -86,7 +86,7 @@ public class MiBand6Coordinator extends HuamiCoordinator { R.xml.devicesettings_miband6, R.xml.devicesettings_vibrationpatterns, R.xml.devicesettings_wearlocation, - R.xml.devicesettings_heartrate_sleep, + R.xml.heartrate_sleep_alert_activity_stress, R.xml.devicesettings_goal_notification, R.xml.devicesettings_custom_emoji_font, R.xml.devicesettings_timeformat, From 603d56c7aa1a182a9d29e7f5a63089996edc4db2 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Wed, 18 May 2022 10:45:44 +0200 Subject: [PATCH 110/110] update changelog, bump version --- CHANGELOG.md | 6 +++-- app/build.gradle | 4 ++-- app/src/main/res/xml/changelog_master.xml | 23 +++++++++++++++++++ .../metadata/android/en-US/changelogs/211.txt | 21 +++++++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/211.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index d1b446111..da38ceee8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ### Changelog -### NEXT +### 0.67.0 * Initial Support for Sony WF-1000XM3 * Initial Support for Galaxy Buds Pro * Huami: Add Toggle function for Open Tracks tracking to button actions @@ -15,13 +15,15 @@ * Amazfit Neo: Allow to disable beeps for email notifications * Bangle.js: Fix incoming calls in release builds * Fossil Hybrid HR: Support flexible custom menu on watch +* Fossil Hybrid HR: Add support for native DND Call/SMS functionality * VESC: added battery indicator * UM25: Add reset option to current accumulation * UM25: Add notification on below current threshold * Fix crash when calendar is accessed but permission is denied -* Add com.asus.asusincallui to blacklist +* Add com.asus.asusincallui and com.samsung.android.incallui to blacklist * New icons for Sony overhead headphones, Sony WF 800n and Mi Band 6 + ### 0.66.0 * Add basic support for Casio GBD-H1000 * Add support for Hama Fit Track 1900 - via FitPro device support diff --git a/app/build.gradle b/app/build.gradle index aff0035ab..76d42bd87 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,8 +55,8 @@ android { multiDexEnabled true // Note: always bump BOTH versionCode and versionName! - versionName "0.66.0" - versionCode 210 + versionName "0.67.0" + versionCode 211 vectorDrawables.useSupportLibrary = true multiDexEnabled true buildConfigField "String", "GIT_HASH_SHORT", "\"${getGitHashShort()}\"" diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index 6d845686b..01eae68c0 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,5 +1,28 @@ + + Initial Support for Sony WF-1000XM3 + Initial Support for Galaxy Buds Pro + Huami: Add Toggle function for Open Tracks tracking to button actions + Huami: Move inactivity warnings, goal notification and HR monitoring to device-specific settings + Mi Band 6: set time on connect + Mi Band 5/6, Amazfit Bip S/U/Pro: Add world clock configuration + Mi Band 5/6: support sensitivity setting for lift wrist configuration + Mi Band 5: Add support for configuring workout menu on device + Mi Band 4/5/6, Amazfit Bip U/Pro: Add support for vibration patterns + Mi Band 5: Increase number of reminder slots to 50 + Mi Band 5/6: Add setting for HR activity monitoring, HR alerts, stress monitoring + Amazfit Neo: Allow to disable beeps for email notifications + Bangle.js: Fix incoming calls in release builds + Fossil Hybrid HR: Support flexible custom menu on watch + Fossil Hybrid HR: Add support for native DND Call/SMS functionality + VESC: added battery indicator + UM25: Add reset option to current accumulation + UM25: Add notification on below current threshold + Fix crash when calendar is accessed but permission is denied + Add com.asus.asusincallui and com.samsung.android.incallui to blacklist + New icons for Sony overhead headphones, Sony WF 800n and Mi Band 6 + Add basic support for Casio GBD-H1000 Add support for Hama Fit Track 1900 - via FitPro device support diff --git a/fastlane/metadata/android/en-US/changelogs/211.txt b/fastlane/metadata/android/en-US/changelogs/211.txt new file mode 100644 index 000000000..b92a455c4 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/211.txt @@ -0,0 +1,21 @@ +* Initial Support for Sony WF-1000XM3 +* Initial Support for Galaxy Buds Pro +* Huami: Add Toggle function for Open Tracks tracking to button actions +* Huami: Move inactivity warnings, goal notification and HR monitoring to device-specific settings +* Mi Band 6: set time on connect +* Mi Band 5/6, Amazfit Bip S/U/Pro: Add world clock configuration +* Mi Band 5/6: support sensitivity setting for lift wrist configuration +* Mi Band 5: Add support for configuring workout menu on device +* Mi Band 4/5/6, Amazfit Bip U/Pro: Add support for vibration patterns +* Mi Band 5: Increase number of reminder slots to 50 +* Mi Band 5/6: Add setting for HR activity monitoring, HR alerts, stress monitoring +* Amazfit Neo: Allow to disable beeps for email notifications +* Bangle.js: Fix incoming calls in release builds +* Fossil Hybrid HR: Support flexible custom menu on watch +* Fossil Hybrid HR: Add support for native DND Call/SMS functionality +* VESC: added battery indicator +* UM25: Add reset option to current accumulation +* UM25: Add notification on below current threshold +* Fix crash when calendar is accessed but permission is denied +* Add com.asus.asusincallui and com.samsung.android.incallui to blacklist +* New icons for Sony overhead headphones, Sony WF 800n and Mi Band 6