diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java index d80e0d5d1..ab1a4cc35 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java @@ -62,8 +62,16 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION_END; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION_START; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ON_LIFT_END; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ON_LIFT_START; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DISPLAY_ITEMS; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_OFF; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_SCHEDULED; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ENABLE_TEXT_NOTIFICATIONS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI3_BAND_SCREEN_UNLOCK; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI3_NIGHT_MODE; @@ -496,6 +504,59 @@ public class SettingsActivity extends AbstractSettingsActivity { } }); + String disconnectNotificationState = prefs.getString(PREF_DISCONNECT_NOTIFICATION, PREF_MI2_DO_NOT_DISTURB_OFF); + boolean disconnectNotificationScheduled = disconnectNotificationState.equals(PREF_MI2_DO_NOT_DISTURB_SCHEDULED); + + final Preference disconnectNotificationStart = findPreference(PREF_DISCONNECT_NOTIFICATION_START); + disconnectNotificationStart.setEnabled(disconnectNotificationScheduled); + disconnectNotificationStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION_START); + } + }); + return true; + } + }); + + + final Preference disconnectNotificationEnd = findPreference(PREF_DISCONNECT_NOTIFICATION_END); + disconnectNotificationStart.setEnabled(disconnectNotificationScheduled); + disconnectNotificationStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION_END); + } + }); + return true; + } + }); + + + final Preference disconnectNotification = findPreference(PREF_DISCONNECT_NOTIFICATION); + disconnectNotification.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + final boolean scheduled = PREF_MI2_DO_NOT_DISTURB_SCHEDULED.equals(newVal.toString()); + + disconnectNotificationStart.setEnabled(scheduled); + disconnectNotificationEnd.setEnabled(scheduled); + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION); + } + }); + return true; + } + }); + // Get all receivers of Media Buttons Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/DisconnectNotificationSetting.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/DisconnectNotificationSetting.java new file mode 100644 index 000000000..14c9c659e --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/DisconnectNotificationSetting.java @@ -0,0 +1,23 @@ +/* Copyright (C) 2019 Andreas Shimokawa. + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.devices.huami; + +public enum DisconnectNotificationSetting { + ON, + OFF, + SCHEDULED +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java index a4bc82811..95b2986ca 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java @@ -48,6 +48,14 @@ public class HuamiConst { public static final String MI_BAND2_NAME_HRX = "Mi Band HRX"; public static final String MI_BAND3_NAME = "Mi Band 3"; + public static final String PREF_ACTIVATE_DISPLAY_ON_LIFT = "activate_display_on_lift_wrist"; + public static final String PREF_DISPLAY_ON_LIFT_START = "display_on_lift_start"; + public static final String PREF_DISPLAY_ON_LIFT_END = "display_on_lift_end"; + + public static final String PREF_DISCONNECT_NOTIFICATION = "disconnect_notification"; + public static final String PREF_DISCONNECT_NOTIFICATION_START = "disconnect_notification_start"; + public static final String PREF_DISCONNECT_NOTIFICATION_END = "disconnect_notification_end"; + public static int toActivityKind(int rawType) { switch (rawType) { case TYPE_DEEP_SLEEP: diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java index d10ecd8cc..5dc18aa54 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiCoordinator.java @@ -139,7 +139,7 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { String liftOn = context.getString(R.string.p_on); String liftScheduled = context.getString(R.string.p_scheduled); - String pref = prefs.getString(MiBandConst.PREF_ACTIVATE_DISPLAY_ON_LIFT, liftOff); + String pref = prefs.getString(HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT, liftOff); if (liftOn.equals(pref)) { return ActivateDisplayOnLift.ON; @@ -151,11 +151,37 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator { } public static Date getDisplayOnLiftStart() { - return getTimePreference( MiBandConst.PREF_DISPLAY_ON_LIFT_START, "00:00"); + return getTimePreference(HuamiConst.PREF_DISPLAY_ON_LIFT_START, "00:00"); } public static Date getDisplayOnLiftEnd() { - return getTimePreference( MiBandConst.PREF_DISPLAY_ON_LIFT_END, "00:00"); + return getTimePreference(HuamiConst.PREF_DISPLAY_ON_LIFT_END, "00:00"); + } + + public static DisconnectNotificationSetting getDisconnectNotificationSetting(Context context) { + Prefs prefs = GBApplication.getPrefs(); + + String liftOff = context.getString(R.string.p_off); + String liftOn = context.getString(R.string.p_on); + String liftScheduled = context.getString(R.string.p_scheduled); + + String pref = prefs.getString(HuamiConst.PREF_DISCONNECT_NOTIFICATION, liftOff); + + if (liftOn.equals(pref)) { + return DisconnectNotificationSetting.ON; + } else if (liftScheduled.equals(pref)) { + return DisconnectNotificationSetting.SCHEDULED; + } + + return DisconnectNotificationSetting.OFF; + } + + public static Date getDisconnectNotificationStart() { + return getTimePreference(HuamiConst.PREF_DISCONNECT_NOTIFICATION_START, "00:00"); + } + + public static Date getDisconnectNotificationEnd() { + return getTimePreference(HuamiConst.PREF_DISCONNECT_NOTIFICATION_END, "00:00"); } public static Set getDisplayItems() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java index 8463ebd59..01cb279d1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java @@ -150,6 +150,8 @@ public class HuamiService { public static final byte[] COMMAND_DISTANCE_UNIT_IMPERIAL = new byte[] { ENDPOINT_DISPLAY, 0x03, 0x00, 0x01 }; public static final byte[] COMMAND_SET_LANGUAGE_NEW_TEMPLATE = new byte[]{ENDPOINT_DISPLAY, 0x17, 0x00, 0, 0, 0, 0, 0}; public static final byte[] COMMAND_FACTORY_RESET = new byte[]{ENDPOINT_DISPLAY, 0x0b, 0x00, 0x01}; + public static final byte[] COMMAND_ENABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x01, 0, 0, 0, 0}; + public static final byte[] COMMAND_DISABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x00, 0, 0, 0, 0}; // The third byte controls the threshold, in minutes // The last 8 bytes represent 2 separate time intervals for the inactivity warnings diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java index 66cb6aa8f..92fa420b6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java @@ -49,9 +49,6 @@ public final class MiBandConst { public static final String PREF_MI2_DISPLAY_ITEM_CALORIES = "calories"; public static final String PREF_MI2_DISPLAY_ITEM_HEART_RATE = "heart_rate"; public static final String PREF_MI2_DISPLAY_ITEM_BATTERY = "battery"; - public static final String PREF_ACTIVATE_DISPLAY_ON_LIFT = "activate_display_on_lift_wrist"; - public static final String PREF_DISPLAY_ON_LIFT_START = "display_on_lift_start"; - public static final String PREF_DISPLAY_ON_LIFT_END = "display_on_lift_end"; public static final String PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO = "mi2_rotate_wrist_to_switch_info"; public static final String PREF_MI2_ENABLE_TEXT_NOTIFICATIONS = "mi2_enable_text_notifications"; public static final String PREF_MI2_DO_NOT_DISTURB = "mi2_do_not_disturb"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java index aafd33518..b23f3cb70 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java @@ -36,11 +36,11 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ON_LIFT_END; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ON_LIFT_START; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_ALARM_CLOCK; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_INCOMING_CALL; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_ACTIVATE_DISPLAY_ON_LIFT; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_DISPLAY_ON_LIFT_END; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_DISPLAY_ON_LIFT_START; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_END; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_OFF; @@ -120,7 +120,7 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity { } }); - String displayOnLiftState = prefs.getString(MiBandConst.PREF_ACTIVATE_DISPLAY_ON_LIFT, PREF_MI2_DO_NOT_DISTURB_OFF); + String displayOnLiftState = prefs.getString(PREF_ACTIVATE_DISPLAY_ON_LIFT, PREF_MI2_DO_NOT_DISTURB_OFF); boolean displayOnLiftScheduled = displayOnLiftState.equals(PREF_MI2_DO_NOT_DISTURB_SCHEDULED); final Preference rotateWristCycleInfo = findPreference(PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 3130d0df3..56a1947a3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -59,6 +59,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInf import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.huami.ActivateDisplayOnLift; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.DisconnectNotificationSetting; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; @@ -1506,11 +1507,16 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case MiBandConst.PREF_MI2_GOAL_NOTIFICATION: setGoalNotification(builder); break; - case MiBandConst.PREF_ACTIVATE_DISPLAY_ON_LIFT: - case MiBandConst.PREF_DISPLAY_ON_LIFT_START: - case MiBandConst.PREF_DISPLAY_ON_LIFT_END: + case HuamiConst.PREF_ACTIVATE_DISPLAY_ON_LIFT: + case HuamiConst.PREF_DISPLAY_ON_LIFT_START: + case HuamiConst.PREF_DISPLAY_ON_LIFT_END: setActivateDisplayOnLiftWrist(builder); break; + case HuamiConst.PREF_DISCONNECT_NOTIFICATION: + case HuamiConst.PREF_DISCONNECT_NOTIFICATION_START: + case HuamiConst.PREF_DISCONNECT_NOTIFICATION_END: + setDisconnectNotification(builder); + break; case MiBandConst.PREF_MI2_DISPLAY_ITEMS: setDisplayItems(builder); break; @@ -1756,6 +1762,37 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return this; } + private HuamiSupport setDisconnectNotification(TransactionBuilder builder) { + DisconnectNotificationSetting disconnectNotificationSetting = HuamiCoordinator.getDisconnectNotificationSetting(getContext()); + LOG.info("Setting disconnect notification to " + disconnectNotificationSetting); + + switch (disconnectNotificationSetting) { + case ON: + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_ENABLE_DISCONNECT_NOTIFCATION); + break; + case OFF: + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_DISABLE_DISCONNECT_NOTIFCATION); + break; + case SCHEDULED: + byte[] cmd = HuamiService.COMMAND_ENABLE_DISCONNECT_NOTIFCATION.clone(); + + Calendar calendar = GregorianCalendar.getInstance(); + + Date start = HuamiCoordinator.getDisconnectNotificationStart(); + calendar.setTime(start); + cmd[4] = (byte) calendar.get(Calendar.HOUR_OF_DAY); + cmd[5] = (byte) calendar.get(Calendar.MINUTE); + + Date end = HuamiCoordinator.getDisconnectNotificationEnd(); + calendar.setTime(end); + cmd[6] = (byte) calendar.get(Calendar.HOUR_OF_DAY); + cmd[7] = (byte) calendar.get(Calendar.MINUTE); + + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), cmd); + } + return this; + } + private HuamiSupport setDistanceUnit(TransactionBuilder builder) { MiBandConst.DistanceUnit unit = HuamiCoordinator.getDistanceUnit(); LOG.info("Setting distance unit to " + unit); @@ -1816,6 +1853,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { setGoalNotification(builder); setInactivityWarnings(builder); setHeartrateSleepSupport(builder); + setDisconnectNotification(builder); setHeartrateMeasurementInterval(builder, getHeartRateMeasurementInterval()); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7b9409ddc..50e676a74 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -426,6 +426,7 @@ Date format Time + Disconnect notification Button actions Specify actions on Mi Band 2 button press Button press count diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 95c8cd731..2b451bf11 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -342,6 +342,33 @@ android:key="bip_display_items" android:summary="@string/mi2_prefs_display_items_summary" android:title="@string/mi2_prefs_display_items"/> + + + + + + + + + + + + +