Mi Band 2: Implement multiple button actions

This enables option for multiple button actions according to the "Delay after button action". This broadcast is being sent to the intent
along with button_id extra identifying how many times have the pass been done.

By pass defined number of button presses is meant.
This commit is contained in:
Michal Novotny 2017-09-10 21:11:50 +02:00 committed by Carsten Pfeiffer
parent 851e47f550
commit 05d0625b68
6 changed files with 94 additions and 48 deletions

View File

@ -36,6 +36,7 @@ public final class MiBandConst {
public static final String PREF_MIBAND_BUTTON_ACTION_VIBRATE = "mi2_button_action_vibrate";
public static final String PREF_MIBAND_BUTTON_PRESS_COUNT = "mi_button_press_count";
public static final String PREF_MIBAND_BUTTON_PRESS_MAX_DELAY = "mi_button_press_count_max_delay";
public static final String PREF_MIBAND_BUTTON_ACTION_DELAY = "mi_button_press_count_match_delay";
public static final String PREF_MIBAND_BUTTON_PRESS_BROADCAST = "mi_button_press_broadcast";
public static final String PREF_MIBAND_USE_HR_FOR_SLEEP_DETECTION = "mi_hr_sleep_detection";
public static final String PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS = "mi_device_time_offset_hours";

View File

@ -24,9 +24,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager;
import android.text.format.DateFormat;
import android.widget.Toast;
@ -42,6 +40,8 @@ import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@ -126,8 +126,10 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ge
public class MiBand2Support extends AbstractBTLEDeviceSupport {
// We introduce key press counter for notification purposes
private static int currentButtonActionId = 0;
private static int currentButtonPressCount = 0;
private static long currentButtonPressTime = 0;
private static long currentButtonTimerActivationTime = 0;
private static final Logger LOG = LoggerFactory.getLogger(MiBand2Support.class);
private final DeviceInfoProfile<MiBand2Support> deviceInfoProfile;
@ -782,6 +784,80 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
// not supported
}
public void runButtonAction() {
Prefs prefs = GBApplication.getPrefs();
if (currentButtonTimerActivationTime != currentButtonPressTime) {
return;
}
String requiredButtonPressMessage = prefs.getString(MiBandConst.PREF_MIBAND_BUTTON_PRESS_BROADCAST,
this.getContext().getString(R.string.mi2_prefs_button_press_broadcast_default_value));
Intent in = new Intent();
in.setAction(requiredButtonPressMessage);
in.putExtra("button_id", currentButtonActionId);
LOG.info("Sending " + requiredButtonPressMessage + " with button_id " + currentButtonActionId);
this.getContext().getApplicationContext().sendBroadcast(in);
if (prefs.getBoolean(MiBandConst.PREF_MIBAND_BUTTON_ACTION_VIBRATE, false)) {
performPreferredNotification(null, null, null, MiBand2Service.ALERT_LEVEL_VIBRATE_ONLY, null);
}
currentButtonActionId = 0;
currentButtonPressCount = 0;
currentButtonPressTime = System.currentTimeMillis();
}
public void handleButtonPressed(byte[] value) {
LOG.info("Button pressed");
///logMessageContent(value);
// If disabled we return from function immediately
Prefs prefs = GBApplication.getPrefs();
if (!prefs.getBoolean(MiBandConst.PREF_MIBAND_BUTTON_ACTION_ENABLE, false)) {
return;
}
int buttonPressMaxDelay = prefs.getInt(MiBandConst.PREF_MIBAND_BUTTON_PRESS_MAX_DELAY, 2000);
int buttonActionDelay = prefs.getInt(MiBandConst.PREF_MIBAND_BUTTON_ACTION_DELAY, 0);
int requiredButtonPressCount = prefs.getInt(MiBandConst.PREF_MIBAND_BUTTON_PRESS_COUNT, 0);
if (requiredButtonPressCount > 0) {
long timeSinceLastPress = System.currentTimeMillis() - currentButtonPressTime;
if ((currentButtonPressTime == 0) || (timeSinceLastPress < buttonPressMaxDelay)) {
currentButtonPressCount++;
}
else {
currentButtonPressCount = 1;
currentButtonActionId = 0;
}
currentButtonPressTime = System.currentTimeMillis();
if (currentButtonPressCount == requiredButtonPressCount) {
currentButtonTimerActivationTime = currentButtonPressTime;
if (buttonActionDelay > 0) {
LOG.info("Activating timer");
final Timer buttonActionTimer = new Timer("Mi Band Button Action Timer");
buttonActionTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runButtonAction();
buttonActionTimer.cancel();
}
}, buttonActionDelay, buttonActionDelay);
}
else {
LOG.info("Activating button action");
runButtonAction();
}
currentButtonActionId++;
currentButtonPressCount = 0;
}
}
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
@ -811,54 +887,10 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
logMessageContent(characteristic.getValue());
}
return false;
}
public void handleButtonPressed(byte[] value) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.getContext());
LOG.info("Button pressed");
logMessageContent(value);
Prefs prefs = GBApplication.getPrefs();
// If disabled we return from function immediately
if (!prefs.getBoolean(MiBandConst.PREF_MIBAND_BUTTON_ACTION_ENABLE, false)) {
return;
}
int buttonPressMaxDelay = prefs.getInt(MiBandConst.PREF_MIBAND_BUTTON_PRESS_MAX_DELAY, 2000);
int requiredButtonPressCount = prefs.getInt(MiBandConst.PREF_MIBAND_BUTTON_PRESS_COUNT, 0);
String requiredButtonPressMessage = prefs.getString(MiBandConst.PREF_MIBAND_BUTTON_PRESS_BROADCAST,
this.getContext().getString(R.string.mi2_prefs_button_press_broadcast_default_value));
if (requiredButtonPressCount > 0) {
long timeSinceLastPress = System.currentTimeMillis() - currentButtonPressTime;
if ((currentButtonPressTime == 0) || (timeSinceLastPress < buttonPressMaxDelay)) {
currentButtonPressCount++;
}
else {
currentButtonPressCount = 0;
}
currentButtonPressTime = System.currentTimeMillis();
if (currentButtonPressCount >= requiredButtonPressCount) {
Intent in = new Intent();
in.setAction(requiredButtonPressMessage);
this.getContext().getApplicationContext().sendBroadcast(in);
currentButtonPressCount = 0;
currentButtonPressTime = System.currentTimeMillis();
if (prefs.getBoolean(MiBandConst.PREF_MIBAND_BUTTON_ACTION_VIBRATE, false)) {
performPreferredNotification(null, null, null, MiBand2Service.ALERT_LEVEL_VIBRATE_ONLY, null);
}
}
}
}
private void handleUnknownCharacteristic(byte[] value) {
}
@ -888,6 +920,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
LOG.info("Unhandled characteristic read: " + characteristicUUID);
logMessageContent(characteristic.getValue());
}
return false;
}
@ -1063,6 +1096,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
// getContext().getString(R.string.DEVINFO_HR_VER),
// info.getSoftwareRevision()));
// }
LOG.warn("Device info: " + info);
versionCmd.hwVersion = info.getHardwareRevision();
// versionCmd.fwVersion = info.getFirmwareRevision(); // always null

View File

@ -68,4 +68,4 @@ public class Version implements Comparable<Version> {
public int hashCode() {
return version.hashCode();
}
}
}

View File

@ -420,6 +420,8 @@
<string name="mi2_prefs_button_action_vibrate_summary">Povolit vibrace náramku při vyslání broadcast zprávy</string>
<string name="mi2_prefs_button_press_count_max_delay">Maximální prodleva mezi stisky</string>
<string name="mi2_prefs_button_press_count_max_delay_summary">Maximální prodleva mezi stisky tlačítka v milisekundách</string>
<string name="mi2_prefs_button_press_count_match_delay">Prodleva před akcí</string>
<string name="mi2_prefs_button_press_count_match_delay_summary">Prodleva před akcí tlačítka. Umožňuje více průchodů (v extra button_id u Intent) nebo 0 pro okamžitou akci</string>
<string name="fw_upgrade_notice_amazfitbip">Chystáte se nainstalovat firmware %s namísto toho, který je aktuálně na vašem Amazfit Bipu.
\n
\nUjistěte se, že jste nainstalovali firmware .gps, pak soubor .res a nakonec soubor .fw. Hodiny se po instalaci souboru .fw restartují.

View File

@ -364,6 +364,8 @@
<string name="mi2_prefs_button_action_vibrate_summary">Enable band vibration on button action triggered</string>
<string name="mi2_prefs_button_press_count_max_delay">Maximum delay between presses</string>
<string name="mi2_prefs_button_press_count_max_delay_summary">Maximum delay between button presses in milliseconds</string>
<string name="mi2_prefs_button_press_count_match_delay">Delay after button action</string>
<string name="mi2_prefs_button_press_count_match_delay_summary">Delay after one button action match (number is in button_id intent extra) or 0 for immediately</string>
<string name="mi2_prefs_goal_notification">Goal notification</string>
<string name="mi2_prefs_goal_notification_summary">The band will vibrate when the daily steps goal is reached</string>
<string name="mi2_prefs_display_items">Display items</string>

View File

@ -72,6 +72,13 @@
android:key="mi_button_press_count_max_delay"
android:summary="@string/mi2_prefs_button_press_count_max_delay_summary"
android:title="@string/mi2_prefs_button_press_count_max_delay" />
<EditTextPreference
android:defaultValue="0"
android:inputType="number"
android:key="mi_button_press_count_match_delay"
android:summary="@string/mi2_prefs_button_press_count_match_delay_summary"
android:title="@string/mi2_prefs_button_press_count_match_delay" />
</PreferenceScreen>
<EditTextPreference