diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java
new file mode 100644
index 000000000..138fd275a
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/DoNotDisturb.java
@@ -0,0 +1,7 @@
+package nodomain.freeyourgadget.gadgetbridge.devices.miband;
+
+public enum DoNotDisturb {
+ OFF,
+ AUTOMATIC,
+ SCHEDULED
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Coordinator.java
index 6dda128bb..535da565b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Coordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Coordinator.java
@@ -28,8 +28,11 @@ import android.support.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@@ -44,6 +47,9 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
+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_START;
+
public class MiBand2Coordinator extends MiBandCoordinator {
private static final Logger LOG = LoggerFactory.getLogger(MiBand2Coordinator.class);
@@ -133,6 +139,50 @@ public class MiBand2Coordinator extends MiBandCoordinator {
return prefs.getBoolean(MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO, false);
}
+ public static Date getDoNotDisturbStart() {
+ Prefs prefs = GBApplication.getPrefs();
+ String time = prefs.getString(PREF_MI2_DO_NOT_DISTURB_START, "01:00");
+
+ DateFormat df = new SimpleDateFormat("HH:mm");
+ try {
+ return df.parse(time);
+ } catch(Exception e) {
+ }
+
+ return new Date();
+ }
+
+ public static Date getDoNotDisturbEnd() {
+ Prefs prefs = GBApplication.getPrefs();
+ String time = prefs.getString(PREF_MI2_DO_NOT_DISTURB_END, "06:00");
+
+ DateFormat df = new SimpleDateFormat("HH:mm");
+ try {
+ return df.parse(time);
+ } catch(Exception e) {
+ }
+
+ return new Date();
+ }
+
+ public static DoNotDisturb getDoNotDisturb(Context context) {
+ Prefs prefs = GBApplication.getPrefs();
+
+ String dndOff = context.getString(R.string.p_off);
+ String dndAutomatic = context.getString(R.string.p_automatic);
+ String dndScheduled = context.getString(R.string.p_scheduled);
+
+ String pref = prefs.getString(MiBandConst.PREF_MI2_DO_NOT_DISTURB, dndOff);
+
+ if (dndAutomatic.equals(pref)) {
+ return DoNotDisturb.AUTOMATIC;
+ } else if (dndScheduled.equals(pref)) {
+ return DoNotDisturb.SCHEDULED;
+ }
+
+ return DoNotDisturb.OFF;
+ }
+
@Override
public InstallHandler findInstallHandler(Uri uri, Context context) {
MiBand2FWInstallHandler handler = new MiBand2FWInstallHandler(uri, context);
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 315d95337..3442cecbd 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
@@ -174,6 +174,17 @@ public class MiBand2Service {
public static final byte[] DISPLAY_XXX = new byte[] {ENDPOINT_DISPLAY, 0x03, 0x0, 0x0 };
public static final byte[] DISPLAY_YYY = new byte[] {ENDPOINT_DISPLAY, 0x10, 0x0, 0x1, 0x1 };
+ public static byte ENDPOINT_DND = 0x09;
+
+ public static final byte[] COMMAND_DO_NOT_DISTURB_AUTOMATIC = new byte[] { ENDPOINT_DND, (byte) 0x83 };
+ public static final byte[] COMMAND_DO_NOT_DISTURB_OFF = new byte[] { ENDPOINT_DND, (byte) 0x82 };
+ public static final byte[] COMMAND_DO_NOT_DISTURB_SCHEDULED = new byte[] { ENDPOINT_DND, (byte) 0x81, 0x01, 0x00, 0x06, 0x00 };
+ // The 4 last bytes set the start and end time in 24h format
+ public static byte DND_BYTE_START_HOURS = 2;
+ public static byte DND_BYTE_START_MINUTES = 3;
+ public static byte DND_BYTE_END_HOURS = 4;
+ public static byte DND_BYTE_END_MINUTES = 5;
+
public static final byte RESPONSE = 0x10;
public static final byte SUCCESS = 0x01;
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 61b809688..a9bffb2c5 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
@@ -46,6 +46,12 @@ public final class MiBandConst {
public static final String PREF_MI2_ACTIVATE_DISPLAY_ON_LIFT = "mi2_activate_display_on_lift_wrist";
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";
+ public static final String PREF_MI2_DO_NOT_DISTURB_OFF = "off";
+ public static final String PREF_MI2_DO_NOT_DISTURB_AUTOMATIC = "automatic";
+ public static final String PREF_MI2_DO_NOT_DISTURB_SCHEDULED = "scheduled";
+ public static final String PREF_MI2_DO_NOT_DISTURB_START = "mi2_do_not_disturb_start";
+ public static final String PREF_MI2_DO_NOT_DISTURB_END = "mi2_do_not_disturb_end";
public static final String PREF_MIBAND_SETUP_BT_PAIRING = "mi_setup_bt_pairing";
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 0b8911a79..124608a2c 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
@@ -34,12 +34,18 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
+import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_ALARM_CLOCK;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_INCOMING_CALL;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ACTIVATE_DISPLAY_ON_LIFT;
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;
+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;
+import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_SCHEDULED;
+import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_START;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ENABLE_TEXT_NOTIFICATIONS;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_GOAL_NOTIFICATION;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO;
@@ -60,6 +66,8 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity {
addTryListeners();
+ Prefs prefs = GBApplication.getPrefs();
+
final Preference enableHeartrateSleepSupport = findPreference(PREF_MIBAND_USE_HR_FOR_SLEEP_DETECTION);
enableHeartrateSleepSupport.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
@@ -139,6 +147,58 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity {
}
});
+ String doNotDisturbState = prefs.getString(MiBandConst.PREF_MI2_DO_NOT_DISTURB, PREF_MI2_DO_NOT_DISTURB_OFF);
+ boolean doNotDisturbScheduled = doNotDisturbState.equals(PREF_MI2_DO_NOT_DISTURB_SCHEDULED);
+
+ final Preference doNotDisturbStart = findPreference(PREF_MI2_DO_NOT_DISTURB_START);
+ doNotDisturbStart.setEnabled(doNotDisturbScheduled);
+ doNotDisturbStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newVal) {
+ invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ GBApplication.deviceService().onSendConfiguration(PREF_MI2_DO_NOT_DISTURB_START);
+ }
+ });
+ return true;
+ }
+ });
+
+ final Preference doNotDisturbEnd = findPreference(PREF_MI2_DO_NOT_DISTURB_END);
+ doNotDisturbEnd.setEnabled(doNotDisturbScheduled);
+ doNotDisturbEnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newVal) {
+ invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ GBApplication.deviceService().onSendConfiguration(PREF_MI2_DO_NOT_DISTURB_END);
+ }
+ });
+ return true;
+ }
+ });
+
+ final Preference doNotDisturb = findPreference(PREF_MI2_DO_NOT_DISTURB);
+ doNotDisturb.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newVal) {
+ final boolean scheduled = PREF_MI2_DO_NOT_DISTURB_SCHEDULED.equals(newVal.toString());
+
+ doNotDisturbStart.setEnabled(scheduled);
+ doNotDisturbEnd.setEnabled(scheduled);
+
+ invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ GBApplication.deviceService().onSendConfiguration(PREF_MI2_DO_NOT_DISTURB);
+ }
+ });
+ return true;
+ }
+ });
+
final Preference fitnessGoal = findPreference(ActivityUser.PREF_USER_STEPS_GOAL);
fitnessGoal.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java
index bd820eafe..13878293c 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
@@ -36,6 +36,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Set;
@@ -51,6 +52,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInf
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.DateTimeDisplay;
+import nodomain.freeyourgadget.gadgetbridge.devices.miband.DoNotDisturb;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service;
@@ -1091,6 +1093,10 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
case ActivityUser.PREF_USER_STEPS_GOAL:
setFitnessGoal(builder);
break;
+ case MiBandConst.PREF_MI2_DO_NOT_DISTURB:
+ case MiBandConst.PREF_MI2_DO_NOT_DISTURB_START:
+ case MiBandConst.PREF_MI2_DO_NOT_DISTURB_END:
+ setDoNotDisturb(builder);
}
builder.queue(getQueue());
} catch (IOException e) {
@@ -1199,6 +1205,39 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
return this;
}
+ private MiBand2Support setDoNotDisturb(TransactionBuilder builder) {
+ DoNotDisturb doNotDisturb = MiBand2Coordinator.getDoNotDisturb(getContext());
+ LOG.info("Setting do not disturb to " + doNotDisturb);
+ switch (doNotDisturb) {
+ case OFF:
+ builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_DO_NOT_DISTURB_OFF);
+ break;
+ case AUTOMATIC:
+ builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_DO_NOT_DISTURB_AUTOMATIC);
+ break;
+ case SCHEDULED:
+ byte[] data = MiBand2Service.COMMAND_DO_NOT_DISTURB_SCHEDULED.clone();
+
+ Calendar calendar = GregorianCalendar.getInstance();
+
+ Date start = MiBand2Coordinator.getDoNotDisturbStart();
+ calendar.setTime(start);
+ data[MiBand2Service.DND_BYTE_START_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY);
+ data[MiBand2Service.DND_BYTE_START_MINUTES] = (byte) calendar.get(Calendar.MINUTE);
+
+ Date end = MiBand2Coordinator.getDoNotDisturbEnd();
+ calendar.setTime(end);
+ data[MiBand2Service.DND_BYTE_END_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY);
+ data[MiBand2Service.DND_BYTE_END_MINUTES] = (byte) calendar.get(Calendar.MINUTE);
+
+ builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), data);
+
+ break;
+ }
+
+ return this;
+ }
+
public void phase2Initialize(TransactionBuilder builder) {
LOG.info("phase2Initialize...");
enableFurtherNotifications(builder, true);
@@ -1208,6 +1247,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
setWearLocation(builder);
setFitnessGoal(builder);
setDisplayItems(builder);
+ setDoNotDisturb(builder);
setRotateWristToSwitchInfo(builder);
setActivateDisplayOnLiftWrist(builder);
setGoalNotification(builder);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java
new file mode 100644
index 000000000..409557db6
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/TimePreference.java
@@ -0,0 +1,100 @@
+package nodomain.freeyourgadget.gadgetbridge.util;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.preference.DialogPreference;
+import android.text.format.DateFormat;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TimePicker;
+
+public class TimePreference extends DialogPreference {
+ private int hour = 0;
+ private int minute = 0;
+
+ private TimePicker picker = null;
+
+ public TimePreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected View onCreateDialogView() {
+ picker = new TimePicker(getContext());
+ picker.setIs24HourView(DateFormat.is24HourFormat(getContext()));
+ picker.setPadding(0, 50, 0, 50);
+
+ return picker;
+ }
+
+ @Override
+ protected void onBindDialogView(View v) {
+ super.onBindDialogView(v);
+
+ picker.setCurrentHour(hour);
+ picker.setCurrentMinute(minute);
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ super.onDialogClosed(positiveResult);
+
+ if (positiveResult) {
+ hour = picker.getCurrentHour();
+ minute = picker.getCurrentMinute();
+
+ String time = getTime24h();
+
+ if (callChangeListener(time)) {
+ persistString(time);
+
+ updateSummary();
+ }
+ }
+ }
+
+ @Override
+ protected Object onGetDefaultValue(TypedArray a, int index) {
+ return a.getString(index);
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ String time;
+
+ if (restoreValue) {
+ if (defaultValue == null) {
+ time = getPersistedString("00:00");
+ } else {
+ time = getPersistedString(defaultValue.toString());
+ }
+ } else {
+ time = defaultValue.toString();
+ }
+
+ String[] pieces = time.split(":");
+
+ hour = Integer.parseInt(pieces[0]);
+ minute = Integer.parseInt(pieces[1]);
+
+ updateSummary();
+ }
+
+ public void updateSummary() {
+ if (DateFormat.is24HourFormat(getContext()))
+ setSummary(getTime24h());
+ else
+ setSummary(getTime12h());
+ }
+
+ public String getTime24h() {
+ return String.format("%02d", hour) + ":" + String.format("%02d", minute);
+ }
+
+ public String getTime12h() {
+ String suffix = hour < 12 ? " AM" : " PM";
+ int h = hour > 12 ? hour - 12 : hour;
+
+ return String.valueOf(h) + ":" + String.format("%02d", minute) + suffix;
+ }
+}
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 174573ccb..3516f7d21 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -306,6 +306,10 @@
Escolher os items a mostrar no ecrã
Ativar ecrã do dispositivo quando o levantar
Rodar o pulso para mudar de ecrã
+ Não incomodar
+ A pulseira não recebe notificações enquanto activo
+ Hora de início
+ Hora de fim
Prestes a transferir dados desde %1$s
aguarde para tornar a ligar
Sobre você
@@ -371,6 +375,9 @@
Notificações de texto
= 1.0.1.28 e Mili_pro.ft* instalado.]]>
desligado
+ Desligado
+ Automático (deteção de sono)
+ Agendado (intervalo de tempo)
A tentar emparelhar com %1$s
Ative o Bluetooth para encontrar os dispositivos.
Emparelhar com %1$s?
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index ed31547d7..f6583a398 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -135,6 +135,17 @@
- @string/p_dateformat_datetime
+
+ - @string/mi2_dnd_off
+ - @string/mi2_dnd_automatic
+ - @string/mi2_dnd_scheduled
+
+
+ - @string/p_off
+ - @string/p_automatic
+ - @string/p_scheduled
+
+
- @string/chart_steps
- @string/distance
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0c5c0d154..4bc1ccf0e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -352,6 +352,10 @@
Choose the items displayed on the band screen
Activate display upon lift
Rotate wrist to switch info
+ Do Not Disturb
+ The band won\'t receive notifications while active
+ Start time
+ End time
About to transfer data since %1$s
waiting for reconnect
@@ -429,6 +433,9 @@
Text notifications
= 1.0.1.28 and Mili_pro.ft* installed.]]>
off
+ Off
+ Automatic (sleep detection)
+ Scheduled (time interval)
Attempting to pair with %1$s
Bonding with %1$s failed immediately.
Trying to connect to: %1$s
diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml
index 10b562f26..addbce96c 100644
--- a/app/src/main/res/values/values.xml
+++ b/app/src/main/res/values/values.xml
@@ -19,6 +19,10 @@
- heart_rate
- battery
+ - off
+ - automatic
+ - scheduled
+
- metric
- imperial
diff --git a/app/src/main/res/xml/miband_preferences.xml b/app/src/main/res/xml/miband_preferences.xml
index 8ce547200..e7338045f 100644
--- a/app/src/main/res/xml/miband_preferences.xml
+++ b/app/src/main/res/xml/miband_preferences.xml
@@ -86,6 +86,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+