Mi Band 2: Do Not Disturb

master
José Rebelo 2017-07-15 14:01:07 +01:00 committed by Carsten Pfeiffer
parent 01d3a3a7be
commit 34bd2ed9cc
12 changed files with 334 additions and 0 deletions

View File

@ -0,0 +1,7 @@
package nodomain.freeyourgadget.gadgetbridge.devices.miband;
public enum DoNotDisturb {
OFF,
AUTOMATIC,
SCHEDULED
}

View File

@ -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);

View File

@ -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;

View File

@ -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";

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}

View File

@ -306,6 +306,10 @@
<string name="mi2_prefs_display_items_summary">Escolher os items a mostrar no ecrã</string>
<string name="mi2_prefs_activate_display_on_lift">Ativar ecrã do dispositivo quando o levantar</string>
<string name="mi2_prefs_rotate_wrist_to_switch_info">Rodar o pulso para mudar de ecrã</string>
<string name="mi2_prefs_do_not_disturb">Não incomodar</string>
<string name="mi2_prefs_do_not_disturb_summary">A pulseira não recebe notificações enquanto activo</string>
<string name="mi2_prefs_do_not_disturb_start">Hora de início</string>
<string name="mi2_prefs_do_not_disturb_end">Hora de fim</string>
<string name="FetchActivityOperation_about_to_transfer_since">Prestes a transferir dados desde %1$s</string>
<string name="waiting_for_reconnect">aguarde para tornar a ligar</string>
<string name="activity_prefs_about_you">Sobre você</string>
@ -371,6 +375,9 @@
<string name="mi2_enable_text_notifications">Notificações de texto</string>
<string name="mi2_enable_text_notifications_summary"><![CDATA[Necessita de firmware >= 1.0.1.28 e Mili_pro.ft* instalado.]]></string>
<string name="off">desligado</string>
<string name="mi2_dnd_off">Desligado</string>
<string name="mi2_dnd_automatic">Automático (deteção de sono)</string>
<string name="mi2_dnd_scheduled">Agendado (intervalo de tempo)</string>
<string name="discovery_attempting_to_pair">A tentar emparelhar com %1$s</string>
<string name="discovery_enable_bluetooth">Ative o Bluetooth para encontrar os dispositivos.</string>
<string name="discovery_pair_title">Emparelhar com %1$s?</string>

View File

@ -135,6 +135,17 @@
<item>@string/p_dateformat_datetime</item>
</string-array>
<string-array name="mi2_do_not_disturb">
<item>@string/mi2_dnd_off</item>
<item>@string/mi2_dnd_automatic</item>
<item>@string/mi2_dnd_scheduled</item>
</string-array>
<string-array name="mi2_do_not_disturb_values">
<item>@string/p_off</item>
<item>@string/p_automatic</item>
<item>@string/p_scheduled</item>
</string-array>
<string-array name="pref_mi2_display_items">
<item>@string/chart_steps</item>
<item>@string/distance</item>

View File

@ -352,6 +352,10 @@
<string name="mi2_prefs_display_items_summary">Choose the items displayed on the band screen</string>
<string name="mi2_prefs_activate_display_on_lift">Activate display upon lift</string>
<string name="mi2_prefs_rotate_wrist_to_switch_info">Rotate wrist to switch info</string>
<string name="mi2_prefs_do_not_disturb">Do Not Disturb</string>
<string name="mi2_prefs_do_not_disturb_summary">The band won\'t receive notifications while active</string>
<string name="mi2_prefs_do_not_disturb_start">Start time</string>
<string name="mi2_prefs_do_not_disturb_end">End time</string>
<string name="FetchActivityOperation_about_to_transfer_since">About to transfer data since %1$s</string>
<string name="waiting_for_reconnect">waiting for reconnect</string>
@ -429,6 +433,9 @@
<string name="mi2_enable_text_notifications">Text notifications</string>
<string name="mi2_enable_text_notifications_summary"><![CDATA[Needs firmware >= 1.0.1.28 and Mili_pro.ft* installed.]]></string>
<string name="off">off</string>
<string name="mi2_dnd_off">Off</string>
<string name="mi2_dnd_automatic">Automatic (sleep detection)</string>
<string name="mi2_dnd_scheduled">Scheduled (time interval)</string>
<string name="discovery_attempting_to_pair">Attempting to pair with %1$s</string>
<string name="discovery_bonding_failed_immediately">Bonding with %1$s failed immediately.</string>
<string name="discovery_trying_to_connect_to">Trying to connect to: %1$s</string>

View File

@ -19,6 +19,10 @@
<item name="p_heart_rate" type="string">heart_rate</item>
<item name="p_battery" type="string">battery</item>
<item name="p_off" type="string">off</item>
<item name="p_automatic" type="string">automatic</item>
<item name="p_scheduled" type="string">scheduled</item>
<item name="p_unit_metric" type="string">metric</item>
<item name="p_unit_imperial" type="string">imperial</item>

View File

@ -86,6 +86,37 @@
</PreferenceCategory>
<PreferenceScreen
android:key="mi2_do_not_disturb_key"
android:title="@string/mi2_prefs_do_not_disturb"
android:persistent="false"
android:summary="@string/mi2_prefs_do_not_disturb_summary">
<!-- workaround for missing toolbar -->
<PreferenceCategory
android:title="@string/mi2_prefs_do_not_disturb"
/>
<ListPreference
android:defaultValue="@string/p_off"
android:entries="@array/mi2_do_not_disturb"
android:entryValues="@array/mi2_do_not_disturb_values"
android:key="mi2_do_not_disturb"
android:title="@string/mi2_prefs_do_not_disturb"
android:summary="%s" />
<nodomain.freeyourgadget.gadgetbridge.util.TimePreference
android:defaultValue="01:00"
android:key="mi2_do_not_disturb_start"
android:title="@string/mi2_prefs_do_not_disturb_start" />
<nodomain.freeyourgadget.gadgetbridge.util.TimePreference
android:defaultValue="06:00"
android:key="mi2_do_not_disturb_end"
android:title="@string/mi2_prefs_do_not_disturb_end" />
</PreferenceScreen>
<PreferenceCategory
android:key="pref_category_miband_notification"
android:title="@string/pref_header_vibration_settings">