diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/DaFitConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/DaFitConstants.java
index 32d4021de6..9115247d38 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/DaFitConstants.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/DaFitConstants.java
@@ -369,4 +369,15 @@ public class DaFitConstants {
return DaFitConstants.WEATHER_HAZE;
}
}
+
+
+ public static final String PREF_WATCH_FACE = "dafit_watch_face";
+ public static final String PREF_LANGUAGE = "dafit_language";
+ public static final String PREF_LANGUAGE_SUPPORT = "dafit_language_supported";
+ public static final String PREF_DEVICE_VERSION = "dafit_device_version";
+ public static final String PREF_SEDENTARY_REMINDER = "sedentary_reminder";
+ public static final String PREF_SEDENTARY_REMINDER_PERIOD = "sedentary_reminder_period";
+ public static final String PREF_SEDENTARY_REMINDER_STEPS = "sedentary_reminder_steps";
+ public static final String PREF_SEDENTARY_REMINDER_START = "sedentary_reminder_start";
+ public static final String PREF_SEDENTARY_REMINDER_END = "sedentary_reminder_end";
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/DaFitDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/DaFitDeviceCoordinator.java
index a46a76d4d4..a4bd39b7a2 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/DaFitDeviceCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/DaFitDeviceCoordinator.java
@@ -31,9 +31,22 @@ import java.util.Collection;
import java.util.Collections;
import nodomain.freeyourgadget.gadgetbridge.GBException;
+import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitEnumDeviceVersion;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitEnumMetricSystem;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitEnumTimeSystem;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSetting;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingBool;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingByte;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingEnum;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingInt;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingLanguage;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingRemindersToMove;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingTimeRange;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingUserInfo;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
@@ -187,8 +200,52 @@ public class DaFitDeviceCoordinator extends AbstractDeviceCoordinator {
@Override
public boolean supportsUnicodeEmojis() { return false; }
+ private static final DaFitSetting[] DAFIT_SETTINGS = new DaFitSetting[] {
+ new DaFitSettingUserInfo("USER_INFO", DaFitConstants.CMD_SET_USER_INFO),
+ new DaFitSettingByte("STEP_LENGTH", (byte)-1, DaFitConstants.CMD_SET_STEP_LENGTH),
+ // (*) new DaFitSettingEnum<>("DOMINANT_HAND", DaFitConstants.CMD_QUERY_DOMINANT_HAND, DaFitConstants.CMD_SET_DOMINANT_HAND, DaFitEnumDominantHand.class),
+ new DaFitSettingInt("GOAL_STEP", DaFitConstants.CMD_QUERY_GOAL_STEP, DaFitConstants.CMD_SET_GOAL_STEP),
+
+ new DaFitSettingEnum<>("DEVICE_VERSION", DaFitConstants.CMD_QUERY_DEVICE_VERSION, DaFitConstants.CMD_SET_DEVICE_VERSION, DaFitEnumDeviceVersion.class),
+ new DaFitSettingLanguage("DEVICE_LANGUAGE", DaFitConstants.CMD_QUERY_DEVICE_LANGUAGE, DaFitConstants.CMD_SET_DEVICE_LANGUAGE),
+ new DaFitSettingEnum<>("TIME_SYSTEM", DaFitConstants.CMD_QUERY_TIME_SYSTEM, DaFitConstants.CMD_SET_TIME_SYSTEM, DaFitEnumTimeSystem.class),
+ new DaFitSettingEnum<>("METRIC_SYSTEM", DaFitConstants.CMD_QUERY_METRIC_SYSTEM, DaFitConstants.CMD_SET_METRIC_SYSTEM, DaFitEnumMetricSystem.class),
+
+ // (*) new DaFitSetting("DISPLAY_DEVICE_FUNCTION", DaFitConstants.CMD_QUERY_DISPLAY_DEVICE_FUNCTION, DaFitConstants.CMD_SET_DISPLAY_DEVICE_FUNCTION),
+ // (*) new DaFitSetting("SUPPORT_WATCH_FACE", DaFitConstants.CMD_QUERY_SUPPORT_WATCH_FACE, (byte)-1),
+ // (*) new DaFitSetting("WATCH_FACE_LAYOUT", DaFitConstants.CMD_QUERY_WATCH_FACE_LAYOUT, DaFitConstants.CMD_SET_WATCH_FACE_LAYOUT),
+ new DaFitSettingByte("DISPLAY_WATCH_FACE", DaFitConstants.CMD_QUERY_DISPLAY_WATCH_FACE, DaFitConstants.CMD_SET_DISPLAY_WATCH_FACE),
+ new DaFitSettingBool("OTHER_MESSAGE_STATE", DaFitConstants.CMD_QUERY_OTHER_MESSAGE_STATE, DaFitConstants.CMD_SET_OTHER_MESSAGE_STATE),
+
+ new DaFitSettingBool("QUICK_VIEW", DaFitConstants.CMD_QUERY_QUICK_VIEW, DaFitConstants.CMD_SET_QUICK_VIEW),
+ new DaFitSettingTimeRange("QUICK_VIEW_TIME", DaFitConstants.CMD_QUERY_QUICK_VIEW_TIME, DaFitConstants.CMD_SET_QUICK_VIEW_TIME),
+ new DaFitSettingBool("SEDENTARY_REMINDER", DaFitConstants.CMD_QUERY_SEDENTARY_REMINDER, DaFitConstants.CMD_SET_SEDENTARY_REMINDER),
+ new DaFitSettingRemindersToMove("REMINDERS_TO_MOVE_PERIOD", DaFitConstants.CMD_QUERY_REMINDERS_TO_MOVE_PERIOD, DaFitConstants.CMD_SET_REMINDERS_TO_MOVE_PERIOD),
+ new DaFitSettingTimeRange("DO_NOT_DISTURB_TIME", DaFitConstants.CMD_QUERY_DO_NOT_DISTURB_TIME, DaFitConstants.CMD_SET_DO_NOT_DISTURB_TIME),
+ // (*) new DaFitSetting("PSYCHOLOGICAL_PERIOD", DaFitConstants.CMD_QUERY_PSYCHOLOGICAL_PERIOD, DaFitConstants.CMD_SET_PSYCHOLOGICAL_PERIOD),
+
+ new DaFitSettingBool("BREATHING_LIGHT", DaFitConstants.CMD_QUERY_BREATHING_LIGHT, DaFitConstants.CMD_SET_BREATHING_LIGHT)
+ };
+
@Override
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
- return null;
+ return new int[]{
+ R.xml.devicesettings_personalinfo,
+ //R.xml.devicesettings_steplength, // TODO is this needed? does it work? write-only so hard to tell
+ R.xml.devicesettings_dafit_device_version,
+ R.xml.devicesettings_dafit_language,
+ R.xml.devicesettings_timeformat,
+ R.xml.devicesettings_measurementsystem,
+ R.xml.devicesettings_dafit_watchface,
+ //R.xml.devicesettings_dafit_othermessage, // not implemented because this doesn't really do anything on the watch side, only enables/disables sending of "other" notifications in the app (no idea why they store the setting on the watch)
+ R.xml.devicesettings_liftwrist_display,
+ R.xml.devicesettings_dafit_sedentary_reminder,
+ R.xml.devicesettings_donotdisturb_no_auto_v2,
+ //R.xml.devicesettings_dafit_breathinglight, // No idea what this does but it doesn't seem to change anything
+ };
+ }
+
+ public DaFitSetting[] getSupportedSettings() {
+ return DAFIT_SETTINGS;
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnum.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnum.java
new file mode 100644
index 0000000000..33f3bdc3e3
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnum.java
@@ -0,0 +1,21 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+public interface DaFitEnum {
+ byte value();
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumDeviceVersion.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumDeviceVersion.java
new file mode 100644
index 0000000000..b33ca49ae3
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumDeviceVersion.java
@@ -0,0 +1,33 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+public enum DaFitEnumDeviceVersion implements DaFitEnum {
+ CHINESE_EDITION((byte)0),
+ INTERNATIONAL_EDITION((byte)1);
+
+ public final byte value;
+
+ DaFitEnumDeviceVersion(byte value) {
+ this.value = value;
+ }
+
+ @Override
+ public byte value() {
+ return value;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumDominantHand.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumDominantHand.java
new file mode 100644
index 0000000000..c05ceabc14
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumDominantHand.java
@@ -0,0 +1,33 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+public enum DaFitEnumDominantHand implements DaFitEnum {
+ LEFT_HAND((byte)0),
+ RIGHT_HAND((byte)1);
+
+ public final byte value;
+
+ DaFitEnumDominantHand(byte value) {
+ this.value = value;
+ }
+
+ @Override
+ public byte value() {
+ return value;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumLanguage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumLanguage.java
new file mode 100644
index 0000000000..5b94f17362
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumLanguage.java
@@ -0,0 +1,56 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+public enum DaFitEnumLanguage implements DaFitEnum {
+ LANGUAGE_ENGLISH((byte)0),
+ LANGUAGE_CHINESE((byte)1),
+ LANGUAGE_JAPANESE((byte)2),
+ LANGUAGE_KOREAN((byte)3),
+ LANGUAGE_GERMAN((byte)4),
+ LANGUAGE_FRENCH((byte)5),
+ LANGUAGE_SPANISH((byte)6),
+ LANGUAGE_ARABIC((byte)7),
+ LANGUAGE_RUSSIAN((byte)8),
+ LANGUAGE_TRADITIONAL((byte)9),
+ LANGUAGE_UKRAINIAN((byte)10),
+ LANGUAGE_ITALIAN((byte)11),
+ LANGUAGE_PORTUGUESE((byte)12),
+ LANGUAGE_DUTCH((byte)13),
+ LANGUAGE_POLISH((byte)14),
+ LANGUAGE_SWEDISH((byte)15),
+ LANGUAGE_FINNISH((byte)16),
+ LANGUAGE_DANISH((byte)17),
+ LANGUAGE_NORWEGIAN((byte)18),
+ LANGUAGE_HUNGARIAN((byte)19),
+ LANGUAGE_CZECH((byte)20),
+ LANGUAGE_BULGARIAN((byte)21),
+ LANGUAGE_ROMANIAN((byte)22),
+ LANGUAGE_SLOVAK_LANGUAGE((byte)23),
+ LANGUAGE_LATVIAN((byte)24);
+
+ public final byte value;
+
+ DaFitEnumLanguage(byte value) {
+ this.value = value;
+ }
+
+ @Override
+ public byte value() {
+ return value;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumMetricSystem.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumMetricSystem.java
new file mode 100644
index 0000000000..570343968c
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumMetricSystem.java
@@ -0,0 +1,33 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+public enum DaFitEnumMetricSystem implements DaFitEnum {
+ METRIC_SYSTEM((byte)0),
+ IMPERIAL_SYSTEM((byte)1);
+
+ public final byte value;
+
+ DaFitEnumMetricSystem(byte value) {
+ this.value = value;
+ }
+
+ @Override
+ public byte value() {
+ return value;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumTimeSystem.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumTimeSystem.java
new file mode 100644
index 0000000000..68e5a26dd7
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitEnumTimeSystem.java
@@ -0,0 +1,33 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+public enum DaFitEnumTimeSystem implements DaFitEnum {
+ TIME_SYSTEM_12((byte)0),
+ TIME_SYSTEM_24((byte)1);
+
+ public final byte value;
+
+ DaFitEnumTimeSystem(byte value) {
+ this.value = value;
+ }
+
+ @Override
+ public byte value() {
+ return value;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSetting.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSetting.java
new file mode 100644
index 0000000000..5638a5ab28
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSetting.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+public abstract class DaFitSetting {
+ public final String name;
+ public final byte cmdQuery;
+ public final byte cmdSet;
+
+ public DaFitSetting(String name, byte cmdQuery, byte cmdSet) {
+ this.name = name;
+ this.cmdQuery = cmdQuery;
+ this.cmdSet = cmdSet;
+ }
+
+ public abstract byte[] encode(T value);
+ public abstract T decode(byte[] data);
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingBool.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingBool.java
new file mode 100644
index 0000000000..515aa6b674
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingBool.java
@@ -0,0 +1,37 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+public class DaFitSettingBool extends DaFitSetting {
+ public DaFitSettingBool(String name, byte cmdQuery, byte cmdSet) {
+ super(name, cmdQuery, cmdSet);
+ }
+
+ @Override
+ public byte[] encode(Boolean value) {
+ return new byte[] { value ? (byte)1 : (byte)0 };
+ }
+
+ @Override
+ public Boolean decode(byte[] data) {
+ if (data.length != 1)
+ throw new IllegalArgumentException("Wrong data length, should be 1, was " + data.length);
+ if (data[0] != 0 && data[0] != 1)
+ throw new IllegalArgumentException("Expected a boolean, got " + data[0]);
+ return data[0] != 0;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingByte.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingByte.java
new file mode 100644
index 0000000000..fb5fd68497
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingByte.java
@@ -0,0 +1,35 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+public class DaFitSettingByte extends DaFitSetting {
+ public DaFitSettingByte(String name, byte cmdQuery, byte cmdSet) {
+ super(name, cmdQuery, cmdSet);
+ }
+
+ @Override
+ public byte[] encode(Byte value) {
+ return new byte[] { value };
+ }
+
+ @Override
+ public Byte decode(byte[] data) {
+ if (data.length != 1)
+ throw new IllegalArgumentException("Wrong data length, should be 1, was " + data.length);
+ return data[0];
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingEnum.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingEnum.java
new file mode 100644
index 0000000000..50791f7356
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingEnum.java
@@ -0,0 +1,54 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+public class DaFitSettingEnum & DaFitEnum> extends DaFitSetting {
+ protected final Class clazz;
+
+ public DaFitSettingEnum(String name, byte cmdQuery, byte cmdSet, Class clazz) {
+ super(name, cmdQuery, cmdSet);
+ this.clazz = clazz;
+ }
+
+ public T findByValue(byte value)
+ {
+ for (T e : clazz.getEnumConstants()) {
+ if (e.value() == value) {
+ return e;
+ }
+ }
+
+ throw new IllegalArgumentException("No enum value for " + value);
+ }
+
+ @Override
+ public byte[] encode(T value) {
+ return new byte[] { value.value() };
+ }
+
+ @Override
+ public T decode(byte[] data) {
+ if (data.length != 1)
+ throw new IllegalArgumentException("Wrong data length, should be 1, was " + data.length);
+
+ return findByValue(data[0]);
+ }
+
+ public T[] decodeSupportedValues(byte[] data) {
+ return clazz.getEnumConstants();
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingInt.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingInt.java
new file mode 100644
index 0000000000..1ba6b0aedd
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingInt.java
@@ -0,0 +1,43 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class DaFitSettingInt extends DaFitSetting {
+ public DaFitSettingInt(String name, byte cmdQuery, byte cmdSet) {
+ super(name, cmdQuery, cmdSet);
+ }
+
+ @Override
+ public byte[] encode(Integer value) {
+ ByteBuffer buffer = ByteBuffer.allocate(4);
+ buffer.order(ByteOrder.BIG_ENDIAN); // <- this is what happens when somebody in China designs a communication protocol
+ buffer.putInt(value);
+ return buffer.array();
+ }
+
+ @Override
+ public Integer decode(byte[] data) {
+ if (data.length != 4)
+ throw new IllegalArgumentException("Wrong data length, should be 4, was " + data.length);
+ ByteBuffer buffer = ByteBuffer.wrap(data);
+ buffer.order(ByteOrder.LITTLE_ENDIAN); // <- yes, it's different here
+ return buffer.getInt();
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingLanguage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingLanguage.java
new file mode 100644
index 0000000000..b3158133ee
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingLanguage.java
@@ -0,0 +1,63 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+import android.util.Pair;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DaFitSettingLanguage extends DaFitSettingEnum {
+ public DaFitSettingLanguage(String name, byte cmdQuery, byte cmdSet) {
+ super(name, cmdQuery, cmdSet, DaFitEnumLanguage.class);
+ }
+
+ private Pair decodeData(byte[] data) {
+ if (data.length != 5)
+ throw new IllegalArgumentException("Wrong data length, should be 5, was " + data.length);
+
+ byte[] current = new byte[] { data[0] };
+ byte[] supported = new byte[] { data[1], data[2], data[3], data[4] };
+
+ ByteBuffer buffer = ByteBuffer.wrap(supported);
+ int supportedNum = buffer.getInt();
+ String supportedStr = new StringBuffer(Integer.toBinaryString(supportedNum)).reverse().toString();
+
+ DaFitEnumLanguage currentLanguage = super.decode(current);
+ List supportedLanguages = new ArrayList<>();
+ for (DaFitEnumLanguage e : clazz.getEnumConstants()) {
+ if (e.value() >= supportedStr.length())
+ continue;
+ if (Integer.parseInt(supportedStr.substring(e.value(), e.value() + 1)) != 0)
+ supportedLanguages.add(e);
+ }
+
+ DaFitEnumLanguage[] supportedLanguagesArr = new DaFitEnumLanguage[supportedLanguages.size()];
+ return Pair.create(currentLanguage, supportedLanguages.toArray(supportedLanguagesArr));
+ }
+
+ @Override
+ public DaFitEnumLanguage decode(byte[] data) {
+ return decodeData(data).first;
+ }
+
+ @Override
+ public DaFitEnumLanguage[] decodeSupportedValues(byte[] data) {
+ return decodeData(data).second;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingRemindersToMove.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingRemindersToMove.java
new file mode 100644
index 0000000000..765ad24d69
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingRemindersToMove.java
@@ -0,0 +1,74 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+import java.nio.ByteBuffer;
+
+public class DaFitSettingRemindersToMove extends DaFitSetting {
+ public static class RemindersToMove {
+ public byte period;
+ public byte steps;
+ public byte start_h;
+ public byte end_h;
+
+ public RemindersToMove() {
+ }
+
+ public RemindersToMove(byte period, byte steps, byte start_h, byte end_h) {
+ this.period = period;
+ this.steps = steps;
+ this.start_h = start_h;
+ this.end_h = end_h;
+ }
+
+ @Override
+ public String toString() {
+ return "RemindersToMove{" +
+ "period=" + period +
+ ", steps=" + steps +
+ ", start_h=" + start_h +
+ ", end_h=" + end_h +
+ '}';
+ }
+ }
+
+ public DaFitSettingRemindersToMove(String name, byte cmdQuery, byte cmdSet) {
+ super(name, cmdQuery, cmdSet);
+ }
+
+ @Override
+ public byte[] encode(RemindersToMove value) {
+ ByteBuffer buffer = ByteBuffer.allocate(4);
+ buffer.put(value.period);
+ buffer.put(value.steps);
+ buffer.put(value.start_h);
+ buffer.put(value.end_h);
+ return buffer.array();
+ }
+
+ @Override
+ public RemindersToMove decode(byte[] data) {
+ if (data.length != 4)
+ throw new IllegalArgumentException("Wrong data length, should be 4, was " + data.length);
+ ByteBuffer buffer = ByteBuffer.wrap(data);
+ byte period = buffer.get();
+ byte steps = buffer.get();
+ byte start_h = buffer.get();
+ byte end_h = buffer.get();
+ return new RemindersToMove(period, steps, start_h, end_h);
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingTimeRange.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingTimeRange.java
new file mode 100644
index 0000000000..6e7fadeefa
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingTimeRange.java
@@ -0,0 +1,76 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class DaFitSettingTimeRange extends DaFitSetting {
+ public static class TimeRange {
+ public byte start_h;
+ public byte start_m;
+ public byte end_h;
+ public byte end_m;
+
+ public TimeRange() {
+ }
+
+ public TimeRange(byte start_h, byte start_m, byte end_h, byte end_m) {
+ this.start_h = start_h;
+ this.start_m = start_m;
+ this.end_h = end_h;
+ this.end_m = end_m;
+ }
+
+ @Override
+ public String toString() {
+ return "TimeRange{" +
+ "start_h=" + start_h +
+ ", start_m=" + start_m +
+ ", end_h=" + end_h +
+ ", end_m=" + end_m +
+ '}';
+ }
+ }
+
+ public DaFitSettingTimeRange(String name, byte cmdQuery, byte cmdSet) {
+ super(name, cmdQuery, cmdSet);
+ }
+
+ // Yes, these are different. Was somebody drunk when designing this?
+
+ @Override
+ public byte[] encode(TimeRange value) {
+ ByteBuffer buffer = ByteBuffer.allocate(4);
+ buffer.put(value.start_h);
+ buffer.put(value.start_m);
+ buffer.put(value.end_h);
+ buffer.put(value.end_m);
+ return buffer.array();
+ }
+
+ @Override
+ public TimeRange decode(byte[] data) {
+ if (data.length != 4)
+ throw new IllegalArgumentException("Wrong data length, should be 4, was " + data.length);
+ ByteBuffer buffer = ByteBuffer.wrap(data);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ short start = buffer.getShort();
+ short end = buffer.getShort();
+ return new TimeRange((byte)(start / 60), (byte)(start % 60), (byte)(end / 60), (byte)(start % 60));
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingUserInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingUserInfo.java
new file mode 100644
index 0000000000..1e55e7714c
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/dafit/settings/DaFitSettingUserInfo.java
@@ -0,0 +1,44 @@
+/* Copyright (C) 2019 krzys_h
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings;
+
+import org.apache.commons.lang3.NotImplementedException;
+
+import java.nio.ByteBuffer;
+
+import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
+
+public class DaFitSettingUserInfo extends DaFitSetting {
+ public DaFitSettingUserInfo(String name, byte cmdSet) {
+ super(name, (byte)-1, cmdSet);
+ }
+
+ @Override
+ public byte[] encode(ActivityUser value) {
+ ByteBuffer buffer = ByteBuffer.allocate(4);
+ buffer.put((byte)value.getHeightCm());
+ buffer.put((byte)value.getWeightKg());
+ buffer.put((byte)value.getAge());
+ buffer.put((byte)value.getGender());
+ return buffer.array();
+ }
+
+ @Override
+ public ActivityUser decode(byte[] data) {
+ throw new NotImplementedException("decode");
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/dafit/DaFitDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/dafit/DaFitDeviceSupport.java
index 95ec2f9480..3830e1a42f 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/dafit/DaFitDeviceSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/dafit/DaFitDeviceSupport.java
@@ -19,8 +19,10 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.dafit;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Handler;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
import android.widget.Toast;
@@ -32,29 +34,51 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.Logging;
+import nodomain.freeyourgadget.gadgetbridge.R;
+import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl;
+import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventConfigurationRead;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.dafit.DaFitConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.dafit.DaFitWeatherForecast;
import nodomain.freeyourgadget.gadgetbridge.devices.dafit.DaFitWeatherToday;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.DaFitDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.dafit.DaFitSampleProvider;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitEnumDeviceVersion;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitEnumLanguage;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitEnumMetricSystem;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitEnumTimeSystem;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSetting;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingEnum;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingLanguage;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingRemindersToMove;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSettingTimeRange;
+import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
+import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.DaFitActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
+import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
@@ -75,8 +99,10 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.battery.Batter
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.HeartRateProfile;
+import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
+import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
// TODO: figure out the training data
@@ -139,6 +165,8 @@ public class DaFitDeviceSupport extends AbstractBTLEDeviceSupport {
builder.notify(getCharacteristic(DaFitConstants.UUID_CHARACTERISTIC_DATA_IN), true);
deviceInfoProfile.requestDeviceInfo(builder);
setTime(builder);
+ sendSetting(builder, getSetting("USER_INFO"), new ActivityUser()); // these settings are write-only, so write them just in case because there is no way to know if they desynced somehow
+ sendSetting(builder, getSetting("GOAL_STEP"), new ActivityUser().getStepsGoal());
batteryInfoProfile.requestBatteryInfo(builder);
batteryInfoProfile.enableNotify(builder);
heartRateProfile.enableNotify(builder);
@@ -331,6 +359,17 @@ public class DaFitDeviceSupport extends AbstractBTLEDeviceSupport {
return true;
}
+ for (DaFitSetting setting : queriedSettings)
+ {
+ if (setting.cmdQuery == packetType)
+ {
+ Object value = setting.decode(payload);
+ onReadConfigurationDone(setting, value, payload);
+ queriedSettings.remove(setting);
+ return true;
+ }
+ }
+
LOG.warn("Unhandled packet " + packetType + ": " + Logging.formatBytes(payload));
return false;
}
@@ -938,18 +977,377 @@ public class DaFitDeviceSupport extends AbstractBTLEDeviceSupport {
throw new UnsupportedOperationException();
}
+ @SuppressWarnings("unchecked")
+ private T getSetting(String id) {
+ DaFitDeviceCoordinator coordinator = (DaFitDeviceCoordinator) DeviceHelper.getInstance().getCoordinator(getDevice());
+ for(DaFitSetting setting : coordinator.getSupportedSettings())
+ {
+ if (setting.name.equals(id))
+ return (T) setting;
+ }
+ throw new IllegalArgumentException("No such setting: " + id);
+ }
+
+ private static Calendar getTimePref(Prefs prefs, String key, String defaultValue) {
+ String timePref = prefs.getString(key, defaultValue);
+ Date time = null;
+ try {
+ time = new SimpleDateFormat("HH:mm").parse(timePref);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(time);
+ return cal;
+ }
+
+ private void sendSetting(TransactionBuilder builder, DaFitSetting setting, T newValue)
+ {
+ sendPacket(builder, DaFitPacketOut.buildPacket(setting.cmdSet, setting.encode(newValue)));
+ }
+
+ private void sendSetting(DaFitSetting setting, T newValue)
+ {
+ try {
+ TransactionBuilder builder = performInitialized("sendSetting");
+ sendSetting(builder, setting, newValue);
+ builder.queue(getQueue());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private Set queriedSettings = new HashSet<>();
+
+ private void querySetting(DaFitSetting setting)
+ {
+ if (queriedSettings.contains(setting))
+ return;
+
+ try {
+ TransactionBuilder builder = performInitialized("querySetting");
+ sendPacket(builder, DaFitPacketOut.buildPacket(setting.cmdQuery, new byte[0]));
+ builder.queue(getQueue());
+ queriedSettings.add(setting);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
@Override
public void onSendConfiguration(String config) {
- // TODO
+ Log.i("OOOOOOOOOOOOOOOOsend", config);
+
+ Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()));
+ switch (config) {
+ case ActivityUser.PREF_USER_HEIGHT_CM:
+ case ActivityUser.PREF_USER_WEIGHT_KG:
+ case ActivityUser.PREF_USER_YEAR_OF_BIRTH:
+ case ActivityUser.PREF_USER_GENDER:
+ sendSetting(getSetting("USER_INFO"), new ActivityUser());
+ break;
+
+ case ActivityUser.PREF_USER_STEPS_GOAL:
+ sendSetting(getSetting("GOAL_STEP"), new ActivityUser().getStepsGoal());
+ break;
+
+ case DeviceSettingsPreferenceConst.PREF_TIMEFORMAT:
+ String timeSystemPref = prefs.getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, getContext().getString(R.string.p_timeformat_24h));
+
+ DaFitEnumTimeSystem timeSystem;
+ if (timeSystemPref.equals(getContext().getString(R.string.p_timeformat_24h)))
+ timeSystem = DaFitEnumTimeSystem.TIME_SYSTEM_24;
+ else if (timeSystemPref.equals(getContext().getString(R.string.p_timeformat_am_pm)))
+ timeSystem = DaFitEnumTimeSystem.TIME_SYSTEM_12;
+ else
+ throw new IllegalArgumentException();
+
+ sendSetting(getSetting("TIME_SYSTEM"), timeSystem);
+ break;
+
+ case DeviceSettingsPreferenceConst.PREF_MEASUREMENTSYSTEM:
+ String metricSystemPref = prefs.getString(DeviceSettingsPreferenceConst.PREF_MEASUREMENTSYSTEM, getContext().getString(R.string.p_unit_metric));
+
+ DaFitEnumMetricSystem metricSystem;
+ if (metricSystemPref.equals(getContext().getString(R.string.p_unit_metric)))
+ metricSystem = DaFitEnumMetricSystem.METRIC_SYSTEM;
+ else if (metricSystemPref.equals(getContext().getString(R.string.p_unit_imperial)))
+ metricSystem = DaFitEnumMetricSystem.IMPERIAL_SYSTEM;
+ else
+ throw new IllegalArgumentException();
+
+ sendSetting(getSetting("METRIC_SYSTEM"), metricSystem);
+ break;
+
+ case DaFitConstants.PREF_WATCH_FACE:
+ String watchFacePref = prefs.getString(DaFitConstants.PREF_WATCH_FACE, String.valueOf(1));
+ byte watchFace = Byte.valueOf(watchFacePref);
+ sendSetting(getSetting("DISPLAY_WATCH_FACE"), watchFace);
+ break;
+
+ case DaFitConstants.PREF_LANGUAGE:
+ String languagePref = prefs.getString(DaFitConstants.PREF_LANGUAGE,
+ String.valueOf(DaFitEnumLanguage.LANGUAGE_ENGLISH.value()));
+ byte languageNum = Byte.valueOf(languagePref);
+ DaFitSettingEnum languageSetting = getSetting("DEVICE_LANGUAGE");
+ sendSetting(languageSetting, languageSetting.findByValue(languageNum));
+ break;
+
+ case DaFitConstants.PREF_DEVICE_VERSION:
+ String versionPref = prefs.getString(DaFitConstants.PREF_DEVICE_VERSION,
+ String.valueOf(DaFitEnumDeviceVersion.INTERNATIONAL_EDITION.value()));
+ byte versionNum = Byte.valueOf(versionPref);
+ DaFitSettingEnum versionSetting = getSetting("DEVICE_VERSION");
+ sendSetting(versionSetting, versionSetting.findByValue(versionNum));
+ break;
+
+ case MiBandConst.PREF_DO_NOT_DISTURB:
+ case MiBandConst.PREF_DO_NOT_DISTURB_START:
+ case MiBandConst.PREF_DO_NOT_DISTURB_END:
+ String doNotDisturbPref = prefs.getString(MiBandConst.PREF_DO_NOT_DISTURB, MiBandConst.PREF_DO_NOT_DISTURB_OFF);
+ boolean doNotDisturbEnabled = !MiBandConst.PREF_DO_NOT_DISTURB_OFF.equals(doNotDisturbPref);
+
+ Calendar doNotDisturbStart = getTimePref(prefs, MiBandConst.PREF_DO_NOT_DISTURB_START, "01:00");
+ Calendar doNotDisturbEnd = getTimePref(prefs, MiBandConst.PREF_DO_NOT_DISTURB_END, "06:00");
+
+ DaFitSettingTimeRange.TimeRange doNotDisturb;
+ if (doNotDisturbEnabled)
+ doNotDisturb = new DaFitSettingTimeRange.TimeRange(
+ (byte) doNotDisturbStart.get(Calendar.HOUR_OF_DAY), (byte) doNotDisturbStart.get(Calendar.MINUTE),
+ (byte) doNotDisturbEnd.get(Calendar.HOUR_OF_DAY), (byte) doNotDisturbEnd.get(Calendar.MINUTE));
+ else
+ doNotDisturb = new DaFitSettingTimeRange.TimeRange((byte)0, (byte)0, (byte)0, (byte)0);
+
+ sendSetting(getSetting("DO_NOT_DISTURB_TIME"), doNotDisturb);
+ break;
+
+ case HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT:
+ case HuamiConst.PREF_DISPLAY_ON_LIFT_START:
+ case HuamiConst.PREF_DISPLAY_ON_LIFT_END:
+ String quickViewPref = prefs.getString(HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT, MiBandConst.PREF_DO_NOT_DISTURB_OFF);
+ boolean quickViewEnabled = !quickViewPref.equals(getContext().getString(R.string.p_off));
+ boolean quickViewScheduled = quickViewPref.equals(getContext().getString(R.string.p_scheduled));
+
+ Calendar quickViewStart = getTimePref(prefs, HuamiConst.PREF_DISPLAY_ON_LIFT_START, "00:00");
+ Calendar quickViewEnd = getTimePref(prefs, HuamiConst.PREF_DISPLAY_ON_LIFT_END, "00:00");
+
+ DaFitSettingTimeRange.TimeRange quickViewTime;
+ if (quickViewEnabled && quickViewScheduled)
+ quickViewTime = new DaFitSettingTimeRange.TimeRange(
+ (byte) quickViewStart.get(Calendar.HOUR_OF_DAY), (byte) quickViewStart.get(Calendar.MINUTE),
+ (byte) quickViewEnd.get(Calendar.HOUR_OF_DAY), (byte) quickViewEnd.get(Calendar.MINUTE));
+ else
+ quickViewTime = new DaFitSettingTimeRange.TimeRange((byte)0, (byte)0, (byte)0, (byte)0);
+
+ sendSetting(getSetting("QUICK_VIEW"), quickViewEnabled);
+ sendSetting(getSetting("QUICK_VIEW_TIME"), quickViewTime);
+ break;
+
+ case DaFitConstants.PREF_SEDENTARY_REMINDER:
+ String sedentaryReminderPref = prefs.getString(DaFitConstants.PREF_SEDENTARY_REMINDER, "off");
+ boolean sedentaryReminderEnabled = !sedentaryReminderPref.equals("off");
+ sendSetting(getSetting("SEDENTARY_REMINDER"), sedentaryReminderEnabled);
+ break;
+
+ case DaFitConstants.PREF_SEDENTARY_REMINDER_PERIOD:
+ case DaFitConstants.PREF_SEDENTARY_REMINDER_STEPS:
+ case DaFitConstants.PREF_SEDENTARY_REMINDER_START:
+ case DaFitConstants.PREF_SEDENTARY_REMINDER_END:
+ byte sedentaryPeriod = (byte) prefs.getInt(DaFitConstants.PREF_SEDENTARY_REMINDER_PERIOD, 30);
+ byte sedentarySteps = (byte) prefs.getInt(DaFitConstants.PREF_SEDENTARY_REMINDER_STEPS, 100);
+ byte sedentaryStart = (byte) prefs.getInt(DaFitConstants.PREF_SEDENTARY_REMINDER_START, 10);
+ byte sedentaryEnd = (byte) prefs.getInt(DaFitConstants.PREF_SEDENTARY_REMINDER_END, 22);
+ sendSetting(getSetting("REMINDERS_TO_MOVE_PERIOD"),
+ new DaFitSettingRemindersToMove.RemindersToMove(sedentaryPeriod, sedentarySteps, sedentaryStart, sedentaryEnd));
+ break;
+ }
+
+ // Query the setting to make sure the configuration got actually applied
+ // TODO: breaks sedentary
+ //onReadConfiguration(config);
}
@Override
public void onReadConfiguration(String config) {
- // TODO
+ Log.i("OOOOOOOOOOOOOOOOread", config);
+
+ switch (config) {
+ /* These use the global Gadgetbridge configuration and are always forced on device upon connection
+ case ActivityUser.PREF_USER_HEIGHT_CM:
+ case ActivityUser.PREF_USER_WEIGHT_KG:
+ case ActivityUser.PREF_USER_YEAR_OF_BIRTH:
+ case ActivityUser.PREF_USER_GENDER:
+ querySetting(getSetting("USER_INFO"));
+ break;
+
+ case ActivityUser.PREF_USER_STEPS_GOAL:
+ querySetting(getSetting("GOAL_STEP"));
+ break;*/
+
+ case DeviceSettingsPreferenceConst.PREF_TIMEFORMAT:
+ querySetting(getSetting("TIME_SYSTEM"));
+ break;
+
+ case DeviceSettingsPreferenceConst.PREF_MEASUREMENTSYSTEM:
+ querySetting(getSetting("METRIC_SYSTEM"));
+ break;
+
+ case DaFitConstants.PREF_WATCH_FACE:
+ querySetting(getSetting("DISPLAY_WATCH_FACE"));
+ break;
+
+ case DaFitConstants.PREF_LANGUAGE:
+ querySetting(getSetting("DEVICE_LANGUAGE"));
+ break;
+
+ case DaFitConstants.PREF_DEVICE_VERSION:
+ querySetting(getSetting("DEVICE_VERSION"));
+ break;
+
+ case MiBandConst.PREF_DO_NOT_DISTURB:
+ case MiBandConst.PREF_DO_NOT_DISTURB_START:
+ case MiBandConst.PREF_DO_NOT_DISTURB_END:
+ querySetting(getSetting("DO_NOT_DISTURB_TIME"));
+ break;
+
+ case HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT:
+ case HuamiConst.PREF_DISPLAY_ON_LIFT_START:
+ case HuamiConst.PREF_DISPLAY_ON_LIFT_END:
+ querySetting(getSetting("QUICK_VIEW"));
+ querySetting(getSetting("QUICK_VIEW_TIME"));
+ break;
+
+ case DaFitConstants.PREF_SEDENTARY_REMINDER:
+ querySetting(getSetting("SEDENTARY_REMINDER"));
+ break;
+
+ case DaFitConstants.PREF_SEDENTARY_REMINDER_PERIOD:
+ case DaFitConstants.PREF_SEDENTARY_REMINDER_STEPS:
+ case DaFitConstants.PREF_SEDENTARY_REMINDER_START:
+ case DaFitConstants.PREF_SEDENTARY_REMINDER_END:
+ querySetting(getSetting("REMINDERS_TO_MOVE_PERIOD"));
+ break;
+ default:
+ return;
+ }
+
+ GBDeviceEventConfigurationRead configReadEvent = new GBDeviceEventConfigurationRead();
+ configReadEvent.config = config;
+ configReadEvent.event = GBDeviceEventConfigurationRead.Event.IN_PROGRESS;
+ evaluateGBDeviceEvent(configReadEvent);
+ }
+
+ public void onReadConfigurationDone(DaFitSetting setting, Object value, byte[] data)
+ {
+ Log.i("CONFIG", setting.name + " = " + value);
+ Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()));
+ Map changedProperties = new ArrayMap<>();
+ SharedPreferences.Editor prefsEditor = prefs.getPreferences().edit();
+ switch (setting.name) {
+ case "TIME_SYSTEM":
+ DaFitEnumTimeSystem timeSystem = (DaFitEnumTimeSystem) value;
+ if (timeSystem == DaFitEnumTimeSystem.TIME_SYSTEM_24)
+ changedProperties.put(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, getContext().getString(R.string.p_timeformat_24h));
+ else if (timeSystem == DaFitEnumTimeSystem.TIME_SYSTEM_12)
+ changedProperties.put(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, getContext().getString(R.string.p_timeformat_am_pm));
+ else
+ throw new IllegalArgumentException("Invalid value");
+ break;
+
+ case "METRIC_SYSTEM":
+ DaFitEnumMetricSystem metricSystem = (DaFitEnumMetricSystem) value;
+ if (metricSystem == DaFitEnumMetricSystem.METRIC_SYSTEM)
+ changedProperties.put(DeviceSettingsPreferenceConst.PREF_MEASUREMENTSYSTEM, getContext().getString(R.string.p_unit_metric));
+ else if (metricSystem == DaFitEnumMetricSystem.IMPERIAL_SYSTEM)
+ changedProperties.put(DeviceSettingsPreferenceConst.PREF_MEASUREMENTSYSTEM, getContext().getString(R.string.p_unit_imperial));
+ else
+ throw new IllegalArgumentException("Invalid value");
+ break;
+
+ case "DISPLAY_WATCH_FACE":
+ byte watchFace = (Byte) value;
+ changedProperties.put(DaFitConstants.PREF_WATCH_FACE, String.valueOf(watchFace));
+ break;
+
+ case "DEVICE_LANGUAGE":
+ DaFitEnumLanguage language = (DaFitEnumLanguage) value;
+ changedProperties.put(DaFitConstants.PREF_LANGUAGE, String.valueOf(language.value()));
+ DaFitEnumLanguage[] supportedLanguages = ((DaFitSettingLanguage) setting).decodeSupportedValues(data);
+ Set supportedLanguagesList = new HashSet<>();
+ for(DaFitEnumLanguage supportedLanguage : supportedLanguages)
+ supportedLanguagesList.add(String.valueOf(supportedLanguage.value()));
+ prefsEditor.putStringSet(DaFitConstants.PREF_LANGUAGE_SUPPORT, supportedLanguagesList);
+ break;
+
+ case "DEVICE_VERSION":
+ DaFitEnumDeviceVersion deviceVersion = (DaFitEnumDeviceVersion) value;
+ changedProperties.put(DaFitConstants.PREF_DEVICE_VERSION, String.valueOf(deviceVersion.value()));
+ break;
+
+ case "DO_NOT_DISTURB_TIME":
+ DaFitSettingTimeRange.TimeRange doNotDisturb = (DaFitSettingTimeRange.TimeRange) value;
+ if (doNotDisturb.start_h == 0 && doNotDisturb.start_m == 0 &&
+ doNotDisturb.end_h == 0 && doNotDisturb.end_m == 0)
+ changedProperties.put(MiBandConst.PREF_DO_NOT_DISTURB, MiBandConst.PREF_DO_NOT_DISTURB_OFF);
+ else
+ changedProperties.put(MiBandConst.PREF_DO_NOT_DISTURB, MiBandConst.PREF_DO_NOT_DISTURB_SCHEDULED);
+ changedProperties.put(MiBandConst.PREF_DO_NOT_DISTURB_START, String.format(Locale.ROOT, "%02d:%02d", doNotDisturb.start_h, doNotDisturb.start_m));
+ changedProperties.put(MiBandConst.PREF_DO_NOT_DISTURB_END, String.format(Locale.ROOT, "%02d:%02d", doNotDisturb.end_h, doNotDisturb.end_m));
+ break;
+
+ case "QUICK_VIEW":
+ boolean quickViewEnabled = (Boolean) value;
+ boolean quickViewScheduled = prefs.getString(HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT, getContext().getString(R.string.p_off)).equals(getContext().getString(R.string.p_scheduled));
+ changedProperties.put(HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT, quickViewEnabled ? (quickViewScheduled ? getContext().getString(R.string.p_scheduled) : getContext().getString(R.string.p_on)) : getContext().getString(R.string.p_off));
+ break;
+
+ case "QUICK_VIEW_TIME":
+ boolean quickViewEnabled2 = !prefs.getString(HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT, getContext().getString(R.string.p_off)).equals(getContext().getString(R.string.p_off));
+ DaFitSettingTimeRange.TimeRange quickViewTime = (DaFitSettingTimeRange.TimeRange) value;
+ if (quickViewEnabled2)
+ {
+ if (quickViewTime.start_h == 0 && quickViewTime.start_m == 0 &&
+ quickViewTime.end_h == 0 && quickViewTime.end_m == 0)
+ changedProperties.put(HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT, getContext().getString(R.string.p_on));
+ else
+ changedProperties.put(HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT, getContext().getString(R.string.p_scheduled));
+ }
+ changedProperties.put(HuamiConst.PREF_DISPLAY_ON_LIFT_START, String.format(Locale.ROOT, "%02d:%02d", quickViewTime.start_h, quickViewTime.start_m));
+ changedProperties.put(HuamiConst.PREF_DISPLAY_ON_LIFT_END, String.format(Locale.ROOT, "%02d:%02d", quickViewTime.end_h, quickViewTime.end_m));
+ break;
+
+ case "SEDENTARY_REMINDER":
+ boolean sedentaryReminderEnabled = (Boolean) value;
+ changedProperties.put(DaFitConstants.PREF_SEDENTARY_REMINDER, sedentaryReminderEnabled ? "on": "off");
+ break;
+
+ case "REMINDERS_TO_MOVE_PERIOD":
+ DaFitSettingRemindersToMove.RemindersToMove remindersToMove = (DaFitSettingRemindersToMove.RemindersToMove) value;
+ changedProperties.put(DaFitConstants.PREF_SEDENTARY_REMINDER_PERIOD, String.valueOf(remindersToMove.period));
+ changedProperties.put(DaFitConstants.PREF_SEDENTARY_REMINDER_STEPS, String.valueOf(remindersToMove.steps));
+ changedProperties.put(DaFitConstants.PREF_SEDENTARY_REMINDER_START, String.valueOf(remindersToMove.start_h));
+ changedProperties.put(DaFitConstants.PREF_SEDENTARY_REMINDER_END, String.valueOf(remindersToMove.end_h));
+ break;
+ }
+ for (Map.Entry property : changedProperties.entrySet())
+ prefsEditor.putString(property.getKey(), property.getValue());
+ prefsEditor.apply();
+ for (Map.Entry property : changedProperties.entrySet())
+ {
+ GBDeviceEventConfigurationRead configReadEvent = new GBDeviceEventConfigurationRead();
+ configReadEvent.config = property.getKey();
+ configReadEvent.event = GBDeviceEventConfigurationRead.Event.SUCCESS;
+ evaluateGBDeviceEvent(configReadEvent);
+ }
}
@Override
public void onTestNewFunction() {
+ try {
+ new QuerySettingsOperation(this).perform();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
@Override
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/dafit/QuerySettingsOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/dafit/QuerySettingsOperation.java
new file mode 100644
index 0000000000..35ecec657e
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/dafit/QuerySettingsOperation.java
@@ -0,0 +1,137 @@
+/* Copyright (C) 2019 krzys_h
+
+ 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.dafit;
+
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.util.Log;
+import android.util.Pair;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.UUID;
+
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.DaFitConstants;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.DaFitDeviceCoordinator;
+import nodomain.freeyourgadget.gadgetbridge.devices.dafit.settings.DaFitSetting;
+import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEOperation;
+import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
+import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
+import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
+
+public class QuerySettingsOperation extends AbstractBTLEOperation {
+
+ private static final Logger LOG = LoggerFactory.getLogger(QuerySettingsOperation.class);
+
+ private final DaFitSetting[] settingsToQuery;
+ private boolean[] received;
+
+ private DaFitPacketIn packetIn = new DaFitPacketIn();
+
+ public QuerySettingsOperation(DaFitDeviceSupport support, DaFitSetting[] settingsToQuery) {
+ super(support);
+ this.settingsToQuery = settingsToQuery;
+ }
+
+ public QuerySettingsOperation(DaFitDeviceSupport support) {
+ super(support);
+ DaFitDeviceCoordinator coordinator = (DaFitDeviceCoordinator) DeviceHelper.getInstance().getCoordinator(getDevice());
+ this.settingsToQuery = coordinator.getSupportedSettings();
+ }
+
+ @Override
+ protected void prePerform() {
+ getDevice().setBusyTask("Querying settings"); // mark as busy quickly to avoid interruptions from the outside
+ getDevice().sendDeviceUpdateIntent(getContext());
+ }
+
+ @Override
+ protected void doPerform() throws IOException {
+ received = new boolean[settingsToQuery.length];
+ TransactionBuilder builder = performInitialized("QuerySettingsOperation");
+ for (DaFitSetting setting : settingsToQuery)
+ {
+ if (setting.cmdQuery == -1)
+ continue;
+
+ getSupport().sendPacket(builder, DaFitPacketOut.buildPacket(setting.cmdQuery, new byte[0]));
+ }
+ builder.queue(getQueue());
+ }
+
+ @Override
+ public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
+ if (!isOperationRunning())
+ {
+ LOG.error("onCharacteristicChanged but operation is not running!");
+ }
+ else
+ {
+ UUID charUuid = characteristic.getUuid();
+ if (charUuid.equals(DaFitConstants.UUID_CHARACTERISTIC_DATA_IN))
+ {
+ if (packetIn.putFragment(characteristic.getValue())) {
+ Pair packet = DaFitPacketIn.parsePacket(packetIn.getPacket());
+ packetIn = new DaFitPacketIn();
+ if (packet != null) {
+ byte packetType = packet.first;
+ byte[] payload = packet.second;
+
+ if (handlePacket(packetType, payload))
+ return true;
+ }
+ }
+ }
+ }
+
+ return super.onCharacteristicChanged(gatt, characteristic);
+ }
+
+ private boolean handlePacket(byte packetType, byte[] payload) {
+ boolean handled = false;
+ boolean receivedEverything = true;
+ for(int i = 0; i < settingsToQuery.length; i++)
+ {
+ DaFitSetting setting = settingsToQuery[i];
+ if (setting.cmdQuery == -1)
+ continue;
+ if (setting.cmdQuery == packetType)
+ {
+ Object value = setting.decode(payload);
+ Log.i("SETTING QUERY", setting.name + " = " + value.toString());
+ received[i] = true;
+ handled = true;
+ }
+ else if (!received[i])
+ receivedEverything = false;
+ }
+ if (receivedEverything)
+ operationFinished();
+
+ return handled;
+ }
+
+ @Override
+ protected void operationFinished() {
+ operationStatus = OperationStatus.FINISHED;
+ if (getDevice() != null && getDevice().isConnected()) {
+ unsetBusy();
+ }
+ }
+}
diff --git a/app/src/main/res/drawable/ic_measurement_system.xml b/app/src/main/res/drawable/ic_measurement_system.xml
new file mode 100644
index 0000000000..18c9e5f550
--- /dev/null
+++ b/app/src/main/res/drawable/ic_measurement_system.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_sitting.xml b/app/src/main/res/drawable/ic_sitting.xml
new file mode 100644
index 0000000000..c46d270f13
--- /dev/null
+++ b/app/src/main/res/drawable/ic_sitting.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index 02215c3fd0..ea24547825 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -372,6 +372,16 @@
- @string/p_scheduled
+
+ - @string/off
+ - @string/on
+
+
+
+ - @string/p_off
+ - @string/p_on
+
+
- @string/mi2_dnd_off
- @string/mi2_dnd_automatic
@@ -2694,6 +2704,28 @@
- ru_RU
+
+ - Watch face 1
+ - Watch face 2
+ - Watch face 3
+
+
+
+ - 1
+ - 2
+ - 3
+
+
+
+ - Chinese edition
+ - International edition
+
+
+
+ - 0
+ - 1
+
+
- @string/off
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index affb53eef3..c0ec168a0a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -448,6 +448,13 @@
New Auth Protocol
Enable if your device no longer connects after a firmware upgrade
Stable Connection
+ Watch face
+ Device version
+ Sedentary reminder
+ Time period (minutes)
+ Minimum steps
+ Start time (hour)
+ End time (hour)
Units
Time format
diff --git a/app/src/main/res/xml/devicesettings_dafit_device_version.xml b/app/src/main/res/xml/devicesettings_dafit_device_version.xml
new file mode 100644
index 0000000000..b50f003ad3
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_dafit_device_version.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_dafit_language.xml b/app/src/main/res/xml/devicesettings_dafit_language.xml
new file mode 100644
index 0000000000..6eda642627
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_dafit_language.xml
@@ -0,0 +1,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/devicesettings_dafit_sedentary_reminder.xml b/app/src/main/res/xml/devicesettings_dafit_sedentary_reminder.xml
new file mode 100644
index 0000000000..b894876339
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_dafit_sedentary_reminder.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_dafit_watchface.xml b/app/src/main/res/xml/devicesettings_dafit_watchface.xml
new file mode 100644
index 0000000000..731e0d49e4
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_dafit_watchface.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_donotdisturb_no_auto_v2.xml b/app/src/main/res/xml/devicesettings_donotdisturb_no_auto_v2.xml
new file mode 100644
index 0000000000..486bde81d5
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_donotdisturb_no_auto_v2.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_measurementsystem.xml b/app/src/main/res/xml/devicesettings_measurementsystem.xml
new file mode 100644
index 0000000000..f324f3fa4d
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_measurementsystem.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/app/src/main/res/xml/devicesettings_personalinfo.xml b/app/src/main/res/xml/devicesettings_personalinfo.xml
new file mode 100644
index 0000000000..014fcbf60c
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_personalinfo.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+