From fe07e09d41488006ec98eef088abec910bb9bc3e Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Fri, 17 Mar 2017 22:34:50 +0100 Subject: [PATCH 01/61] Fix firmware installation on Pebble Time Round Closes #602 --- .../gadgetbridge/devices/pebble/PBWReader.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java index 5cb0dc8b1..ee2458f77 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java @@ -97,9 +97,13 @@ public class PBWReader { return; } - String platformDir = determinePlatformDir(uriHelper, platform); - if (platform.equals("chalk") && platformDir.equals("")) { - return; + String platformDir = ""; + if (!uriHelper.getFileName().endsWith(".pbz")) { + platformDir = determinePlatformDir(uriHelper, platform); + + if (platform.equals("chalk") && platformDir.equals("")) { + return; + } } LOG.info("using platformdir: '" + platformDir + "'"); @@ -237,9 +241,6 @@ public class PBWReader { private String determinePlatformDir(UriHelper uriHelper, String platform) throws IOException { String platformDir = ""; - if (uriHelper.getFileName().endsWith(".pbz")) { - return platformDir; - } /* * for aplite and basalt it is possible to install 2.x apps which have no subfolder * we still prefer the subfolders if present. From b2886b81c9d86721b59c88530975fa57e6441093 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Fri, 17 Mar 2017 22:52:36 +0100 Subject: [PATCH 02/61] bump version, update changelog --- CHANGELOG.md | 5 +++++ app/build.gradle | 4 ++-- app/src/main/res/xml/changelog_master.xml | 5 +++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12a2b1a32..acd090c9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ###Changelog +###Version 0.18.1 +* Pebble: Fix Firmware insstallation on Pebble Time Round (broken since 0.16.0) +* Start VibrationActivity when using "find device" button with Vibratissimo +* Support material fork of K9 + ###Version 0.18.0 * All new GUI for the control center * Add Portuguese pt_PT and pt_BR translations diff --git a/app/build.gradle b/app/build.gradle index 90de6d715..63f8b2132 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { targetSdkVersion 25 // note: always bump BOTH versionCode and versionName! - versionName "0.18.0" - versionCode 87 + versionName "0.18.1" + versionCode 88 vectorDrawables.useSupportLibrary = true } buildTypes { diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index 954f33d1b..a4dc1aa09 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,5 +1,10 @@ + + Pebble: Fix Firmware insstallation on Pebble Time Round (broken since 0.16.0) + Start VibrationActivity when using "find device" button with Vibratissimo + Support material fork of K9 + All new GUI for the control center Add Portuguese pt_PT and pt_BR translations From f1d07c83f629d4ca4c9444061b8ef296ab4c6265 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sat, 18 Mar 2017 11:41:47 +0100 Subject: [PATCH 03/61] Fix NPE #603 --- .../freeyourgadget/gadgetbridge/util/NotificationUtils.java | 2 +- .../nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java index 7e7b8df02..7939f4eb9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java @@ -42,7 +42,7 @@ public class NotificationUtils { case CONVERSATIONS: case FACEBOOK: case FACEBOOK_MESSENGER: - return notificationSpec.body; + return StringUtils.ensureNotNull(notificationSpec.body); } return ""; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java index 0a9eaae20..d7b6757d9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java @@ -20,6 +20,7 @@ import android.support.annotation.NonNull; public class StringUtils { + @NonNull public static String truncate(String s, int maxLength){ if (s == null) { return ""; From cc159cf80f105b10f0e5c7d8cb079ee30670a965 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sat, 18 Mar 2017 11:46:08 +0100 Subject: [PATCH 04/61] 0.18.2 --- CHANGELOG.md | 3 +++ app/build.gradle | 4 ++-- app/src/main/res/xml/changelog_master.xml | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index acd090c9c..30bb65ad1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ###Changelog +###Version 0.18.1 +* Mi2: Fix crash on "chat" or "social network" text notification #603 + ###Version 0.18.1 * Pebble: Fix Firmware insstallation on Pebble Time Round (broken since 0.16.0) * Start VibrationActivity when using "find device" button with Vibratissimo diff --git a/app/build.gradle b/app/build.gradle index 63f8b2132..c42d79b3a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { targetSdkVersion 25 // note: always bump BOTH versionCode and versionName! - versionName "0.18.1" - versionCode 88 + versionName "0.18.2" + versionCode 89 vectorDrawables.useSupportLibrary = true } buildTypes { diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index a4dc1aa09..1154a27c9 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,5 +1,8 @@ + + Mi2: Fix crash on "chat" or "social network" text notification #603 + Pebble: Fix Firmware insstallation on Pebble Time Round (broken since 0.16.0) Start VibrationActivity when using "find device" button with Vibratissimo From 5d042cf3c8ac89e11477f3e45f2f0290d369217b Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sat, 18 Mar 2017 17:13:35 +0100 Subject: [PATCH 05/61] Fix weekly charts to display the same value for every day Android < 7 Closes #604 --- .../activities/charts/AbstractWeekChartFragment.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java index 9e2f15686..b43816372 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java @@ -287,16 +287,17 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { ActivityAmounts amounts = null; Activity activity = getActivity(); + int key = (int) (day.getTimeInMillis() / 1000) + (mOffsetHours * 3600); if (activity != null) { activityAmountCache = ((ChartsActivity) activity).mActivityAmountCache; - amounts = (ActivityAmounts) (activityAmountCache.lookup(day.hashCode() ^ mOffsetHours)); + amounts = (ActivityAmounts) (activityAmountCache.lookup(key)); } if (amounts == null) { ActivityAnalysis analysis = new ActivityAnalysis(); amounts = analysis.calculateActivityAmounts(getSamplesOfDay(db, day, mOffsetHours, device)); if (activityAmountCache != null) { - activityAmountCache.add(day.hashCode() ^ mOffsetHours, amounts); + activityAmountCache.add(key, amounts); } } From abd79ef5c926d0e5ad177b6aa4da8f345deab1a0 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sat, 18 Mar 2017 17:22:40 +0100 Subject: [PATCH 06/61] 0.18.3 --- CHANGELOG.md | 7 +++++-- app/build.gradle | 4 ++-- app/src/main/res/xml/changelog_master.xml | 5 ++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30bb65ad1..767e9ac49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,10 @@ ###Changelog -###Version 0.18.1 -* Mi2: Fix crash on "chat" or "social network" text notification #603 +###Version 0.18.3 +* Fix bug that caused the same value in weekly charts for every day on Android 6 and older + +###Version 0.18.2 +* Mi2: Fix crash on "chat" or "social network" text notification (#603) ###Version 0.18.1 * Pebble: Fix Firmware insstallation on Pebble Time Round (broken since 0.16.0) diff --git a/app/build.gradle b/app/build.gradle index c42d79b3a..d6ea9c869 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { targetSdkVersion 25 // note: always bump BOTH versionCode and versionName! - versionName "0.18.2" - versionCode 89 + versionName "0.18.3" + versionCode 90 vectorDrawables.useSupportLibrary = true } buildTypes { diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index 1154a27c9..e881747ab 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,7 +1,10 @@ + + Fix bug that caused the same value in weekly charts for every day on Android 6 and older + - Mi2: Fix crash on "chat" or "social network" text notification #603 + Mi2: Fix crash on "chat" or "social network" text notification (#603) Pebble: Fix Firmware insstallation on Pebble Time Round (broken since 0.16.0) From ad82a753123e19010af2e8ce64ef6860f62ccae0 Mon Sep 17 00:00:00 2001 From: Translation Bot Date: Sun, 19 Mar 2017 21:34:57 +0100 Subject: [PATCH 07/61] update translations from transifex (thanks!) --- app/src/main/res/values-es/strings.xml | 7 ++++++- app/src/main/res/values-fr/strings.xml | 10 ++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index d7b8e2425..ee79d4963 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -84,6 +84,7 @@ Modo de privacidad de llamada Mostrar nombre y número Ocultar nombre pero mostrar número + Ocultar el número pero mostrar el nombre Ocultar nombre y número Excluir aplicaciones Mensajes predeterminados @@ -247,7 +248,7 @@ Última carga: %s \n Número de cargas: %s Tu sueño - Dormir una semana + Sueño esta semana Sueño hoy, objetivo: %1$s Pasos por semana Tu actividad y sueño @@ -356,4 +357,8 @@ (%1$s) ¡Lo ha encontrado! Mi2: formato de hora + ¡Debes instalar la versión %1$s antes de instalar este firmware! + Notificaciones textuales + = 1.0.1.28 and Mili_pro.ft* installed.]]> + off diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 634fc00cf..94bfb91c7 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -84,6 +84,7 @@ Mode de confidentialité d\'appel Afficher le nom et le numéro Masquer le nom mais afficher le numéro + Masquer le numéro mais afficher le nom Masquer le nom et le numéro Applications bloquées Modèles de messages @@ -247,7 +248,7 @@ Dernière charge: %s \n Nombre de charges: %s Votre sommeil - Dormir une semaine + Sommeil cette semaine Sommeil aujourd\'hui, objectif: %1$s Pas de la semaine Votre activité et sommeil @@ -306,7 +307,8 @@ authentification requise ZzZz Ajouter un widget - Préférer le mode heure pendant le sommeil + +Temps de sommeil péféré en heures Une alarme a été enregistré pour %1$02d:%2$02d Modèle: %1$s Micrologiciel: %1$s @@ -357,4 +359,8 @@ NOTE: la base de données sera bien évidement plus grande ! (%1$s) Vous l\'avez trouvé! Mi2: format de l\'heure + Vous devez installer la version %1$s avant d\'installer ce micrologiciel! + Notifications textuelles + = 1.0.1.28 and Mili_pro.ft* installed.]]> + off From 7c63f92aaa7b6188cf931d46c534b62cd998d6b8 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 20 Mar 2017 22:27:17 +0100 Subject: [PATCH 08/61] Remove obsolte and unused code related to old and unsupported activity database --- .../gadgetbridge/devices/SampleProvider.java | 16 +--------------- .../devices/UnknownDeviceCoordinator.java | 5 ----- .../devices/hplus/HPlusHealthSampleProvider.java | 7 ------- .../devices/miband/MiBand2SampleProvider.java | 7 ------- .../devices/miband/MiBandSampleProvider.java | 6 ------ .../pebble/PebbleHealthSampleProvider.java | 6 ------ .../pebble/PebbleMisfitSampleProvider.java | 6 ------ .../pebble/PebbleMorpheuzSampleProvider.java | 6 ------ 8 files changed, 1 insertion(+), 58 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/SampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/SampleProvider.java index ce71afd37..3af113b31 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/SampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/SampleProvider.java @@ -34,24 +34,10 @@ import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; * @param the device/provider specific sample type (must extend AbstractActivitySample) */ public interface SampleProvider { - // TODO: these constants can all be removed - int PROVIDER_MIBAND = 0; + // These are only used for SharedPreferences int PROVIDER_PEBBLE_MORPHEUZ = 1; - int PROVIDER_PEBBLE_GADGETBRIDGE = 2; // removed int PROVIDER_PEBBLE_MISFIT = 3; int PROVIDER_PEBBLE_HEALTH = 4; - int PROVIDER_MIBAND2 = 5; - int PROVIDER_HPLUS = 6; - - int PROVIDER_UNKNOWN = 100; - // TODO: can also be removed - - /** - * Returns the "id" of this sample provider, as used in Gadgetbridge versions < 0.12.0. - * Only used for importing old samples. - * @deprecated - */ - int getID(); int normalizeType(int rawType); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java index 9451190e6..108423d0c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java @@ -87,11 +87,6 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator { public AbstractActivitySample getLatestActivitySample() { return null; } - - @Override - public int getID() { - return PROVIDER_UNKNOWN; - } } public UnknownDeviceCoordinator() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java index 4a2851fa0..2946731e0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java @@ -21,7 +21,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.hplus; */ import android.support.annotation.NonNull; -import android.util.Log; import java.util.Calendar; import java.util.Collections; @@ -34,7 +33,6 @@ import de.greenrobot.dao.Property; import de.greenrobot.dao.query.QueryBuilder; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.HPlusHealthActivityOverlay; @@ -58,11 +56,6 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) { List samples = super.getGBActivitySamples(timestamp_from, timestamp_to, activityType); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandSampleProvider.java index 53b15cdd9..4842e5fa9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandSampleProvider.java @@ -17,7 +17,6 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.miband; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; @@ -42,11 +41,6 @@ public class MiBandSampleProvider extends AbstractMiBandSampleProvider { super(device, session); } - @Override - public int getID() { - return SampleProvider.PROVIDER_MIBAND; - } - @Override public int normalizeType(int rawType) { switch (rawType) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleHealthSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleHealthSampleProvider.java index c249322f8..94ee43f2c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleHealthSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleHealthSampleProvider.java @@ -25,7 +25,6 @@ import de.greenrobot.dao.Property; import de.greenrobot.dao.query.QueryBuilder; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlay; @@ -139,9 +138,4 @@ public class PebbleHealthSampleProvider extends AbstractSampleProvider getSampleDao() { return getSession().getPebbleMisfitSampleDao(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMorpheuzSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMorpheuzSampleProvider.java index 206b4babd..b8dd72cb8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMorpheuzSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleMorpheuzSampleProvider.java @@ -19,7 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.pebble; import de.greenrobot.dao.AbstractDao; import de.greenrobot.dao.Property; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSample; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSampleDao; @@ -64,11 +63,6 @@ public class PebbleMorpheuzSampleProvider extends AbstractSampleProvider Date: Mon, 20 Mar 2017 22:41:54 +0100 Subject: [PATCH 09/61] Mi2: Display realtime steps in Live Activity #428 Thanks for the hint! --- .../devices/miband/MiBand2Service.java | 2 +- .../service/devices/miband/MiBandSupport.java | 3 +- .../devices/miband2/MiBand2Support.java | 48 +++++++++++++------ .../gadgetbridge/test/Tryout.java | 1 + 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java index 84d1d781e..62f260ee6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java @@ -43,7 +43,7 @@ public class MiBand2Service { public static final UUID UUID_UNKNOWN_CHARACTERISTIC4 = UUID.fromString("00000004-0000-3512-2118-0009af100700"); public static final UUID UUID_CHARACTERISTIC_5_ACTIVITY_DATA = UUID.fromString("00000005-0000-3512-2118-0009af100700"); public static final UUID UUID_CHARACTERISTIC_6_BATTERY_INFO = UUID.fromString("00000006-0000-3512-2118-0009af100700"); - public static final UUID UUID_UNKNOWN_CHARACTERISTIC7 = UUID.fromString("00000007-0000-3512-2118-0009af100700"); + public static final UUID UUID_CHARACTERISTIC_7_REALTIME_STEPS = UUID.fromString("00000007-0000-3512-2118-0009af100700"); public static final UUID UUID_UNKNOWN_CHARACTERISTIC8 = UUID.fromString("00000008-0000-3512-2118-0009af100700"); // service uuid fee1 public static final UUID UUID_CHARACTERISTIC_AUTH = UUID.fromString("00000009-0000-3512-2118-0009af100700"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java index 2df2fee52..b8827b161 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java @@ -73,6 +73,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; @@ -965,7 +966,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { } private void handleRealtimeSteps(byte[] value) { - int steps = 0xff & value[0] | (0xff & value[1]) << 8; + int steps = BLETypeConversions.toUint16(value); if (LOG.isDebugEnabled()) { LOG.debug("realtime steps: " + steps); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java index 9ef66da91..2f849a432 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java @@ -42,6 +42,7 @@ import java.util.UUID; import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; @@ -84,9 +85,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactionAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory; -import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile; -import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert; -import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.OverflowStrategy; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.HeartRateProfile; import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; @@ -689,6 +687,17 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { @Override public void onEnableRealtimeSteps(boolean enable) { + try { + TransactionBuilder builder = performInitialized(enable ? "Enabling realtime steps notifications" : "Disabling realtime steps notifications"); + if (enable) { + builder.read(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS)); + } + builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS), enable); + builder.queue(getQueue()); + enableRealtimeSamplesTimer(enable); + } catch (IOException e) { + LOG.error("Unable to change realtime steps notification to: " + enable, e); + } } private byte[] getHighLatency() { @@ -783,9 +792,6 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } else if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) { handleHeartrate(characteristic.getValue()); return true; -// } else if (MiBand2Service.UUID_UNKNOQN_CHARACTERISTIC0.equals(characteristicUUID)) { -// handleUnknownCharacteristic(characteristic.getValue()); -// return true; } else if (MiBand2Service.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) { LOG.info("AUTHENTICATION?? " + characteristicUUID); logMessageContent(characteristic.getValue()); @@ -793,6 +799,9 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } else if (MiBand2Service.UUID_CHARACTERISTIC_10_BUTTON.equals(characteristicUUID)) { handleButtonPressed(characteristic.getValue()); return true; + } else if (MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) { + handleRealtimeSteps(characteristic.getValue()); + return true; } else { LOG.info("Unhandled characteristic changed: " + characteristicUUID); logMessageContent(characteristic.getValue()); @@ -824,6 +833,9 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } else if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) { logHeartrate(characteristic.getValue(), status); return true; + } else if (MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) { + handleRealtimeSteps(characteristic.getValue()); + return true; } else if (MiBand2Service.UUID_CHARACTERISTIC_10_BUTTON.equals(characteristicUUID)) { handleButtonPressed(characteristic.getValue()); return true; @@ -874,11 +886,21 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } private void handleRealtimeSteps(byte[] value) { - int steps = 0xff & value[0] | (0xff & value[1]) << 8; - if (LOG.isDebugEnabled()) { - LOG.debug("realtime steps: " + steps); + if (value == null) { + LOG.error("realtime steps: value is null"); + return; + } + + if (value.length == 13) { + byte[] stepsValue = new byte[] {value[1], value[2]}; + int steps = BLETypeConversions.toUint16(stepsValue); + if (LOG.isDebugEnabled()) { + LOG.debug("realtime steps: " + steps); + } + getRealtimeSamplesSupport().setSteps(steps); + } else { + LOG.warn("Unrecognized realtime steps value: " + Logging.formatBytes(value)); } - getRealtimeSamplesSupport().setSteps(steps); } private void enableRealtimeSamplesTimer(boolean enable) { @@ -1073,10 +1095,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { @Override public void onTestNewFunction() { try { - TransactionBuilder builder = performInitialized("incoming call from peter"); - NewAlert alert = new NewAlert(AlertCategory.Custom, 1, new String(new byte[] {0x19})); - AlertNotificationProfile profile = new AlertNotificationProfile<>(this); - profile.newAlert(builder, alert, OverflowStrategy.MAKE_MULTIPLE); + TransactionBuilder builder = performInitialized("test realtime steps"); + builder.read(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS)); builder.queue(getQueue()); } catch (IOException e) { } diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/Tryout.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/Tryout.java index fc7153dae..af346b139 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/Tryout.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/Tryout.java @@ -8,6 +8,7 @@ import java.util.GregorianCalendar; import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandDateConverter; +import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; /** From 14552a1a804697ae64bbbcb2dc39925e1ab760dd Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Mon, 20 Mar 2017 22:58:45 +0100 Subject: [PATCH 10/61] Disable live activity tracking when activity is paused Fixes #496 --- .../charts/LiveActivityFragment.java | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java index 980ca8b9f..c91023035 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java @@ -282,13 +282,14 @@ public class LiveActivityFragment extends AbstractChartFragment { @Override public void onPause() { + enableRealtimeTracking(false); super.onPause(); - stopActivityPulse(); } @Override public void onResume() { super.onResume(); + enableRealtimeTracking(true); } private ScheduledExecutorService startActivityPulse() { @@ -345,23 +346,34 @@ public class LiveActivityFragment extends AbstractChartFragment { @Override protected void onMadeVisibleInActivity() { - GBApplication.deviceService().onEnableRealtimeSteps(true); - GBApplication.deviceService().onEnableRealtimeHeartRateMeasurement(true); super.onMadeVisibleInActivity(); - if (getActivity() != null) { - getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + enableRealtimeTracking(true); + } + + private void enableRealtimeTracking(boolean enable) { + if (enable && pulseScheduler != null) { + // already running + return; + } + + GBApplication.deviceService().onEnableRealtimeSteps(enable); + GBApplication.deviceService().onEnableRealtimeHeartRateMeasurement(enable); + if (enable) { + if (getActivity() != null) { + getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + pulseScheduler = startActivityPulse(); + } else { + stopActivityPulse(); + if (getActivity() != null) { + getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } } - pulseScheduler = startActivityPulse(); } @Override protected void onMadeInvisibleInActivity() { - stopActivityPulse(); - GBApplication.deviceService().onEnableRealtimeSteps(false); - GBApplication.deviceService().onEnableRealtimeHeartRateMeasurement(false); - if (getActivity() != null) { - getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } + enableRealtimeTracking(false); super.onMadeInvisibleInActivity(); } From da9742fd67ebc6328e65f7b7ff6ec47dd7c82e22 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Mon, 20 Mar 2017 23:25:42 +0100 Subject: [PATCH 11/61] Mi1: Attempt to recognize Mi1 model with hwVersion = 8 Closes #364 --- .../gadgetbridge/service/devices/miband/DeviceInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/DeviceInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/DeviceInfo.java index d04ece47d..919a22965 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/DeviceInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/DeviceInfo.java @@ -117,7 +117,7 @@ public class DeviceInfo extends AbstractInfo { } public boolean isMili1() { - return hwVersion == 2; + return hwVersion == 2 || (feature == 0 && appearance == 0 && hwVersion == 8 && fw2Version == -1); } public boolean isMili1A() { From 75089d7cb4053dc379c168b31bf0c0c7dad7ac69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Paulo=20Barraca?= Date: Fri, 24 Mar 2017 18:10:05 +0000 Subject: [PATCH 12/61] Add HPlus and LiveView icons to level list --- app/src/main/res/drawable/level_list_device.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/drawable/level_list_device.xml b/app/src/main/res/drawable/level_list_device.xml index 7de9a84f2..0c5208894 100644 --- a/app/src/main/res/drawable/level_list_device.xml +++ b/app/src/main/res/drawable/level_list_device.xml @@ -5,10 +5,17 @@ + + + + + + + \ No newline at end of file From 11b48e7a1a7e14e245340e620679fe6ac4f19482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Paulo=20Barraca?= Date: Fri, 24 Mar 2017 20:52:14 +0000 Subject: [PATCH 13/61] Set HPlus Sleep Intensity to 10% --- .../gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java index 2946731e0..09f857ef2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java @@ -193,6 +193,9 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider= overlay.getTimestampFrom() && sample.getTimestamp() < overlay.getTimestampTo()) { + if(overlay.getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP || overlay.getRawKind() == ActivityKind.TYPE_DEEP_SLEEP) + sample.setRawIntensity(10); + sample.setRawKind(overlay.getRawKind()); } } From d550defcb3bdb5529b5ce59280a31916ff5e5ed9 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sun, 26 Mar 2017 17:57:03 +0200 Subject: [PATCH 14/61] Do not save an alarm as "smart" if the device does not support it (#612) Opening the activity when a device that does not support smart alarms is connected hides the "smart alarm" toggle. This is now reflected also on the saved data. This solution is not ideal in case of multiple devices but as long as #577 is not solved its the best we can do. --- CHANGELOG.md | 3 +++ .../freeyourgadget/gadgetbridge/activities/AlarmDetails.java | 2 +- app/src/main/res/xml/changelog_master.xml | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 767e9ac49..b3a95f41a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ###Changelog +###Version next +* Alarms activity improvements and fixes + ###Version 0.18.3 * Fix bug that caused the same value in weekly charts for every day on Android 6 and older diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java index 43744716a..d14db9dc6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java @@ -105,7 +105,7 @@ public class AlarmDetails extends GBActivity { } private void updateAlarm() { - alarm.setSmartWakeup(cbSmartWakeup.isChecked()); + alarm.setSmartWakeup(supportsSmartWakeup() && cbSmartWakeup.isChecked()); alarm.setRepetition(cbMonday.isChecked(), cbTuesday.isChecked(), cbWednesday.isChecked(), cbThursday.isChecked(), cbFriday.isChecked(), cbSaturday.isChecked(), cbSunday.isChecked()); alarm.setHour(timePicker.getCurrentHour()); alarm.setMinute(timePicker.getCurrentMinute()); diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index e881747ab..22c00ad66 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,5 +1,8 @@ + + Alarms activity improvements and fixes + Fix bug that caused the same value in weekly charts for every day on Android 6 and older From 1813ec9378b70bb66f0a9b014bb17b03859b9a31 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sun, 26 Mar 2017 20:29:57 +0200 Subject: [PATCH 15/61] Forbid landscape orientation on AlarmDetails activity. Landscape mode triggers a bug in android DatePicker on devices with small screens. Fixes #612 --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index df30fac78..b15323fc7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -337,6 +337,7 @@ Date: Mon, 27 Mar 2017 13:56:03 +0200 Subject: [PATCH 16/61] Enlarge the "hit box" of each icon (replace some margin pixels with padding). Fixes #615 --- app/src/main/res/layout/device_itemv2.xml | 51 +++++++++++++---------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/app/src/main/res/layout/device_itemv2.xml b/app/src/main/res/layout/device_itemv2.xml index a8979189d..f5c8fe30f 100644 --- a/app/src/main/res/layout/device_itemv2.xml +++ b/app/src/main/res/layout/device_itemv2.xml @@ -111,17 +111,18 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/device_image" - android:layout_marginBottom="8dp" - android:layout_marginStart="8dp" + android:layout_marginBottom="4dp" + android:layout_marginStart="4dp" android:layout_marginEnd="0dp" - android:layout_marginTop="8dp" + android:layout_marginTop="4dp" + android:padding="4dp" android:minWidth="48dp" android:orientation="vertical"> @@ -142,7 +143,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/device_image" - android:layout_margin="8dp" + android:layout_margin="4dp" + android:padding="4dp" android:layout_toEndOf="@id/device_battery_status_box" android:gravity="center_vertical" android:minWidth="36dp" @@ -150,8 +152,8 @@ Date: Mon, 27 Mar 2017 22:15:03 +0200 Subject: [PATCH 17/61] update changelog, bump version to 0.18.4 --- CHANGELOG.md | 15 +++++++++------ app/build.gradle | 4 ++-- app/src/main/res/xml/changelog_master.xml | 5 ++++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3a95f41a..ef8dbf97c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,16 @@ ###Changelog -###Version next +###Version 0.18.4 +* Mi Band 2: Display realtime steps in Live Activity +* Mi Band: Attempt to recognize Mi Band model with hwVersion = 8 * Alarms activity improvements and fixes +* Make Buttons in the main activity easier to hit ###Version 0.18.3 * Fix bug that caused the same value in weekly charts for every day on Android 6 and older ###Version 0.18.2 -* Mi2: Fix crash on "chat" or "social network" text notification (#603) +* Mi Band 2: Fix crash on "chat" or "social network" text notification (#603) ###Version 0.18.1 * Pebble: Fix Firmware insstallation on Pebble Time Round (broken since 0.16.0) @@ -24,10 +27,10 @@ * Huge speedup for weekly charts when changing days * Drop support for importing pre Gadgetbridge 0.12.0 database * Pebble: allow configuration web pages (clay) to access device location -* Mi2: Initial support for text notifications, caller ID, and icons (requires font installation) (#560) -* Mi2: Support for flashing Mili_pro.ft* font files -* Mi2: Improved firmware/font updated -* Mi2: Set 12h/24h time format, following the Android configuration (#573) +* Mi Band 2: Initial support for text notifications, caller ID, and icons (requires font installation) (#560) +* Mi Band 2: Support for flashing Mili_pro.ft* font files +* Mi Band 2: Improved firmware/font updated +* Mi Band 2: Set 12h/24h time format, following the Android configuration (#573) * Improved BLE discovery and connectivity ####Version 0.17.5 diff --git a/app/build.gradle b/app/build.gradle index d6ea9c869..c53951140 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { targetSdkVersion 25 // note: always bump BOTH versionCode and versionName! - versionName "0.18.3" - versionCode 90 + versionName "0.18.4" + versionCode 91 vectorDrawables.useSupportLibrary = true } buildTypes { diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index 22c00ad66..218c76fa5 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,6 +1,9 @@ - + + Mi Band 2: Display realtime steps in Live Activity + Mi Band: Attempt to recognize Mi Band model with hwVersion = 8 + Make Buttons in the main activity easier to hit Alarms activity improvements and fixes From b25bc66485cf1fb5657aaa485cf616d7e67d9956 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 28 Mar 2017 09:51:06 +0200 Subject: [PATCH 18/61] Allow Datalog handlers to return GBDeviceEvent[] --- .../devices/pebble/DatalogSession.java | 9 ++++---- .../pebble/DatalogSessionHealthHR.java | 5 +++-- .../DatalogSessionHealthOverlayData.java | 9 ++++---- .../pebble/DatalogSessionHealthSleep.java | 9 ++++---- .../pebble/DatalogSessionHealthSteps.java | 11 +++++----- .../devices/pebble/PebbleProtocol.java | 21 +++++++++---------- 6 files changed, 34 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSession.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSession.java index ab613a65f..a5fdd1d44 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSession.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSession.java @@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; import java.util.UUID; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.pebble.GBDeviceEventDataLogging; class DatalogSession { @@ -44,15 +45,15 @@ class DatalogSession { this.itemSize = itemSize; } - boolean handleMessage(ByteBuffer buf, int length) { - return true; + GBDeviceEvent[] handleMessage(ByteBuffer buf, int length) { + return new GBDeviceEvent[]{null}; } String getTaginfo() { return taginfo; } - GBDeviceEventDataLogging handleMessageForPebbleKit(ByteBuffer buf, int length) { + GBDeviceEvent[] handleMessageForPebbleKit(ByteBuffer buf, int length) { if (0 != (length % itemSize)) { LOG.warn("invalid length"); return null; @@ -89,6 +90,6 @@ class DatalogSession { break; } } - return dataLogging; + return new GBDeviceEvent[]{dataLogging, null}; } } \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthHR.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthHR.java index b769d13b0..82146827a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthHR.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthHR.java @@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; import java.util.UUID; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -35,9 +36,9 @@ class DatalogSessionHealthHR extends DatalogSessionPebbleHealth { } @Override - public boolean handleMessage(ByteBuffer datalogMessage, int length) { + public GBDeviceEvent[] handleMessage(ByteBuffer datalogMessage, int length) { LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length)); - return isPebbleHealthEnabled(); + return isPebbleHealthEnabled() ? new GBDeviceEvent[]{null} : null; } } \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java index 958a1e12d..ac1a1d811 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java @@ -29,6 +29,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlay; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlayDao; @@ -45,11 +46,11 @@ class DatalogSessionHealthOverlayData extends DatalogSessionPebbleHealth { } @Override - public boolean handleMessage(ByteBuffer datalogMessage, int length) { + public GBDeviceEvent[] handleMessage(ByteBuffer datalogMessage, int length) { LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length)); if (!isPebbleHealthEnabled()) { - return false; + return null; } int initialPosition = datalogMessage.position(); @@ -58,7 +59,7 @@ class DatalogSessionHealthOverlayData extends DatalogSessionPebbleHealth { short recordType; //probably: 1=sleep, 2=deep sleep, 5=??run??ignored for now if (0 != (length % itemSize)) - return false;//malformed message? + return null;//malformed message? int recordCount = length / itemSize; OverlayRecord[] overlayRecords = new OverlayRecord[recordCount]; @@ -72,7 +73,7 @@ class DatalogSessionHealthOverlayData extends DatalogSessionPebbleHealth { } store(overlayRecords); - return true; + return new GBDeviceEvent[]{null}; } private void store(OverlayRecord[] overlayRecords) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java index 8ee24e561..882302d0a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java @@ -29,6 +29,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlay; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlayDao; @@ -45,11 +46,11 @@ class DatalogSessionHealthSleep extends DatalogSessionPebbleHealth { } @Override - public boolean handleMessage(ByteBuffer datalogMessage, int length) { + public GBDeviceEvent[] handleMessage(ByteBuffer datalogMessage, int length) { LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length)); if (!isPebbleHealthEnabled()) { - return false; + return null; } int initialPosition = datalogMessage.position(); @@ -57,7 +58,7 @@ class DatalogSessionHealthSleep extends DatalogSessionPebbleHealth { short recordVersion; //probably if (0 != (length % itemSize)) - return false;//malformed message? + return null;//malformed message? int recordCount = length / itemSize; SleepRecord[] sleepRecords = new SleepRecord[recordCount]; @@ -72,7 +73,7 @@ class DatalogSessionHealthSleep extends DatalogSessionPebbleHealth { } store(sleepRecords); - return true; + return new GBDeviceEvent[]{null}; } private void store(SleepRecord[] sleepRecords) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java index 8581e4f03..2c033eff4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java @@ -28,6 +28,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleHealthSampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; @@ -43,11 +44,11 @@ class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth { } @Override - public boolean handleMessage(ByteBuffer datalogMessage, int length) { + public GBDeviceEvent[] handleMessage(ByteBuffer datalogMessage, int length) { LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length)); if (!isPebbleHealthEnabled()) { - return false; + return null; } int timestamp; @@ -57,7 +58,7 @@ class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth { int initialPosition = datalogMessage.position(); if (0 != (length % itemSize)) - return false;//malformed message? + return null;//malformed message? int packetCount = length / itemSize; @@ -68,7 +69,7 @@ class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth { recordVersion = datalogMessage.getShort(); if ((recordVersion != 5) && (recordVersion != 6) && (recordVersion != 7) && (recordVersion != 12) && (recordVersion != 13)) - return false; //we don't know how to deal with the data TODO: this is not ideal because we will get the same message again and again since we NACK it + return null; //we don't know how to deal with the data TODO: this is not ideal because we will get the same message again and again since we NACK it timestamp = datalogMessage.getInt(); datalogMessage.get(); //unknown, throw away @@ -88,7 +89,7 @@ class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth { store(stepsRecords); } - return true;//ACK by default + return new GBDeviceEvent[]{null};//ACK by default } private void store(StepsRecord[] stepsRecords) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 3fd9900c9..04d95805b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -2232,10 +2232,9 @@ public class PebbleProtocol extends GBDeviceProtocol { } private GBDeviceEvent[] decodeDatalog(ByteBuffer buf, short length) { - boolean ack = true; byte command = buf.get(); byte id = buf.get(); - GBDeviceEventDataLogging devEvtDataLogging = null; + GBDeviceEvent[] devEvtsDataLogging = null; switch (command) { case DATALOG_TIMEOUT: LOG.info("DATALOG TIMEOUT. id=" + (id & 0xff) + " - ignoring"); @@ -2249,12 +2248,9 @@ public class PebbleProtocol extends GBDeviceProtocol { if (datalogSession != null) { LOG.info("DATALOG UUID=" + datalogSession.uuid + ", tag=" + datalogSession.tag + datalogSession.getTaginfo() + ", itemSize=" + datalogSession.itemSize + ", itemType=" + datalogSession.itemType); if (!datalogSession.uuid.equals(UUID_ZERO) && datalogSession.getClass().equals(DatalogSession.class) && mEnablePebbleKit) { - devEvtDataLogging = datalogSession.handleMessageForPebbleKit(buf, length - 10); - if (devEvtDataLogging == null) { - ack = false; - } + devEvtsDataLogging = datalogSession.handleMessageForPebbleKit(buf, length - 10); } else { - ack = datalogSession.handleMessage(buf, length - 10); + devEvtsDataLogging = datalogSession.handleMessage(buf, length - 10); } } break; @@ -2289,7 +2285,7 @@ public class PebbleProtocol extends GBDeviceProtocol { dataLogging.command = GBDeviceEventDataLogging.COMMAND_FINISH_SESSION; dataLogging.appUUID = datalogSession.uuid; dataLogging.tag = datalogSession.tag; - devEvtDataLogging = dataLogging; + devEvtsDataLogging = new GBDeviceEvent[]{dataLogging, null}; } mDatalogSessions.remove(id); } @@ -2299,15 +2295,18 @@ public class PebbleProtocol extends GBDeviceProtocol { break; } GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes(); - if (ack) { + + if (devEvtsDataLogging != null) { + // append ack LOG.info("sending ACK (0x85)"); sendBytes.encodedBytes = encodeDatalog(id, DATALOG_ACK); + devEvtsDataLogging[devEvtsDataLogging.length - 1] = sendBytes; } else { LOG.info("sending NACK (0x86)"); sendBytes.encodedBytes = encodeDatalog(id, DATALOG_NACK); + devEvtsDataLogging = new GBDeviceEvent[]{sendBytes}; } - // append ack/nack - return new GBDeviceEvent[]{devEvtDataLogging, sendBytes}; + return devEvtsDataLogging; } private GBDeviceEvent decodeAppReorder(ByteBuffer buf) { From eae119f9df54b5330eb555b391cbc522cf885f5f Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Wed, 29 Mar 2017 08:53:13 +0200 Subject: [PATCH 19/61] Add some preliminary checks/links to the issue template --- .github/ISSUE_TEMPLATE.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 3d46d303f..3a9463eea 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,7 @@ +#### Before opening an issue please confirm the following: +- [ ] I have read the [wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki), and I didn't find a solution to my problem / an answer to my question. +- [ ] I have searched the [issues](https://github.com/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question. + #### Your issue is: *In case of a bug, do not forget to attach logs!* @@ -8,3 +12,7 @@ #### Your android version is: #### Your Gadgetbridge version is: + + + +*New issues about already solved/documented topics could be closed without further comments. Same for too generic or incomplete reports.* From 447885033bb7323b1f213934e8c914de2cdffa38 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Wed, 29 Mar 2017 08:59:53 +0200 Subject: [PATCH 20/61] Add links to the wiki sections next to supported devices line --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d004dc0fd..080f44a9f 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,13 @@ need to create an account and transmit any of your data to the vendor's servers. [List of changes](CHANGELOG.md) ## Supported Devices -* Pebble, Pebble Steel, Pebble Time, Pebble Time Steel, Pebble Time Round -* Pebble 2, Pebble Time 2 (experimental, PAIR WITHIN GADGETBRIDGE) -* Mi Band, Mi Band 1A, Mi Band 1S -* Mi Band 2 +* Pebble, Pebble Steel, Pebble Time, Pebble Time Steel, Pebble Time Round [Wiki section about this device](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Pebble) +* Pebble 2, Pebble Time 2 (experimental, PAIR WITHIN GADGETBRIDGE) [Wiki section about pebble](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Pebble), most parts apply to Pebble 2 as well +* Mi Band, Mi Band 1A, Mi Band 1S [Wiki section about this device](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band) +* Mi Band 2 [Wiki section about mi band](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band), some parts apply to mi band 2 as well * Vibratissimo (experimental) * Liveview -* HPlus Devices (e.g. ZeBand) +* HPlus Devices (e.g. ZeBand) [Wiki section about this device](https://github.com/Freeyourgadget/Gadgetbridge/wiki/HPlus) ## Features (Pebble) From ab3f6c0bbfcbed955202b70e6b528014c2d90ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Paulo=20Barraca?= Date: Thu, 30 Mar 2017 14:45:02 +0100 Subject: [PATCH 21/61] Fixes #629 --- app/src/main/res/values-pt-rBR/strings.xml | 2 +- app/src/main/res/values-pt/strings.xml | 126 ++++++++++----------- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 2e451f1cf..942572bdf 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -289,7 +289,7 @@ Sobre para transferir dados desde %1$s aguarde para reconectar Sobre você - Ano de anoversário + Ano de aniversário Gênero Altura em cm Peso em kg diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index a4752e630..b773377ff 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5,9 +5,9 @@ Sair Sincronizar Monitor de sono (ALPHA) - Buscando dispositivo perdido... - Print da tela - Desconectar + Procurando dispositivo perdido... + Captura de ecrã + Desligar Apagar dispositivo Apagar %1$s Isto irá apagar o dispositivo e apagar os dados associados! @@ -20,29 +20,29 @@ Apagar Apagar e remover do cache Reinstalar - Buscar na loja Pebble + Procurar na loja Pebble Ativar Desativar Ativar HRM Desativar HRM - Ativas app de clima do sistema + Ativar app de clima do sistema Desativar app de clima do sistema Instalar notificações do app de clima Configurar Mover para o topo - Blacklist de notificações + Bloqueio de notificações Instalador FW/App - Você está prestes a instalar o firmware %s no lugar do atual em sua Mi Band. - O firmware foi testado e é compatível com Gadgetbridge. + Está prestes a instalar o firmware %s no lugar do atual na sua Mi Band. + O firmware foi testado e é compatível com o Gadgetbridge. Configurações Configurações Gerais - Conecte o dispositivo com o ligar o Bluetooth + Ligar ao dispositivo ao ativar o Bluetooth Iniciar automaticamente - Reconectar automaticamente - Player de música preferencial + Religar automaticamente + Aplicação de música preferencial Padrão Data e Hora Sincronizar hora @@ -51,33 +51,33 @@ Escuro Idioma Ocultar notificações do Gadgetbridge - Exibir ícone na barra de status e nas notificações na tela inicial - Ocultar ícone na barra de status e nas notificações na tela inicial + Exibir ícone na barra de status e nas notificações no ecrã inicial + Ocultar ícone na barra de status e nas notificações no ecrã inicial Notificações Repetições - Chamadas de telefone + Chamadas telefónicas SMS Mensagens do Pebble Suportar notificações de aplicações que enviam notificações pelo PebbleKit. Suportar notificações genéricas - ... e quando a tela estiver ligada + ... e quando o ecrã estiver ligado Não perturbe - Parar com notificações indesejadas enquanto estiver no modo Não Perturbe. + Ignorar notificações indesejadas enquanto estiver no modo Não Perturbe. sempre - quando a tela estiver desligada + quando o ecrã estiver desligado nunca Privacidade Modo de chamada privada Exibir nome e número Ocultar nome e exibir número Ocultar nome e número - Apps em Blacklist + Aplicações ignoradas Histórico de mensagens Respostas Sufixo comum Chamadas recusadas Atualizar no Pebble - Opções do desenvolvedor + Opções do programador Endereço do Mi Band Configurações Pebble Ativar monitores @@ -85,48 +85,48 @@ Sincronizar com Pebble Health Sincronizar com Misfit Sincronizar com Morpheuz - Habilitar suporte experimental ao App Android que use PebbleKit + Ativar suporte experimental a Apps Android que usem PebbleKit Despertar e pôr do sol - Enviar despertar e pôr do sol baseado na localização do pebble + Enviar despertar e pôr do sol com base na localização do pebble Auto remover notificações rejeitadas Notificações são automaticamente removidas quando rejeitadas no Android Modo de privacidade Notificações - Deslocar texto de notificações que extrapolar a tela + Deslocar texto de notificações que extravasar o ecrã Apenas mostrar ícone de notificações Localização Obter localização Latitude Longitude Mantenha a localização atualizada - Tente obter a localização online, use dados armazenados como fallback - Por favor, habilite localização de rede + Tente obter a localização online, use dados armazenados como alternativa + Por favor, ative a localização de rede localização obtida Forçar o protocolo de notificação - Esta opção força o uso do protocolo de notificação mais recente. HABILITE APENAS SE SABE O QUE ESTÁ FAZENDO! - Habilitar recursos não certificados - Habilitar recursos não certificados. FAÇA ISSO SE SOUBER O QUE REALMENTE ESTÁ FAZENDO! - Sempre preferir BLE + Esta opção força o uso do protocolo de notificação mais recente. APENAS ATIVE SE SOUBER O QUE ESTÁ A FAZER! + Permitir recursos não certificados + Permitir recursos não certificados. APENAS ATIVE SE SOUBER O QUE ESTÁ A FAZER! + Preferir sempre BLE Unidades Formato da hora - Duração de tela - desconectado - conectando - conectado + Duração do ecrã + desligado + a ligar + ligado estado desconhecido Teste - Teste de notificação + Teste de notificações Bluetooth não suportado - Bluetooth desabilitado + Bluetooth desligado falha na instalação! instalação bem sucedida inicializado Dispositivo encontrado - Parar com a busca - Iniciar busca - Conecte novo dispositivo - Parear dispositivo - Pareando com %s... + Terminar a procura + Iniciar a procura + Ligue o novo dispositivo + Emparelhar dispositivo + A emparelhar com %s... masculino feminino outro @@ -137,7 +137,7 @@ Nome/Apelido Quantidade de vibrações Monitor de sono - Escrever arquivos de Log + Escrever arquivos de registo Inicializando Pequeno Médio @@ -150,10 +150,10 @@ Notificação genérica Notificação de email Notificações de chamadas - Bate papo + Conversas Navegação Rede social - Sua atividade + A sua atividade Configurar Alarmes Configurar alarmes Detalhes do alarme @@ -165,16 +165,16 @@ Sex Sab despertar inteligente - Tem algum erro ao definir o alarme, tente novamente! + Existiu um erro ao definir o alarme, tente novamente! Alarme enviado para o dispositivo! - Sem data. Sincronizar com dispositivo? + Sem data. Sincronizar com o dispositivo? Objetivo de passos por dia - Sua Atividade (ALPHA) + A Sua Atividade (ALPHA) Não foi possível encontrar um manipulador para instalar o arquivo. - Gadget com bateria baixa! - Seu Sono + Dispositivo com bateria baixa! + O Seu Sono Passos na semana - Sua Atividade e Sono + A Sua Atividade e Sono Atualizando Firmware... Arquivo não pode ser instalado, o dispositivo não está pronto. Versão compatível @@ -184,44 +184,44 @@ Instalação do Firmware completa, reiniciando o dispositivo... Falha ao instalar o Firmware Passos - Atividade ao vivo + Atividade em Tempo Real Histórico de passos Passos/min atuais Total de passos Histórico de passos por minuto - Iniciar sua atividade + Iniciar a sua atividade Atividade Sono leve - Sono pesado + Sono profundo Não utilizado - Desconectado. - Todos os alarmes desabilitados + Desligado. + Todos os alarmes desligados Manter dados de atividade no dispositivo Firmware incompatível Este firmware não é compatível com seu dispositivo Alarmes reservados para eventos próximos Hora - aguarde para reconectar + aguarde para tornar a ligar Sobre você - Ano de anoversário - Gênero + Ano de nascimento + Género Altura em cm Peso em kg - autenticando - autenticação requerida + a autenticar + autenticação necessária Adicionar widget - Preferir duração de sono em horas - Atualização de Firmware em progresso + Preferir duração do sono em horas + Atualização de Firmware em curso Firmware não enviado Importar dados? - Sucesso ao importar. - Sobrepor + Dados importados com sucesso. + Escrever por cima Cancelar Apagar Vibração - Pareando Pebble + A emparelhar Pebble Métrico Imperial Alarme From 562049296c028a40f24ef92fefe481b80f162d7a Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 30 Mar 2017 23:01:40 +0200 Subject: [PATCH 22/61] Pebble: fix datalogging Was broken after 0.18.4 --- .../gadgetbridge/service/devices/pebble/PebbleProtocol.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 04d95805b..83b1f2bd8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -2275,6 +2275,7 @@ public class PebbleProtocol extends GBDeviceProtocol { mDatalogSessions.put(id, new DatalogSession(id, uuid, timestamp, log_tag, item_type, item_size)); } } + devEvtsDataLogging = new GBDeviceEvent[]{null}; break; case DATALOG_CLOSE: LOG.info("DATALOG_CLOSE. id=" + (id & 0xff)); From f80215b37a597a4ae5c4087e82b35209a6b35091 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Fri, 31 Mar 2017 18:17:53 +0200 Subject: [PATCH 23/61] Use standard recyclerview for app reordering - allow dragging by using a drag handler (as per best practice) - remove the custom draglistview dependency - update to the latest android support libraries --- app/build.gradle | 11 +-- .../AbstractAppManagerFragment.java | 91 ++++++++++++------ .../adapter/GBDeviceAppAdapter.java | 93 ++++++++++++------- .../drawable/ic_drag_handle_black_24dp.xml | 9 ++ .../main/res/layout/activity_appmanager.xml | 5 +- .../item_with_details_and_drag_handle.xml | 52 +++++++++++ 6 files changed, 188 insertions(+), 73 deletions(-) create mode 100644 app/src/main/res/drawable/ic_drag_handle_black_24dp.xml create mode 100644 app/src/main/res/layout/item_with_details_and_drag_handle.xml diff --git a/app/build.gradle b/app/build.gradle index c53951140..858c362c0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,11 +64,11 @@ dependencies { testCompile "org.robolectric:robolectric:3.2.2" compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:25.2.0' - compile 'com.android.support:cardview-v7:25.2.0' - compile 'com.android.support:recyclerview-v7:25.2.0' - compile 'com.android.support:support-v4:25.2.0' - compile 'com.android.support:design:25.2.0' + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:cardview-v7:25.3.1' + compile 'com.android.support:recyclerview-v7:25.3.1' + compile 'com.android.support:support-v4:25.3.1' + compile 'com.android.support:design:25.3.1' compile 'com.github.tony19:logback-android-classic:1.1.1-4' compile 'org.slf4j:slf4j-api:1.7.7' compile 'com.github.PhilJay:MPAndroidChart:v3.0.1' @@ -76,7 +76,6 @@ dependencies { compile 'de.cketti.library.changelog:ckchangelog:1.2.2' compile 'net.e175.klaus:solarpositioning:0.0.9' compile 'com.github.freeyourgadget:greendao:1998d7cd2d21f662c6044f6ccf3b3a251bbad341' - compile 'com.github.woxthebox:draglistview:1.2.9' compile 'org.apache.commons:commons-lang3:3.4' // compile project(":DaoCore") diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java index 4eea9ec33..c9ebb69af 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java @@ -27,7 +27,8 @@ import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.widget.LinearLayoutManager; -import android.view.HapticFeedbackConstants; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -35,8 +36,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.PopupMenu; -import com.woxthebox.draglistview.DragListView; - import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,6 +63,8 @@ public abstract class AbstractAppManagerFragment extends Fragment { = "nodomain.freeyourgadget.gadgetbridge.appmanager.action.refresh_applist"; private static final Logger LOG = LoggerFactory.getLogger(AbstractAppManagerFragment.class); + private ItemTouchHelper appManagementTouchHelper; + protected abstract List getSystemAppsInCategory(); protected abstract String getSortFilename(); @@ -72,9 +73,13 @@ public abstract class AbstractAppManagerFragment extends Fragment { protected abstract boolean filterApp(GBDeviceApp gbDeviceApp); + public void startDragging(RecyclerView.ViewHolder viewHolder) { + appManagementTouchHelper.startDrag(viewHolder); + } + protected void onChangedAppOrder() { List uuidList = new ArrayList<>(); - for (GBDeviceApp gbDeviceApp : mGBDeviceAppAdapter.getItemList()) { + for (GBDeviceApp gbDeviceApp : mGBDeviceAppAdapter.getAppList()) { uuidList.add(gbDeviceApp.getUUID()); } AppManagerActivity.rewriteAppOrderFile(getSortFilename(), uuidList); @@ -133,7 +138,6 @@ public abstract class AbstractAppManagerFragment extends Fragment { } }; - private DragListView appListView; protected final List appList = new ArrayList<>(); private GBDeviceAppAdapter mGBDeviceAppAdapter; protected GBDevice mGBDevice = null; @@ -237,10 +241,6 @@ public abstract class AbstractAppManagerFragment extends Fragment { super.onActivityCreated(savedInstanceState); mGBDevice = ((AppManagerActivity) getActivity()).getGBDevice(); - if (PebbleUtils.getFwMajor(mGBDevice.getFirmwareVersion()) < 3 && !isCacheManager()) { - appListView.setDragEnabled(false); - } - IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_REFRESH_APPLIST); @@ -261,31 +261,21 @@ public abstract class AbstractAppManagerFragment extends Fragment { View rootView = inflater.inflate(R.layout.activity_appmanager, container, false); - appListView = (DragListView) (rootView.findViewById(R.id.appListView)); + RecyclerView appListView = (RecyclerView) (rootView.findViewById(R.id.appListView)); appListView.setLayoutManager(new LinearLayoutManager(getActivity())); - mGBDeviceAppAdapter = new GBDeviceAppAdapter(appList, R.layout.item_with_details, R.id.item_image, this.getContext(), this); - appListView.setAdapter(mGBDeviceAppAdapter, false); - appListView.setCanDragHorizontally(false); - appListView.setDragListListener(new DragListView.DragListListener() { - @Override - public void onItemDragStarted(int position) { - } + mGBDeviceAppAdapter = new GBDeviceAppAdapter(appList, R.layout.item_with_details_and_drag_handle, this); + appListView.setAdapter(mGBDeviceAppAdapter); - @Override - public void onItemDragging(int itemPosition, float x, float y) { - } + ItemTouchHelper.Callback appItemTouchHelperCallback = new AppItemTouchHelperCallback(mGBDeviceAppAdapter); + appManagementTouchHelper = new ItemTouchHelper(appItemTouchHelperCallback); - @Override - public void onItemDragEnded(int fromPosition, int toPosition) { - onChangedAppOrder(); - } - }); + appManagementTouchHelper.attachToRecyclerView(appListView); return rootView; } protected void sendOrderToDevice(String concatFilename) { ArrayList uuids = new ArrayList<>(); - for (GBDeviceApp gbDeviceApp : mGBDeviceAppAdapter.getItemList()) { + for (GBDeviceApp gbDeviceApp : mGBDeviceAppAdapter.getAppList()) { uuids.add(gbDeviceApp.getUUID()); } if (concatFilename != null) { @@ -295,11 +285,11 @@ public abstract class AbstractAppManagerFragment extends Fragment { GBApplication.deviceService().onAppReorder(uuids.toArray(new UUID[uuids.size()])); } - public boolean openPopupMenu(View view, int position) { + public boolean openPopupMenu(View view, GBDeviceApp deviceApp) { PopupMenu popupMenu = new PopupMenu(getContext(), view); popupMenu.getMenuInflater().inflate(R.menu.appmanager_context, popupMenu.getMenu()); Menu menu = popupMenu.getMenu(); - final GBDeviceApp selectedApp = appList.get(position); + final GBDeviceApp selectedApp = deviceApp; if (!selectedApp.isInCache()) { menu.removeItem(R.id.appmanager_app_reinstall); @@ -352,12 +342,11 @@ public abstract class AbstractAppManagerFragment extends Fragment { } ); - view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); popupMenu.show(); return true; } - public boolean onContextItemSelected(MenuItem item, GBDeviceApp selectedApp) { + private boolean onContextItemSelected(MenuItem item, GBDeviceApp selectedApp) { switch (item.getItemId()) { case R.id.appmanager_app_delete_cache: String baseName; @@ -440,4 +429,46 @@ public abstract class AbstractAppManagerFragment extends Fragment { LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mReceiver); super.onDestroy(); } + + public class AppItemTouchHelperCallback extends ItemTouchHelper.Callback { + + private final GBDeviceAppAdapter gbDeviceAppAdapter; + + public AppItemTouchHelperCallback(GBDeviceAppAdapter gbDeviceAppAdapter) { + this.gbDeviceAppAdapter = gbDeviceAppAdapter; + } + + @Override + public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + //app reordering is not possible on old firmwares + if (PebbleUtils.getFwMajor(mGBDevice.getFirmwareVersion()) < 3 && !isCacheManager()) { + return 0; + } + //we only support up and down movement and only for moving, not for swiping apps away + return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0); + } + + @Override + public boolean isLongPressDragEnabled() { + return false; + } + + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) { + gbDeviceAppAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition()); + return true; + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { + //nothing to do + } + + @Override + public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + super.clearView(recyclerView, viewHolder); + onChangedAppOrder(); + } + + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java index cb1c9b939..403304809 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java @@ -16,15 +16,15 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.adapter; -import android.content.Context; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import com.woxthebox.draglistview.DragItemAdapter; - +import java.util.Collections; import java.util.List; import java.util.UUID; @@ -37,40 +37,41 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp; * Adapter for displaying GBDeviceApp instances. */ -public class GBDeviceAppAdapter extends DragItemAdapter { +public class GBDeviceAppAdapter extends RecyclerView.Adapter { private final int mLayoutId; - private final int mGrabHandleId; - private final Context mContext; + private final List appList; private final AbstractAppManagerFragment mParentFragment; - public GBDeviceAppAdapter(List list, int layoutId, int grabHandleId, Context context, AbstractAppManagerFragment parentFragment) { - super(true); // longpress + public List getAppList() { + return appList; + } + + public GBDeviceAppAdapter(List list, int layoutId, AbstractAppManagerFragment parentFragment) { mLayoutId = layoutId; - mGrabHandleId = grabHandleId; - mContext = context; + appList = list; mParentFragment = parentFragment; - setHasStableIds(true); - setItemList(list); } @Override public long getItemId(int position) { - return mItemList.get(position).getUUID().getLeastSignificantBits(); + return appList.get(position).getUUID().getLeastSignificantBits(); } @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + public int getItemCount() { + return appList.size(); + } + @Override + public GBDeviceAppAdapter.AppViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(mLayoutId, parent, false); - return new ViewHolder(view); + return new AppViewHolder(view); } @Override - public void onBindViewHolder(ViewHolder holder, int position) { - super.onBindViewHolder(holder, position); - GBDeviceApp deviceApp = mItemList.get(position); - + public void onBindViewHolder(final AppViewHolder holder, int position) { + final GBDeviceApp deviceApp = appList.get(position); holder.mDeviceAppVersionAuthorLabel.setText(GBApplication.getContext().getString(R.string.appversion_by_creator, deviceApp.getVersion(), deviceApp.getCreator())); // FIXME: replace with small icons @@ -93,29 +94,51 @@ public class GBDeviceAppAdapter extends DragItemAdapter.ViewHolder { - TextView mDeviceAppVersionAuthorLabel; - TextView mDeviceAppNameLabel; - ImageView mDeviceImageView; + public void onItemMove(int from, int to) { + Collections.swap(appList, from, to); + notifyItemMoved(from, to); + } - public ViewHolder(final View itemView) { - super(itemView, mGrabHandleId); + public class AppViewHolder extends RecyclerView.ViewHolder { + final TextView mDeviceAppVersionAuthorLabel; + final TextView mDeviceAppNameLabel; + final ImageView mDeviceImageView; + final ImageView mDragHandle; + + AppViewHolder(View itemView) { + super(itemView); mDeviceAppVersionAuthorLabel = (TextView) itemView.findViewById(R.id.item_details); mDeviceAppNameLabel = (TextView) itemView.findViewById(R.id.item_name); mDeviceImageView = (ImageView) itemView.findViewById(R.id.item_image); + mDragHandle = (ImageView) itemView.findViewById(R.id.drag_handle); } - @Override - public void onItemClicked(View view) { - UUID uuid = mItemList.get(getAdapterPosition()).getUUID(); - GBApplication.deviceService().onAppStart(uuid, true); - } - - @Override - public boolean onItemLongClicked(View view) { - return mParentFragment.openPopupMenu(view, getAdapterPosition()); - } } + } diff --git a/app/src/main/res/drawable/ic_drag_handle_black_24dp.xml b/app/src/main/res/drawable/ic_drag_handle_black_24dp.xml new file mode 100644 index 000000000..8f7f335a3 --- /dev/null +++ b/app/src/main/res/drawable/ic_drag_handle_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_appmanager.xml b/app/src/main/res/layout/activity_appmanager.xml index bf304a271..ed6a70f38 100644 --- a/app/src/main/res/layout/activity_appmanager.xml +++ b/app/src/main/res/layout/activity_appmanager.xml @@ -3,8 +3,9 @@ android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools" tools:context="nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AbstractAppManagerFragment"> - + android:layout_height="fill_parent" /> diff --git a/app/src/main/res/layout/item_with_details_and_drag_handle.xml b/app/src/main/res/layout/item_with_details_and_drag_handle.xml new file mode 100644 index 000000000..58943cb68 --- /dev/null +++ b/app/src/main/res/layout/item_with_details_and_drag_handle.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + \ No newline at end of file From 8fccbe3b6975e0a85f9885bc0a531e075a10f494 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Fri, 31 Mar 2017 18:23:02 +0200 Subject: [PATCH 24/61] Pebble: implement battery display in control center - extract the millivolts reading from the analytics datalog message and map to percentage - mapping is manually made and is possibly wrong, but the values are commented - the values are sent once per hour and are delayed, this might make the reading really inaccurate on pebble time round watches --- .../pebble/DatalogSessionAnalytics.java | 97 +++++++++++++++++++ .../devices/pebble/PebbleProtocol.java | 4 +- 2 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionAnalytics.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionAnalytics.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionAnalytics.java new file mode 100644 index 000000000..7ce6f7d51 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionAnalytics.java @@ -0,0 +1,97 @@ +/* Copyright (C) 2016-2017 Daniele Gobbetti + + 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.pebble; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.ByteBuffer; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +class DatalogSessionAnalytics extends DatalogSession { + private static final Logger LOG = LoggerFactory.getLogger(DatalogSessionAnalytics.class); + private GBDeviceEventBatteryInfo mGBDeviceEventBatteryInfo = new GBDeviceEventBatteryInfo(); + private GBDevice mGBDevice; + + DatalogSessionAnalytics(byte id, UUID uuid, int timestamp, int tag, byte itemType, short itemSize, GBDevice device) { + super(id, uuid, timestamp, tag, itemType, itemSize); + if (mGBDevice == null || !device.equals(mGBDevice)) { //prevent showing information of other pebble watches when switching devices + mGBDevice = device; + mGBDeviceEventBatteryInfo.state = BatteryState.UNKNOWN; + } + + // The default notification should not be too bad (one per hour) but we can override this if needed + //mGBDevice.setBatteryThresholdPercent((short) 5); + + taginfo = "(analytics - " + tag + ")"; + } + + @Override + GBDeviceEvent[] handleMessage(ByteBuffer datalogMessage, int length) { + LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length)); + + datalogMessage.position(datalogMessage.position() + 3); + int messageTS = datalogMessage.getInt(); + + datalogMessage.position(datalogMessage.position() + 12); + short reportedMilliVolts = datalogMessage.getShort(); + + LOG.info("Battery reading for TS " + messageTS + " is: " + reportedMilliVolts + " milliVolts, mapped to percentage: " + milliVoltstoPercentage(reportedMilliVolts)); + + if (messageTS > 0 && reportedMilliVolts < 5000) { //some safety checks + mGBDeviceEventBatteryInfo.state = BatteryState.BATTERY_NORMAL; + mGBDeviceEventBatteryInfo.level = milliVoltstoPercentage(reportedMilliVolts); + + return new GBDeviceEvent[]{mGBDeviceEventBatteryInfo, null}; + } else { //invalid data, but we ack nevertheless + return new GBDeviceEvent[]{null}; + } + + } + + private short milliVoltstoPercentage(short batteryMilliVolts) { + if (batteryMilliVolts > 4145) { //(4146 is still 100, next reported value is already 90) + return 100; + } else if (batteryMilliVolts > 4053) { //(4054 is still 90, next reported value is already 80) + return 90; + } else if (batteryMilliVolts > 4000) { //guessed + return 80; + } else if (batteryMilliVolts > 3880) { //confirmed + return 70; + } else if (batteryMilliVolts > 3855) { //probably + return 60; + } else if (batteryMilliVolts > 3780) { //3781 is still 50, next reading is 3776 but percentage on pebble unknown + return 50; + } else if (batteryMilliVolts >= 3750) { //3750 is still 40, next reported value is 3746 and already 30 + return 40; + } else if (batteryMilliVolts > 3720) { //3723 is still 30, next reported value is 3719 and already 20 + return 30; + } else if (batteryMilliVolts > 3680) { //3683 is still 20, next reported value is 3675 and already 10 + return 20; + } else if (batteryMilliVolts > 3650) { //3657 is still 10 + return 10; + } else { + return 0; //or -1 for invalid? + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 83b1f2bd8..582e3878e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -2263,7 +2263,9 @@ public class PebbleProtocol extends GBDeviceProtocol { short item_size = buf.getShort(); LOG.info("DATALOG OPENSESSION. id=" + (id & 0xff) + ", App UUID=" + uuid.toString() + ", log_tag=" + log_tag + ", item_type=" + item_type + ", itemSize=" + item_size); if (!mDatalogSessions.containsKey(id)) { - if (uuid.equals(UUID_ZERO) && log_tag == 81) { + if (uuid.equals(UUID_ZERO) && log_tag == 78) { + mDatalogSessions.put(id, new DatalogSessionAnalytics(id, uuid, timestamp, log_tag, item_type, item_size, getDevice())); + } else if (uuid.equals(UUID_ZERO) && log_tag == 81) { mDatalogSessions.put(id, new DatalogSessionHealthSteps(id, uuid, timestamp, log_tag, item_type, item_size, getDevice())); } else if (uuid.equals(UUID_ZERO) && log_tag == 83) { mDatalogSessions.put(id, new DatalogSessionHealthSleep(id, uuid, timestamp, log_tag, item_type, item_size, getDevice())); From 173b4fbbe60074cdb592b0eab7e92637d2900620 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Fri, 31 Mar 2017 23:42:25 +0200 Subject: [PATCH 25/61] Add legend ans labels to weekly sleep charts Also remove the "missing sleep" gray entry to avoid confusion --- .../charts/AbstractWeekChartFragment.java | 38 +++++++++---------- .../charts/WeekSleepChartFragment.java | 27 +++++++++++++ .../charts/WeekStepsChartFragment.java | 12 ++++++ 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java index b43816372..ea55e740e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java @@ -25,7 +25,6 @@ import android.view.View; import android.view.ViewGroup; import com.github.mikephil.charting.charts.BarChart; -import com.github.mikephil.charting.charts.Chart; import com.github.mikephil.charting.charts.PieChart; import com.github.mikephil.charting.components.LimitLine; import com.github.mikephil.charting.components.XAxis; @@ -81,13 +80,12 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { protected void updateChartsnUIThread(ChartsData chartsData) { MyChartsData mcd = (MyChartsData) chartsData; -// setupLegend(mWeekChart); + setupLegend(mWeekChart); mTodayPieChart.setCenterText(mcd.getDayData().centerText); mTodayPieChart.setData(mcd.getDayData().data); mWeekChart.setData(null); // workaround for https://github.com/PhilJay/MPAndroidChart/issues/2317 mWeekChart.setData(mcd.getWeekBeforeData().getData()); - mWeekChart.getLegend().setEnabled(false); mWeekChart.getXAxis().setValueFormatter(mcd.getWeekBeforeData().getXValueFormatter()); } @@ -133,23 +131,30 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { ActivityAmounts amounts = getActivityAmountsForDay(db, day, device); float totalValues[] = getTotalsForActivityAmounts(amounts); + String[] pieLabels = getPieLabels(); float totalValue = 0; - for (float value : totalValues) { + for (int i = 0; i < totalValues.length; i++) { + float value = totalValues[i]; totalValue += value; - entries.add(new PieEntry(value)); + entries.add(new PieEntry(value, pieLabels[i])); } set.setValueFormatter(getPieValueFormatter()); set.setColors(getColors()); - if (totalValue < mTargetValue) { - entries.add(new PieEntry((mTargetValue - totalValue))); - set.addColor(Color.GRAY); + //this hides the values (numeric) added to the set. These would be shown aside the strings set with addXValue above + if (totalValues.length < 2) { + if (totalValue < mTargetValue) { + entries.add(new PieEntry((mTargetValue - totalValue))); + set.addColor(Color.GRAY); + } } data.setDataSet(set); - //this hides the values (numeric) added to the set. These would be shown aside the strings set with addXValue above - data.setDrawValues(false); + + if (totalValues.length < 2) { + data.setDrawValues(false); + } return new DayData(data, formatPieValue((int) totalValue)); } @@ -185,7 +190,6 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { // mTodayPieChart.setNoDataTextDescription(""); mTodayPieChart.setNoDataText(""); mTodayPieChart.getLegend().setEnabled(false); -// setupLegend(mTodayPieChart); } private void setupWeekChart() { @@ -222,16 +226,6 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { yAxisRight.setTextColor(CHART_TEXT_COLOR); } - @Override - protected void setupLegend(Chart chart) { -// List legendColors = new ArrayList<>(1); -// List legendLabels = new ArrayList<>(1); -// legendColors.add(akActivity.color); -// legendLabels.add(getContext().getString(R.string.chart_steps)); -// chart.getLegend().setCustom(legendColors, legendLabels); -// chart.getLegend().setTextColor(LEGEND_TEXT_COLOR); - } - private List getSamplesOfDay(DBHandler db, Calendar day, int offsetHours, GBDevice device) { int startTs; int endTs; @@ -312,6 +306,8 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { abstract String formatPieValue(int value); + abstract String[] getPieLabels(); + abstract IValueFormatter getPieValueFormatter(); abstract IValueFormatter getBarValueFormatter(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java index 8e6e5623d..29ef5a969 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java @@ -16,12 +16,16 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities.charts; +import com.github.mikephil.charting.charts.Chart; import com.github.mikephil.charting.components.AxisBase; +import com.github.mikephil.charting.components.LegendEntry; import com.github.mikephil.charting.data.Entry; import com.github.mikephil.charting.formatter.IAxisValueFormatter; import com.github.mikephil.charting.formatter.IValueFormatter; import com.github.mikephil.charting.utils.ViewPortHandler; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -72,6 +76,11 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment { return DateTimeUtils.formatDurationHoursMinutes((long) value, TimeUnit.MINUTES); } + @Override + String[] getPieLabels() { + return new String[]{getString(R.string.abstract_chart_fragment_kind_deep_sleep), getString(R.string.abstract_chart_fragment_kind_light_sleep)}; + } + @Override IValueFormatter getPieValueFormatter() { return new IValueFormatter() { @@ -106,4 +115,22 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment { int[] getColors() { return new int[]{akDeepSleep.color, akLightSleep.color}; } + + @Override + protected void setupLegend(Chart chart) { + List legendEntries = new ArrayList<>(2); + + LegendEntry lightSleepEntry = new LegendEntry(); + lightSleepEntry.label = akLightSleep.label; + lightSleepEntry.formColor = akLightSleep.color; + legendEntries.add(lightSleepEntry); + + LegendEntry deepSleepEntry = new LegendEntry(); + deepSleepEntry.label = akDeepSleep.label; + deepSleepEntry.formColor = akDeepSleep.color; + legendEntries.add(deepSleepEntry); + + chart.getLegend().setCustom(legendEntries); + chart.getLegend().setTextColor(LEGEND_TEXT_COLOR); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java index 143ad9cfa..86cc382c6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java @@ -17,6 +17,7 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities.charts; +import com.github.mikephil.charting.charts.Chart; import com.github.mikephil.charting.formatter.IAxisValueFormatter; import com.github.mikephil.charting.formatter.IValueFormatter; @@ -62,6 +63,11 @@ public class WeekStepsChartFragment extends AbstractWeekChartFragment { return String.valueOf(value); } + @Override + String[] getPieLabels() { + return new String[]{""}; + } + @Override IValueFormatter getPieValueFormatter() { return null; @@ -81,4 +87,10 @@ public class WeekStepsChartFragment extends AbstractWeekChartFragment { int[] getColors() { return new int[]{akActivity.color}; } + + @Override + protected void setupLegend(Chart chart) { + // no legend here, it is all about the steps here + chart.getLegend().setEnabled(false); + } } From db4e37d08b984cd2c49c935239729b52f75e1eb4 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sat, 1 Apr 2017 15:45:30 +0200 Subject: [PATCH 26/61] Make the drag handle less prominent (grey) --- app/src/main/res/layout/item_with_details_and_drag_handle.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/layout/item_with_details_and_drag_handle.xml b/app/src/main/res/layout/item_with_details_and_drag_handle.xml index 58943cb68..98d39a23f 100644 --- a/app/src/main/res/layout/item_with_details_and_drag_handle.xml +++ b/app/src/main/res/layout/item_with_details_and_drag_handle.xml @@ -43,6 +43,7 @@ Date: Sat, 1 Apr 2017 17:06:38 +0200 Subject: [PATCH 27/61] Apply some Material design guidelines to the app management - replace the PagerTabStrip with a TabLayout (moved to top) - change the row element to adhere to the guidelines wrt spacing - move the FAB a bit and hide it when scrolling down, scroll up to reveal it again --- .../AbstractAppManagerFragment.java | 13 +++++++ .../main/res/layout/activity_appmanager.xml | 9 +++-- .../layout/activity_fragmentappmanager.xml | 12 +++---- .../item_with_details_and_drag_handle.xml | 36 ++++++++++++------- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java index c9ebb69af..e2ad884f6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java @@ -24,6 +24,7 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; import android.support.v4.app.Fragment; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.widget.LinearLayoutManager; @@ -259,9 +260,21 @@ public abstract class AbstractAppManagerFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final FloatingActionButton appListFab = ((FloatingActionButton) getActivity().findViewById(R.id.fab)); View rootView = inflater.inflate(R.layout.activity_appmanager, container, false); RecyclerView appListView = (RecyclerView) (rootView.findViewById(R.id.appListView)); + + appListView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + if (dy > 0) { + appListFab.hide(); + } else if (dy < 0) { + appListFab.show(); + } + } + }); appListView.setLayoutManager(new LinearLayoutManager(getActivity())); mGBDeviceAppAdapter = new GBDeviceAppAdapter(appList, R.layout.item_with_details_and_drag_handle, this); appListView.setAdapter(mGBDeviceAppAdapter); diff --git a/app/src/main/res/layout/activity_appmanager.xml b/app/src/main/res/layout/activity_appmanager.xml index ed6a70f38..943de9d83 100644 --- a/app/src/main/res/layout/activity_appmanager.xml +++ b/app/src/main/res/layout/activity_appmanager.xml @@ -5,7 +5,10 @@ tools:context="nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AbstractAppManagerFragment"> + android:id="@+id/appListView" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alignParentTop="true" + android:layout_centerHorizontal="true" + android:divider="@null" /> diff --git a/app/src/main/res/layout/activity_fragmentappmanager.xml b/app/src/main/res/layout/activity_fragmentappmanager.xml index d32ada664..95915b0a6 100644 --- a/app/src/main/res/layout/activity_fragmentappmanager.xml +++ b/app/src/main/res/layout/activity_fragmentappmanager.xml @@ -3,10 +3,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" - android:paddingBottom="0px" - android:paddingLeft="0px" - android:paddingRight="0px" - android:paddingTop="0px" tools:context=".activities.appmanager.AppManagerActivity"> - + android:layout_gravity="top" /> @@ -39,7 +35,7 @@ android:src="@drawable/ic_add_white" app:elevation="6dp" app:pressedTranslationZ="12dp" - android:layout_marginBottom="10dp" - android:layout_marginRight="10dp" /> + android:layout_marginBottom="30dp" + android:layout_marginEnd="10dp" /> diff --git a/app/src/main/res/layout/item_with_details_and_drag_handle.xml b/app/src/main/res/layout/item_with_details_and_drag_handle.xml index 98d39a23f..316fc03a6 100644 --- a/app/src/main/res/layout/item_with_details_and_drag_handle.xml +++ b/app/src/main/res/layout/item_with_details_and_drag_handle.xml @@ -4,50 +4,60 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/activatedBackgroundIndicator" - android:padding="8dp"> + android:minHeight="60dp"> + android:paddingBottom="8dp" + android:paddingTop="8dp"> + android:textAppearance="@style/TextAppearance.AppCompat.Subhead" /> + android:text="Item Description" + android:textAppearance="@style/TextAppearance.AppCompat.Body1" /> \ No newline at end of file From e89ba529c301bc653151b6f86e94c0a1c1926e3a Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sat, 1 Apr 2017 17:47:54 +0200 Subject: [PATCH 28/61] Apply some Material design guidelines to the charts - replace the PagerTabStrip with a TabLayout (moved to top and scrollable) - move the date selection to the bottom - do not update the activity title as the tab name is much more visible now --- CHANGELOG.md | 3 + .../activities/AbstractGBFragment.java | 11 --- .../activities/charts/ChartsActivity.java | 3 - app/src/main/res/layout/activity_charts.xml | 89 ++++++++++--------- app/src/main/res/xml/changelog_master.xml | 5 ++ 5 files changed, 54 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef8dbf97c..d9bdad8a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ###Changelog +###Version next +* Applied some material design guidelines to Charts and (pebble) app management + ###Version 0.18.4 * Mi Band 2: Display realtime steps in Live Activity * Mi Band: Attempt to recognize Mi Band model with hwVersion = 8 diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragment.java index 66858bf1b..d9939ba07 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractGBFragment.java @@ -18,7 +18,6 @@ package nodomain.freeyourgadget.gadgetbridge.activities; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentActivity; /** * Abstract base class for fragments. Provides hooks that are called when @@ -37,7 +36,6 @@ public abstract class AbstractGBFragment extends Fragment { * @see #onMadeInvisibleInActivity() */ protected void onMadeVisibleInActivity() { - updateActivityTitle(); } /** @@ -58,15 +56,6 @@ public abstract class AbstractGBFragment extends Fragment { return mVisibleInactivity; } - protected void updateActivityTitle() { - FragmentActivity activity = getActivity(); - if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) { - if (getTitle() != null) { - activity.setTitle(getTitle()); - } - } - } - @Nullable protected abstract CharSequence getTitle(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java index d5dedfc24..2b73b1923 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java @@ -27,7 +27,6 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.content.LocalBroadcastManager; -import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; import android.support.v4.widget.SwipeRefreshLayout; import android.view.Menu; @@ -67,7 +66,6 @@ public class ChartsActivity extends AbstractGBFragmentActivity implements Charts private Date mStartDate; private Date mEndDate; private SwipeRefreshLayout swipeLayout; - private PagerTabStrip mPagerTabStrip; private ViewPager viewPager; LimitedQueue mActivityAmountCache = new LimitedQueue(60); @@ -200,7 +198,6 @@ public class ChartsActivity extends AbstractGBFragmentActivity implements Charts handleNextButtonClicked(); } }); - mPagerTabStrip = (PagerTabStrip) findViewById(R.id.charts_pagerTabStrip); LinearLayout mainLayout = (LinearLayout) findViewById(R.id.charts_main_layout); } diff --git a/app/src/main/res/layout/activity_charts.xml b/app/src/main/res/layout/activity_charts.xml index bce480827..6321f441e 100644 --- a/app/src/main/res/layout/activity_charts.xml +++ b/app/src/main/res/layout/activity_charts.xml @@ -1,56 +1,59 @@ - - + android:layout_height="match_parent" + tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity"> -