mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-05 09:47:01 +01:00
parent
8fc6dfeca7
commit
17ecee0cab
@ -53,6 +53,7 @@ public class MiBand2Service {
|
|||||||
public static final int ALERT_LEVEL_MESSAGE = 1;
|
public static final int ALERT_LEVEL_MESSAGE = 1;
|
||||||
public static final int ALERT_LEVEL_PHONE_CALL = 2;
|
public static final int ALERT_LEVEL_PHONE_CALL = 2;
|
||||||
public static final int ALERT_LEVEL_VIBRATE_ONLY = 3;
|
public static final int ALERT_LEVEL_VIBRATE_ONLY = 3;
|
||||||
|
public static final int ALERT_LEVEL_CUSTOM = 0xfa; // followed by another uin8 to select the actual icon
|
||||||
|
|
||||||
// set metric distance
|
// set metric distance
|
||||||
// set 12 hour time mode
|
// set 12 hour time mode
|
||||||
@ -109,6 +110,41 @@ public class MiBand2Service {
|
|||||||
public static final byte[] COMMAND_SET_FITNESS_GOAL_START = new byte[] { 0x10, 0x0, 0x0 };
|
public static final byte[] COMMAND_SET_FITNESS_GOAL_START = new byte[] { 0x10, 0x0, 0x0 };
|
||||||
public static final byte[] COMMAND_SET_FITNESS_GOAL_END = new byte[] { 0, 0 };
|
public static final byte[] COMMAND_SET_FITNESS_GOAL_END = new byte[] { 0, 0 };
|
||||||
|
|
||||||
|
public static final byte ICON_CHAT = 0x00;
|
||||||
|
public static final byte ICON_PENGUIN = 0x01;
|
||||||
|
public static final byte ICON_CHAT_MI = 0x02;
|
||||||
|
public static final byte ICON_FB = 0x03;
|
||||||
|
public static final byte ICON_TWITTER = 0x04;
|
||||||
|
public static final byte ICON_MIBAND = 0x05;
|
||||||
|
public static final byte ICON_SNAPCHAT = 0x06;
|
||||||
|
public static final byte ICON_WHATSAPP = 0x07;
|
||||||
|
public static final byte ICON_MANTA = 0x08;
|
||||||
|
public static final byte ICON_XX0 = 0x09;
|
||||||
|
public static final byte ICON_ALARM = 0x10;
|
||||||
|
public static final byte ICON_SHATTERED_GLASS = 0x11;
|
||||||
|
public static final byte ICON_INSTAGRAM = 0x12;
|
||||||
|
public static final byte ICON_CHAT_GHOST = 0x13;
|
||||||
|
public static final byte ICON_COW = 0x14;
|
||||||
|
public static final byte ICON_XX2 = 0x15;
|
||||||
|
public static final byte ICON_XX3 = 0x16;
|
||||||
|
public static final byte ICON_XX4 = 0x17;
|
||||||
|
public static final byte ICON_XX5 = 0x18;
|
||||||
|
public static final byte ICON_XX6 = 0x19;
|
||||||
|
public static final byte ICON_EGALE = 0x1a;
|
||||||
|
public static final byte ICON_CALENDAR = 0x1b;
|
||||||
|
public static final byte ICON_XX7 = 0x1c;
|
||||||
|
public static final byte ICON_PHONE_CALL = 0x1d;
|
||||||
|
public static final byte ICON_CHAT_LINE = 0x1e;
|
||||||
|
public static final byte ICON_TELEGRAM = 0x1f;
|
||||||
|
public static final byte ICON_CHAT_TALK = 0x20;
|
||||||
|
public static final byte ICON_SKYPE = 0x21;
|
||||||
|
public static final byte ICON_VK = 0x22;
|
||||||
|
public static final byte ICON_CIRCLES = 0x23;
|
||||||
|
public static final byte ICON_HANGOUTS = 0x24;
|
||||||
|
public static final byte ICON_MI = 0x25;
|
||||||
|
|
||||||
|
public static final byte ICON_HIGH_PRIORITY = 0x7;
|
||||||
|
|
||||||
|
|
||||||
public static byte ENDPOINT_DISPLAY = 0x06;
|
public static byte ENDPOINT_DISPLAY = 0x06;
|
||||||
|
|
||||||
@ -119,7 +155,7 @@ public class MiBand2Service {
|
|||||||
public static final byte[] COMMAND_ENABLE_DISPLAY_ON_LIFT_WRIST = new byte[]{ENDPOINT_DISPLAY, 0x05, 0x00, 0x01};
|
public static final byte[] COMMAND_ENABLE_DISPLAY_ON_LIFT_WRIST = new byte[]{ENDPOINT_DISPLAY, 0x05, 0x00, 0x01};
|
||||||
public static final byte[] COMMAND_DISABLE_DISPLAY_ON_LIFT_WRIST = new byte[]{ENDPOINT_DISPLAY, 0x05, 0x00, 0x00};
|
public static final byte[] COMMAND_DISABLE_DISPLAY_ON_LIFT_WRIST = new byte[]{ENDPOINT_DISPLAY, 0x05, 0x00, 0x00};
|
||||||
public static final byte[] DISPLAY_XXX = new byte[] {ENDPOINT_DISPLAY, 0x03, 0x0, 0x0 };
|
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, 0x0 };
|
public static final byte[] DISPLAY_YYY = new byte[] {ENDPOINT_DISPLAY, 0x10, 0x0, 0x1, 0x1 };
|
||||||
|
|
||||||
public static final byte RESPONSE = 0x10;
|
public static final byte RESPONSE = 0x10;
|
||||||
|
|
||||||
@ -148,7 +184,6 @@ public class MiBand2Service {
|
|||||||
public static final byte[] COMMAND_DISABLE_HR_SLEEP_MEASUREMENT = new byte[]{0x15, 0x00, 0x00};
|
public static final byte[] COMMAND_DISABLE_HR_SLEEP_MEASUREMENT = new byte[]{0x15, 0x00, 0x00};
|
||||||
|
|
||||||
public static final byte[] COMMAND_TEXT_NOTIFICATION = new byte[] {0x05, 0x01};
|
public static final byte[] COMMAND_TEXT_NOTIFICATION = new byte[] {0x05, 0x01};
|
||||||
public static final byte COMMAND_ALERT_CATEGORY_CHAT = (byte) 0xfa;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
MIBAND_DEBUG = new HashMap<>();
|
MIBAND_DEBUG = new HashMap<>();
|
||||||
|
@ -36,7 +36,8 @@ public enum AlertCategory {
|
|||||||
InstantMessage(9),
|
InstantMessage(9),
|
||||||
// 10-250 reserved for future use
|
// 10-250 reserved for future use
|
||||||
// 251-255 defined by service specification
|
// 251-255 defined by service specification
|
||||||
Any(255);
|
Any(255),
|
||||||
|
Custom(-1);
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ public class AlertNotificationProfile<T extends AbstractBTLEDeviceSupport> exten
|
|||||||
public void newAlert(TransactionBuilder builder, NewAlert alert, OverflowStrategy strategy) {
|
public void newAlert(TransactionBuilder builder, NewAlert alert, OverflowStrategy strategy) {
|
||||||
BluetoothGattCharacteristic characteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_NEW_ALERT);
|
BluetoothGattCharacteristic characteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_NEW_ALERT);
|
||||||
if (characteristic != null) {
|
if (characteristic != null) {
|
||||||
String message = alert.getMessage();
|
String message = StringUtils.ensureNotNull(alert.getMessage());
|
||||||
if (message.length() > MAX_MSG_LENGTH && strategy == OverflowStrategy.TRUNCATE) {
|
if (message.length() > MAX_MSG_LENGTH && strategy == OverflowStrategy.TRUNCATE) {
|
||||||
message = StringUtils.truncate(message, MAX_MSG_LENGTH);
|
message = StringUtils.truncate(message, MAX_MSG_LENGTH);
|
||||||
}
|
}
|
||||||
@ -66,6 +66,7 @@ public class AlertNotificationProfile<T extends AbstractBTLEDeviceSupport> exten
|
|||||||
numChunks++;
|
numChunks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
boolean hasAlerted = false;
|
boolean hasAlerted = false;
|
||||||
for (int i = 0; i < numChunks; i++) {
|
for (int i = 0; i < numChunks; i++) {
|
||||||
int offset = i * MAX_MSG_LENGTH;
|
int offset = i * MAX_MSG_LENGTH;
|
||||||
@ -75,19 +76,22 @@ public class AlertNotificationProfile<T extends AbstractBTLEDeviceSupport> exten
|
|||||||
// no need to do it again when there is no text content
|
// no need to do it again when there is no text content
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
writeAlertMessage(builder, characteristic, alert, message, i);
|
builder.write(characteristic, getAlertMessage(alert, message, 1));
|
||||||
hasAlerted = true;
|
hasAlerted = true;
|
||||||
}
|
}
|
||||||
if (!hasAlerted) {
|
if (!hasAlerted) {
|
||||||
writeAlertMessage(builder, characteristic, alert, "", 1);
|
builder.write(characteristic, getAlertMessage(alert, "", 1));
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
// ain't gonna happen
|
||||||
|
LOG.error("Error writing alert message to ByteArrayOutputStream");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG.warn("NEW_ALERT characteristic not available");
|
LOG.warn("NEW_ALERT characteristic not available");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeAlertMessage(TransactionBuilder builder, BluetoothGattCharacteristic characteristic, NewAlert alert, String message, int chunk) {
|
protected byte[] getAlertMessage(NewAlert alert, String message, int chunk) throws IOException {
|
||||||
try {
|
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream(100);
|
ByteArrayOutputStream stream = new ByteArrayOutputStream(100);
|
||||||
stream.write(BLETypeConversions.fromUint8(alert.getCategory().getId()));
|
stream.write(BLETypeConversions.fromUint8(alert.getCategory().getId()));
|
||||||
stream.write(BLETypeConversions.fromUint8(alert.getNumAlerts()));
|
stream.write(BLETypeConversions.fromUint8(alert.getNumAlerts()));
|
||||||
@ -98,10 +102,6 @@ public class AlertNotificationProfile<T extends AbstractBTLEDeviceSupport> exten
|
|||||||
// some write a null byte instead of leaving out this optional value
|
// some write a null byte instead of leaving out this optional value
|
||||||
// stream.write(new byte[] {0});
|
// stream.write(new byte[] {0});
|
||||||
}
|
}
|
||||||
builder.write(characteristic, stream.toByteArray());
|
return stream.toByteArray();
|
||||||
} catch (IOException ex) {
|
|
||||||
// ain't gonna happen
|
|
||||||
LOG.error("Error writing alert message to ByteArrayOutputStream");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import android.bluetooth.BluetoothGatt;
|
|||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@ -72,7 +73,6 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
|
||||||
@ -248,7 +248,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
* @param extraAction an extra action to be executed after every vibration and flash sequence. Allows to abort the repetition, for example.
|
* @param extraAction an extra action to be executed after every vibration and flash sequence. Allows to abort the repetition, for example.
|
||||||
* @param builder
|
* @param builder
|
||||||
*/
|
*/
|
||||||
private MiBandSupport sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) {
|
private MiBandSupport sendCustomNotification(VibrationProfile vibrationProfile, @Nullable SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) {
|
||||||
getNotificationStrategy().sendCustomNotification(vibrationProfile, simpleNotification, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder);
|
getNotificationStrategy().sendCustomNotification(vibrationProfile, simpleNotification, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder);
|
||||||
LOG.info("Sending notification to MiBand");
|
LOG.info("Sending notification to MiBand");
|
||||||
return this;
|
return this;
|
||||||
@ -487,7 +487,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performPreferredNotification(String task, SimpleNotification simpleNotification, String notificationOrigin, BtLEAction extraAction) {
|
private void performPreferredNotification(String task, @Nullable SimpleNotification simpleNotification, String notificationOrigin, BtLEAction extraAction) {
|
||||||
try {
|
try {
|
||||||
TransactionBuilder builder = performInitialized(task);
|
TransactionBuilder builder = performInitialized(task);
|
||||||
Prefs prefs = GBApplication.getPrefs();
|
Prefs prefs = GBApplication.getPrefs();
|
||||||
@ -572,11 +572,8 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext()).trim();
|
|
||||||
SimpleNotification simpleNotification = new SimpleNotification(message, BLETypeConversions.toAlertCategory(notificationSpec.type));
|
|
||||||
|
|
||||||
String origin = notificationSpec.type.getGenericType();
|
String origin = notificationSpec.type.getGenericType();
|
||||||
performPreferredNotification(origin + " received", simpleNotification, origin, null);
|
performPreferredNotification(origin + " received", null, origin, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAlarmClock(NotificationSpec notificationSpec) {
|
private void onAlarmClock(NotificationSpec notificationSpec) {
|
||||||
|
@ -39,4 +39,9 @@ public class NoNotificationStrategy implements NotificationStrategy {
|
|||||||
public void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) {
|
public void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) {
|
||||||
LOG.info("dummy notification stragegy: custom notification: " + simpleNotification);
|
LOG.info("dummy notification stragegy: custom notification: " + simpleNotification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopCurrentNotification(TransactionBuilder builder) {
|
||||||
|
LOG.info("dummy notification stragegy: stop notification");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
@ -27,7 +29,7 @@ public interface NotificationStrategy {
|
|||||||
/**
|
/**
|
||||||
* Adds a custom notification to the given transaction builder
|
* Adds a custom notification to the given transaction builder
|
||||||
* @param vibrationProfile specifies how and how often the Band shall vibrate.
|
* @param vibrationProfile specifies how and how often the Band shall vibrate.
|
||||||
* @param simpleNotification
|
* @param simpleNotification an optional notification containing a type and text message
|
||||||
* @param flashTimes
|
* @param flashTimes
|
||||||
* @param flashColour
|
* @param flashColour
|
||||||
* @param originalColour
|
* @param originalColour
|
||||||
@ -35,5 +37,11 @@ public interface NotificationStrategy {
|
|||||||
* @param extraAction an extra action to be executed after every vibration and flash sequence. Allows to abort the repetition, for example.
|
* @param extraAction an extra action to be executed after every vibration and flash sequence. Allows to abort the repetition, for example.
|
||||||
* @param builder
|
* @param builder
|
||||||
*/
|
*/
|
||||||
void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder);
|
void sendCustomNotification(VibrationProfile vibrationProfile, @Nullable SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops any current notification.
|
||||||
|
* @param builder
|
||||||
|
*/
|
||||||
|
void stopCurrentNotification(TransactionBuilder builder);
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,12 @@ public class V1NotificationStrategy implements NotificationStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopCurrentNotification(TransactionBuilder builder) {
|
||||||
|
BluetoothGattCharacteristic controlPoint = support.getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT);
|
||||||
|
builder.write(controlPoint, stopVibrate);
|
||||||
|
}
|
||||||
|
|
||||||
// private void sendCustomNotification(int vibrateDuration, int vibrateTimes, int pause, int flashTimes, int flashColour, int originalColour, long flashDuration, TransactionBuilder builder) {
|
// 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);
|
// BluetoothGattCharacteristic controlPoint = getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT);
|
||||||
// int vDuration = Math.min(500, vibrateDuration); // longer than 500ms is not possible
|
// int vDuration = Math.min(500, vibrateDuration); // longer than 500ms is not possible
|
||||||
|
@ -17,25 +17,23 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband;
|
||||||
|
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.OverflowStrategy;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
||||||
|
|
||||||
public class V2NotificationStrategy implements NotificationStrategy {
|
public class V2NotificationStrategy<T extends AbstractBTLEDeviceSupport> implements NotificationStrategy {
|
||||||
private final AbstractBTLEDeviceSupport support;
|
private final T support;
|
||||||
|
|
||||||
public V2NotificationStrategy(AbstractBTLEDeviceSupport support) {
|
public V2NotificationStrategy(T support) {
|
||||||
this.support = support;
|
this.support = support;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractBTLEDeviceSupport getSupport() {
|
protected T getSupport() {
|
||||||
return support;
|
return support;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +43,7 @@ public class V2NotificationStrategy implements NotificationStrategy {
|
|||||||
sendCustomNotification(profile, simpleNotification, extraAction, builder);
|
sendCustomNotification(profile, simpleNotification, extraAction, builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, BtLEAction extraAction, TransactionBuilder builder) {
|
protected void sendCustomNotification(VibrationProfile vibrationProfile, @Nullable SimpleNotification simpleNotification, BtLEAction extraAction, TransactionBuilder builder) {
|
||||||
//use the new alert characteristic
|
//use the new alert characteristic
|
||||||
BluetoothGattCharacteristic alert = support.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL);
|
BluetoothGattCharacteristic alert = support.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL);
|
||||||
for (short i = 0; i < vibrationProfile.getRepeat(); i++) {
|
for (short i = 0; i < vibrationProfile.getRepeat(); i++) {
|
||||||
@ -69,13 +67,6 @@ public class V2NotificationStrategy implements NotificationStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// sendAlert(simpleNotification, builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void sendAlert(SimpleNotification simpleNotification, TransactionBuilder builder) {
|
|
||||||
AlertNotificationProfile<?> profile = new AlertNotificationProfile<>(getSupport());
|
|
||||||
NewAlert alert = new NewAlert(simpleNotification.getAlertCategory(), 1, simpleNotification.getMessage());
|
|
||||||
profile.newAlert(builder, alert, OverflowStrategy.MAKE_MULTIPLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -83,4 +74,10 @@ public class V2NotificationStrategy implements NotificationStrategy {
|
|||||||
// all other parameters are unfortunately not supported anymore ;-(
|
// all other parameters are unfortunately not supported anymore ;-(
|
||||||
sendCustomNotification(vibrationProfile, simpleNotification, extraAction, builder);
|
sendCustomNotification(vibrationProfile, simpleNotification, extraAction, builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopCurrentNotification(TransactionBuilder builder) {
|
||||||
|
BluetoothGattCharacteristic alert = support.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL);
|
||||||
|
builder.write(alert, new byte[]{GattCharacteristic.NO_ALERT});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,34 +17,34 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband2;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband2;
|
||||||
|
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.V2NotificationStrategy;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.V2NotificationStrategy;
|
||||||
|
|
||||||
public class Mi2NotificationStrategy extends V2NotificationStrategy {
|
public class Mi2NotificationStrategy extends V2NotificationStrategy<MiBand2Support> {
|
||||||
|
|
||||||
public Mi2NotificationStrategy(AbstractBTLEDeviceSupport support) {
|
private final BluetoothGattCharacteristic alertLevelCharacteristic;
|
||||||
|
|
||||||
|
public Mi2NotificationStrategy(MiBand2Support support) {
|
||||||
super(support);
|
super(support);
|
||||||
|
alertLevelCharacteristic = support.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, BtLEAction extraAction, TransactionBuilder builder) {
|
protected void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, BtLEAction extraAction, TransactionBuilder builder) {
|
||||||
//use the new alert characteristic
|
|
||||||
BluetoothGattCharacteristic alert = getSupport().getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL);
|
|
||||||
for (short i = 0; i < vibrationProfile.getRepeat(); i++) {
|
for (short i = 0; i < vibrationProfile.getRepeat(); i++) {
|
||||||
int[] onOffSequence = vibrationProfile.getOnOffSequence();
|
int[] onOffSequence = vibrationProfile.getOnOffSequence();
|
||||||
for (int j = 0; j < onOffSequence.length; j++) {
|
for (int j = 0; j < onOffSequence.length; j++) {
|
||||||
int on = onOffSequence[j];
|
int on = onOffSequence[j];
|
||||||
on = Math.min(500, on); // longer than 500ms is not possible
|
on = Math.min(500, on); // longer than 500ms is not possible
|
||||||
builder.write(alert, new byte[]{(byte) vibrationProfile.getAlertLevel()});
|
startNotify(builder, vibrationProfile.getAlertLevel(), simpleNotification);
|
||||||
builder.wait(on);
|
builder.wait(on);
|
||||||
builder.write(alert, new byte[]{GattCharacteristic.NO_ALERT});
|
stopNotify(builder);
|
||||||
|
|
||||||
if (++j < onOffSequence.length) {
|
if (++j < onOffSequence.length) {
|
||||||
int off = Math.max(onOffSequence[j], 25); // wait at least 25ms
|
int off = Math.max(onOffSequence[j], 25); // wait at least 25ms
|
||||||
@ -56,12 +56,19 @@ public class Mi2NotificationStrategy extends V2NotificationStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sendAlert(simpleNotification, builder);
|
protected void startNotify(TransactionBuilder builder, int alertLevel, @Nullable SimpleNotification simpleNotification) {
|
||||||
|
builder.write(alertLevelCharacteristic, new byte[] {(byte) alertLevel});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stopNotify(TransactionBuilder builder) {
|
||||||
|
builder.write(alertLevelCharacteristic, new byte[]{GattCharacteristic.NO_ALERT});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) {
|
public void sendCustomNotification(VibrationProfile vibrationProfile, @Nullable SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) {
|
||||||
// all other parameters are unfortunately not supported anymore ;-(
|
// all other parameters are unfortunately not supported anymore ;-(
|
||||||
sendCustomNotification(vibrationProfile, simpleNotification, extraAction, builder);
|
sendCustomNotification(vibrationProfile, simpleNotification, extraAction, builder);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,74 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband2;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.OverflowStrategy;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||||
|
|
||||||
|
public class Mi2TextNotificationStrategy extends Mi2NotificationStrategy {
|
||||||
|
private final BluetoothGattCharacteristic newAlertCharacteristic;
|
||||||
|
|
||||||
|
public Mi2TextNotificationStrategy(MiBand2Support support) {
|
||||||
|
super(support);
|
||||||
|
newAlertCharacteristic = support.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_NEW_ALERT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, BtLEAction extraAction, TransactionBuilder builder) {
|
||||||
|
if (simpleNotification != null && simpleNotification.getAlertCategory() == AlertCategory.IncomingCall) {
|
||||||
|
// incoming calls are notified solely via NewAlert including caller ID
|
||||||
|
sendAlert(simpleNotification, builder);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// announce text messages with configured alerts first
|
||||||
|
super.sendCustomNotification(vibrationProfile, simpleNotification, extraAction, builder);
|
||||||
|
// and finally send the text message, if any
|
||||||
|
if (simpleNotification != null && !StringUtils.isEmpty(simpleNotification.getMessage())) {
|
||||||
|
sendAlert(simpleNotification, builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startNotify(TransactionBuilder builder, int alertLevel, SimpleNotification simpleNotification) {
|
||||||
|
builder.write(newAlertCharacteristic, getNotifyMessage(simpleNotification));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected byte[] getNotifyMessage(SimpleNotification simpleNotification) {
|
||||||
|
int numAlerts = 1;
|
||||||
|
if (simpleNotification != null) {
|
||||||
|
switch (simpleNotification.getAlertCategory()) {
|
||||||
|
case Email:
|
||||||
|
return new byte[] { BLETypeConversions.fromUint8(MiBand2Service.ALERT_LEVEL_MESSAGE), BLETypeConversions.fromUint8(numAlerts)};
|
||||||
|
case InstantMessage:
|
||||||
|
return new byte[] { BLETypeConversions.fromUint8(MiBand2Service.ALERT_LEVEL_CUSTOM), BLETypeConversions.fromUint8(numAlerts), MiBand2Service.ICON_CHAT};
|
||||||
|
case News:
|
||||||
|
return new byte[] { BLETypeConversions.fromUint8(MiBand2Service.ALERT_LEVEL_CUSTOM), BLETypeConversions.fromUint8(numAlerts), MiBand2Service.ICON_PENGUIN};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new byte[] { BLETypeConversions.fromUint8(AlertCategory.SMS.getId()), BLETypeConversions.fromUint8(numAlerts)};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sendAlert(@NonNull SimpleNotification simpleNotification, TransactionBuilder builder) {
|
||||||
|
AlertNotificationProfile<?> profile = new AlertNotificationProfile<>(getSupport());
|
||||||
|
// override the alert category, since only SMS and incoming call support text notification
|
||||||
|
AlertCategory category = AlertCategory.SMS;
|
||||||
|
if (simpleNotification.getAlertCategory() == AlertCategory.IncomingCall) {
|
||||||
|
category = simpleNotification.getAlertCategory();
|
||||||
|
}
|
||||||
|
NewAlert alert = new NewAlert(category, 1, simpleNotification.getMessage());
|
||||||
|
profile.newAlert(builder, alert, OverflowStrategy.MAKE_MULTIPLE);
|
||||||
|
}
|
||||||
|
}
|
@ -84,6 +84,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactionAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactionAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.OverflowStrategy;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.HeartRateProfile;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.HeartRateProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
||||||
@ -301,7 +304,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private NotificationStrategy getNotificationStrategy() {
|
private NotificationStrategy getNotificationStrategy() {
|
||||||
return new Mi2NotificationStrategy(this);
|
// return new Mi2NotificationStrategy(this);
|
||||||
|
return new Mi2TextNotificationStrategy(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final byte[] startHeartMeasurementManual = new byte[]{0x15, MiBandService.COMMAND_SET_HR_MANUAL, 1};
|
private static final byte[] startHeartMeasurementManual = new byte[]{0x15, MiBandService.COMMAND_SET_HR_MANUAL, 1};
|
||||||
@ -440,6 +444,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
int flashDuration = getPreferredFlashDuration(notificationOrigin, prefs);
|
int flashDuration = getPreferredFlashDuration(notificationOrigin, prefs);
|
||||||
|
|
||||||
sendCustomNotification(profile, simpleNotification, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder);
|
sendCustomNotification(profile, simpleNotification, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder);
|
||||||
|
|
||||||
// sendCustomNotification(vibrateDuration, vibrateTimes, vibratePause, flashTimes, flashColour, originalColour, flashDuration, builder);
|
// sendCustomNotification(vibrateDuration, vibrateTimes, vibratePause, flashTimes, flashColour, originalColour, flashDuration, builder);
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
@ -563,6 +568,17 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
performPreferredNotification("incoming call", MiBandConst.ORIGIN_INCOMING_CALL, simpleNotification, MiBand2Service.ALERT_LEVEL_PHONE_CALL, abortAction);
|
performPreferredNotification("incoming call", MiBandConst.ORIGIN_INCOMING_CALL, simpleNotification, MiBand2Service.ALERT_LEVEL_PHONE_CALL, abortAction);
|
||||||
} else if ((callSpec.command == CallSpec.CALL_START) || (callSpec.command == CallSpec.CALL_END)) {
|
} else if ((callSpec.command == CallSpec.CALL_START) || (callSpec.command == CallSpec.CALL_END)) {
|
||||||
telephoneRinging = false;
|
telephoneRinging = false;
|
||||||
|
stopCurrentNotification();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopCurrentNotification() {
|
||||||
|
try {
|
||||||
|
TransactionBuilder builder = performInitialized("stop notification");
|
||||||
|
getNotificationStrategy().stopCurrentNotification(builder);
|
||||||
|
builder.queue(getQueue());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Error stopping notification");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,7 +658,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
return !isLocatingDevice;
|
return !isLocatingDevice;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
SimpleNotification simpleNotification = new SimpleNotification(getContext().getString(R.string.find_device_you_found_it), AlertCategory.HighPriorityAlert.HighPriorityAlert);
|
SimpleNotification simpleNotification = new SimpleNotification(getContext().getString(R.string.find_device_you_found_it), AlertCategory.HighPriorityAlert);
|
||||||
performDefaultNotification("locating device", simpleNotification, (short) 255, abortAction);
|
performDefaultNotification("locating device", simpleNotification, (short) 255, abortAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1044,11 +1060,12 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
@Override
|
@Override
|
||||||
public void onTestNewFunction() {
|
public void onTestNewFunction() {
|
||||||
try {
|
try {
|
||||||
performInitialized("read characteristic 10")
|
TransactionBuilder builder = performInitialized("incoming call from peter");
|
||||||
.read(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_10_BUTTON))
|
NewAlert alert = new NewAlert(AlertCategory.Custom, 1, new String(new byte[] {0x19}));
|
||||||
.queue(getQueue());
|
AlertNotificationProfile<MiBand2Support> profile = new AlertNotificationProfile<>(this);
|
||||||
|
profile.newAlert(builder, alert, OverflowStrategy.MAKE_MULTIPLE);
|
||||||
|
builder.queue(getQueue());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,4 +81,15 @@ public class StringUtils {
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isEmpty(String string) {
|
||||||
|
return string != null && string.length() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String ensureNotNull(String message) {
|
||||||
|
if (message != null) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user