Support configurable notifications. Closes #53

To close #29, we need to have a bit more configuration options than
just the number of vibrations. E.g.
- duration
- pause
- LED flashing (again, number of flashes, duration and pause, but also
  the colour and maybe which LEDs)

Also implements reboot-functionality for Mi Band.
This commit is contained in:
cpfeiffer 2015-05-17 22:57:37 +02:00
parent 4be50b3a82
commit d1d3e758d9
3 changed files with 160 additions and 25 deletions

View File

@ -1,14 +1,56 @@
package nodomain.freeyourgadget.gadgetbridge.miband;
public interface MiBandConst {
String PREF_USER_ALIAS = "mi_user_alias";
String PREF_USER_YEAR_OF_BIRTH = "mi_user_year_of_birth";
String PREF_USER_GENDER = "mi_user_gender";
String PREF_USER_HEIGHT_CM = "mi_user_height_cm";
String PREF_USER_WEIGHT_KG = "mi_user_weight_kg";
String PREF_MIBAND_ADDRESS = "development_miaddr"; // FIXME: should be prefixed mi_
String PREF_VIBRATION_COUNT_SMS = "mi_vibration_count_sms";
String PREF_VIBRATION_COUNT_K9MAIL = "mi_vibration_count_k9mail";
String PREF_VIBRATION_COUNT_PEBBLEMSG = "mi_vibration_count_pebblemsg";
String PREF_VIBRATION_COUNT_GENERIC = "mi_vibration_count_generic";
import android.content.SharedPreferences;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class MiBandConst {
private static final Logger LOG = LoggerFactory.getLogger(MiBandConst.class);
public static final String PREF_USER_ALIAS = "mi_user_alias";
public static final String PREF_USER_YEAR_OF_BIRTH = "mi_user_year_of_birth";
public static final String PREF_USER_GENDER = "mi_user_gender";
public static final String PREF_USER_HEIGHT_CM = "mi_user_height_cm";
public static final String PREF_USER_WEIGHT_KG = "mi_user_weight_kg";
public static final String PREF_MIBAND_ADDRESS = "development_miaddr"; // FIXME: should be prefixed mi_
public static final String ORIGIN_SMS = "sms";
public static final String ORIGIN_K9MAIL = "k9mail";
public static final String ORIGIN_PEBBLEMSG = "pebblemsg";
public static final String ORIGIN_GENERIC = "generic";
public static int getNotificationPrefIntValue(String pref, String origin, SharedPreferences prefs, int defaultValue) {
String key = getNotificationPrefKey(pref, origin);
String value = null;
try {
value = prefs.getString(key, String.valueOf(defaultValue));
return Integer.valueOf(value).intValue();
} catch (NumberFormatException ex) {
LOG.error("Error converting preference value to int: " + key + ": " + value);
return defaultValue;
}
}
public static final String getNotificationPrefKey(String pref, String origin) {
return new StringBuilder(pref).append('_').append(origin).toString();
}
public static final String VIBRATION_COUNT = "mi_vibration_count";
public static final String VIBRATION_DURATION = "mi_vibration_duration";
public static final String VIBRATION_PAUSE = "mi_vibration_pause";
public static final String FLASH_COUNT = "mi_flash_count";
public static final String FLASH_DURATION = "mi_flash_duration";
public static final String FLASH_PAUSE = "mi_flash_pause";
public static final String FLASH_COLOUR = "mi_flash_colour";
public static final String FLASH_ORIGINAL_COLOUR = "mi_flash_original_colour";
public static final int DEFAULT_VALUE_VIBRATION_COUNT = 6;
public static final int DEFAULT_VALUE_VIBRATION_DURATION = 500; // ms
public static final int DEFAULT_VALUE_VIBRATION_PAUSE = 500; // ms
public static final int DEFAULT_VALUE_FLASH_COUNT = 10; // ms
public static final int DEFAULT_VALUE_FLASH_DURATION = 500; // ms
public static final int DEFAULT_VALUE_FLASH_PAUSE = 500; // ms
public static final int DEFAULT_VALUE_FLASH_COLOUR = 1; // TODO: colour!
public static final int DEFAULT_VALUE_FLASH_ORIGINAL_COLOUR = 1; // TODO: colour!
}

View File

@ -8,6 +8,7 @@ import android.support.v4.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.ControlCenter;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.*;
public class MiBandPreferencesActivity extends AbstractSettingsActivity {
@Override
@ -16,7 +17,7 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity {
addPreferencesFromResource(R.xml.miband_preferences);
final Preference developmentMiaddr = findPreference(MiBandConst.PREF_MIBAND_ADDRESS);
final Preference developmentMiaddr = findPreference(PREF_MIBAND_ADDRESS);
developmentMiaddr.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
@ -33,16 +34,16 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity {
@Override
protected String[] getPreferenceKeysWithSummary() {
return new String[]{
MiBandConst.PREF_USER_ALIAS,
MiBandConst.PREF_USER_YEAR_OF_BIRTH,
MiBandConst.PREF_USER_GENDER,
MiBandConst.PREF_USER_HEIGHT_CM,
MiBandConst.PREF_USER_WEIGHT_KG,
MiBandConst.PREF_MIBAND_ADDRESS,
MiBandConst.PREF_VIBRATION_COUNT_SMS,
MiBandConst.PREF_VIBRATION_COUNT_K9MAIL,
MiBandConst.PREF_VIBRATION_COUNT_PEBBLEMSG,
MiBandConst.PREF_VIBRATION_COUNT_GENERIC,
PREF_USER_ALIAS,
PREF_USER_YEAR_OF_BIRTH,
PREF_USER_GENDER,
PREF_USER_HEIGHT_CM,
PREF_USER_WEIGHT_KG,
PREF_MIBAND_ADDRESS,
getNotificationPrefKey(VIBRATION_COUNT, ORIGIN_SMS),
getNotificationPrefKey(VIBRATION_COUNT, ORIGIN_K9MAIL),
getNotificationPrefKey(VIBRATION_COUNT, ORIGIN_PEBBLEMSG),
getNotificationPrefKey(VIBRATION_COUNT, ORIGIN_GENERIC),
};
}
}

View File

@ -2,6 +2,8 @@ package nodomain.freeyourgadget.gadgetbridge.miband;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import java.io.IOException;
import java.util.Arrays;
@ -15,6 +17,8 @@ import nodomain.freeyourgadget.gadgetbridge.GBDevice.State;
import nodomain.freeyourgadget.gadgetbridge.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.btle.TransactionBuilder;
import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.*;
public class MiBandSupport extends AbstractBTLEDeviceSupport {
private static final Logger LOG = LoggerFactory.getLogger(MiBandSupport.class);
@ -60,6 +64,26 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
builder.write(characteristic, getDefaultNotification()).queue(getQueue());
}
private void sendCustomNotification(int vibrateDuration, int vibrateTimes, int pause, int flashTimes, int flashColour, int originalColour, long flashDuration, TransactionBuilder builder) {
BluetoothGattCharacteristic controlPoint = getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT);
int vDuration = Math.min(500, vibrateDuration); // longer than 500ms is not possible
for (int i = 0; i < vibrateTimes; i++) {
builder.write(controlPoint, startVibrate);
builder.wait(vDuration);
builder.write(controlPoint, stopVibrate);
if (pause > 0) {
builder.wait(pause);
}
}
LOG.info("Sending notification to MiBand: " + controlPoint);
builder.queue(getQueue());
}
private static final byte[] startVibrate = new byte[]{ 8, 1 };
private static final byte[] stopVibrate = new byte[]{ 19 };
private static final byte[] reboot = new byte[]{ 12 };
private byte[] getNotification(long vibrateDuration, int vibrateTimes, int flashTimes, int flashColour, int originalColour, long flashDuration) {
byte[] vibrate = new byte[]{(byte) 8, (byte) 1};
byte r = 6;
@ -116,19 +140,76 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
}
}
// private void performCustomNotification(String task, int vibrateDuration, int vibrateTimes, int pause, int flashTimes, int flashColour, int originalColour, long flashDuration) {
// try {
// TransactionBuilder builder = performInitialized(task);
// sendCustomNotification(vibrateDuration, vibrateTimes, pause, flashTimes, flashColour, originalColour, flashDuration, builder);
// } catch (IOException ex) {
// LOG.error("Unable to send notification to MI device", ex);
// }
// }
private void performPreferredNotification(String task, String notificationOrigin) {
try {
TransactionBuilder builder = performInitialized(task);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
int vibrateDuration = getPreferredVibrateDuration(notificationOrigin, prefs);
int vibrateTimes = getPreferredVibrateCount(notificationOrigin, prefs);
int vibratePause = getPreferredVibratePause(notificationOrigin, prefs);
int flashTimes = getPreferredFlashCount(notificationOrigin, prefs);
int flashColour = getPreferredFlashColour(notificationOrigin, prefs);
int originalColour = getPreferredOriginalColour(notificationOrigin, prefs);
int flashDuration = getPreferredFlashDuration(notificationOrigin, prefs);
sendCustomNotification(vibrateDuration, vibrateTimes, vibratePause, flashTimes, flashColour, originalColour, flashDuration, builder);
} catch (IOException ex) {
LOG.error("Unable to send notification to MI device", ex);
}
}
private int getPreferredFlashDuration(String notificationOrigin, SharedPreferences prefs) {
return getNotificationPrefIntValue(FLASH_DURATION, notificationOrigin, prefs, DEFAULT_VALUE_FLASH_DURATION);
}
private int getPreferredOriginalColour(String notificationOrigin, SharedPreferences prefs) {
return getNotificationPrefIntValue(FLASH_ORIGINAL_COLOUR, notificationOrigin, prefs, DEFAULT_VALUE_FLASH_ORIGINAL_COLOUR);
}
private int getPreferredFlashColour(String notificationOrigin, SharedPreferences prefs) {
return getNotificationPrefIntValue(FLASH_COLOUR, notificationOrigin, prefs, DEFAULT_VALUE_FLASH_COLOUR);
}
private int getPreferredFlashCount(String notificationOrigin, SharedPreferences prefs) {
return getNotificationPrefIntValue(FLASH_COUNT, notificationOrigin, prefs, DEFAULT_VALUE_FLASH_COUNT);
}
private int getPreferredVibratePause(String notificationOrigin, SharedPreferences prefs) {
return getNotificationPrefIntValue(VIBRATION_PAUSE, notificationOrigin, prefs, DEFAULT_VALUE_VIBRATION_PAUSE);
}
private int getPreferredVibrateCount(String notificationOrigin, SharedPreferences prefs) {
return getNotificationPrefIntValue(VIBRATION_COUNT, notificationOrigin, prefs, DEFAULT_VALUE_VIBRATION_COUNT);
}
private int getPreferredVibrateDuration(String notificationOrigin, SharedPreferences prefs) {
return getNotificationPrefIntValue(VIBRATION_DURATION, notificationOrigin, prefs, DEFAULT_VALUE_VIBRATION_DURATION);
}
@Override
public void onSMS(String from, String body) {
performDefaultNotification("sms received");
// performCustomNotification("sms received", 500, 3, 2000, 0, 0, 0, 0);
performPreferredNotification("sms received", ORIGIN_SMS);
}
@Override
public void onEmail(String from, String subject, String body) {
performDefaultNotification("email received");
performPreferredNotification("email received", ORIGIN_K9MAIL);
}
@Override
public void onGenericNotification(String title, String details) {
performDefaultNotification("generic notification received");
performPreferredNotification("generic notification received", ORIGIN_GENERIC);
}
@Override
@ -206,6 +287,17 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
}
}
@Override
public void onReboot() {
try {
TransactionBuilder builder = performInitialized("Reboot");
builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), reboot);
builder.queue(getQueue());
} catch (IOException ex) {
LOG.error("Unable to reboot MI", ex);
}
}
@Override
public void onAppInfoReq() {
// not supported