mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-28 04:46:51 +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_PHONE_CALL = 2;
|
||||
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 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_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;
|
||||
|
||||
@ -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_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_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;
|
||||
|
||||
@ -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_TEXT_NOTIFICATION = new byte[] {0x05, 0x01};
|
||||
public static final byte COMMAND_ALERT_CATEGORY_CHAT = (byte) 0xfa;
|
||||
|
||||
static {
|
||||
MIBAND_DEBUG = new HashMap<>();
|
||||
|
@ -36,7 +36,8 @@ public enum AlertCategory {
|
||||
InstantMessage(9),
|
||||
// 10-250 reserved for future use
|
||||
// 251-255 defined by service specification
|
||||
Any(255);
|
||||
Any(255),
|
||||
Custom(-1);
|
||||
|
||||
private final int id;
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class AlertNotificationProfile<T extends AbstractBTLEDeviceSupport> exten
|
||||
public void newAlert(TransactionBuilder builder, NewAlert alert, OverflowStrategy strategy) {
|
||||
BluetoothGattCharacteristic characteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_NEW_ALERT);
|
||||
if (characteristic != null) {
|
||||
String message = alert.getMessage();
|
||||
String message = StringUtils.ensureNotNull(alert.getMessage());
|
||||
if (message.length() > MAX_MSG_LENGTH && strategy == OverflowStrategy.TRUNCATE) {
|
||||
message = StringUtils.truncate(message, MAX_MSG_LENGTH);
|
||||
}
|
||||
@ -66,42 +66,42 @@ public class AlertNotificationProfile<T extends AbstractBTLEDeviceSupport> exten
|
||||
numChunks++;
|
||||
}
|
||||
|
||||
boolean hasAlerted = false;
|
||||
for (int i = 0; i < numChunks; i++) {
|
||||
int offset = i * MAX_MSG_LENGTH;
|
||||
int restLength = message.length() - offset;
|
||||
message = message.substring(offset, offset + Math.min(MAX_MSG_LENGTH, restLength));
|
||||
if (hasAlerted && message.length() == 0) {
|
||||
// no need to do it again when there is no text content
|
||||
break;
|
||||
try {
|
||||
boolean hasAlerted = false;
|
||||
for (int i = 0; i < numChunks; i++) {
|
||||
int offset = i * MAX_MSG_LENGTH;
|
||||
int restLength = message.length() - offset;
|
||||
message = message.substring(offset, offset + Math.min(MAX_MSG_LENGTH, restLength));
|
||||
if (hasAlerted && message.length() == 0) {
|
||||
// no need to do it again when there is no text content
|
||||
break;
|
||||
}
|
||||
builder.write(characteristic, getAlertMessage(alert, message, 1));
|
||||
hasAlerted = true;
|
||||
}
|
||||
writeAlertMessage(builder, characteristic, alert, message, i);
|
||||
hasAlerted = true;
|
||||
}
|
||||
if (!hasAlerted) {
|
||||
writeAlertMessage(builder, characteristic, alert, "", 1);
|
||||
if (!hasAlerted) {
|
||||
builder.write(characteristic, getAlertMessage(alert, "", 1));
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
// ain't gonna happen
|
||||
LOG.error("Error writing alert message to ByteArrayOutputStream");
|
||||
}
|
||||
} else {
|
||||
LOG.warn("NEW_ALERT characteristic not available");
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeAlertMessage(TransactionBuilder builder, BluetoothGattCharacteristic characteristic, NewAlert alert, String message, int chunk) {
|
||||
try {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream(100);
|
||||
stream.write(BLETypeConversions.fromUint8(alert.getCategory().getId()));
|
||||
stream.write(BLETypeConversions.fromUint8(alert.getNumAlerts()));
|
||||
protected byte[] getAlertMessage(NewAlert alert, String message, int chunk) throws IOException {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream(100);
|
||||
stream.write(BLETypeConversions.fromUint8(alert.getCategory().getId()));
|
||||
stream.write(BLETypeConversions.fromUint8(alert.getNumAlerts()));
|
||||
|
||||
if (message.length() > 0) {
|
||||
stream.write(BLETypeConversions.toUtf8s(message));
|
||||
} else {
|
||||
// some write a null byte instead of leaving out this optional value
|
||||
if (message.length() > 0) {
|
||||
stream.write(BLETypeConversions.toUtf8s(message));
|
||||
} else {
|
||||
// some write a null byte instead of leaving out this optional value
|
||||
// stream.write(new byte[] {0});
|
||||
}
|
||||
builder.write(characteristic, stream.toByteArray());
|
||||
} catch (IOException ex) {
|
||||
// ain't gonna happen
|
||||
LOG.error("Error writing alert message to ByteArrayOutputStream");
|
||||
}
|
||||
return stream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
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.WeatherSpec;
|
||||
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.GattCharacteristic;
|
||||
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 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);
|
||||
LOG.info("Sending notification to MiBand");
|
||||
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 {
|
||||
TransactionBuilder builder = performInitialized(task);
|
||||
Prefs prefs = GBApplication.getPrefs();
|
||||
@ -572,11 +572,8 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
||||
return;
|
||||
}
|
||||
|
||||
String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext()).trim();
|
||||
SimpleNotification simpleNotification = new SimpleNotification(message, BLETypeConversions.toAlertCategory(notificationSpec.type));
|
||||
|
||||
String origin = notificationSpec.type.getGenericType();
|
||||
performPreferredNotification(origin + " received", simpleNotification, origin, null);
|
||||
performPreferredNotification(origin + " received", null, origin, null);
|
||||
}
|
||||
|
||||
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) {
|
||||
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/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
@ -27,7 +29,7 @@ public interface NotificationStrategy {
|
||||
/**
|
||||
* Adds a custom notification to the given transaction builder
|
||||
* @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 flashColour
|
||||
* @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 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) {
|
||||
// BluetoothGattCharacteristic controlPoint = getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT);
|
||||
// int vDuration = Math.min(500, vibrateDuration); // longer than 500ms is not possible
|
||||
|
@ -17,25 +17,23 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.miband;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
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.GattCharacteristic;
|
||||
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;
|
||||
|
||||
public class V2NotificationStrategy implements NotificationStrategy {
|
||||
private final AbstractBTLEDeviceSupport support;
|
||||
public class V2NotificationStrategy<T extends AbstractBTLEDeviceSupport> implements NotificationStrategy {
|
||||
private final T support;
|
||||
|
||||
public V2NotificationStrategy(AbstractBTLEDeviceSupport support) {
|
||||
public V2NotificationStrategy(T support) {
|
||||
this.support = support;
|
||||
}
|
||||
|
||||
protected AbstractBTLEDeviceSupport getSupport() {
|
||||
protected T getSupport() {
|
||||
return support;
|
||||
}
|
||||
|
||||
@ -45,7 +43,7 @@ public class V2NotificationStrategy implements NotificationStrategy {
|
||||
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
|
||||
BluetoothGattCharacteristic alert = support.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL);
|
||||
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
|
||||
@ -83,4 +74,10 @@ public class V2NotificationStrategy implements NotificationStrategy {
|
||||
// all other parameters are unfortunately not supported anymore ;-(
|
||||
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;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
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.GattCharacteristic;
|
||||
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.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);
|
||||
alertLevelCharacteristic = support.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
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++) {
|
||||
int[] onOffSequence = vibrationProfile.getOnOffSequence();
|
||||
for (int j = 0; j < onOffSequence.length; j++) {
|
||||
int on = onOffSequence[j];
|
||||
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.write(alert, new byte[]{GattCharacteristic.NO_ALERT});
|
||||
stopNotify(builder);
|
||||
|
||||
if (++j < onOffSequence.length) {
|
||||
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
|
||||
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 ;-(
|
||||
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.SetDeviceStateAction;
|
||||
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.heartrate.HeartRateProfile;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
||||
@ -301,7 +304,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
||||
}
|
||||
|
||||
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};
|
||||
@ -440,6 +444,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
||||
int flashDuration = getPreferredFlashDuration(notificationOrigin, prefs);
|
||||
|
||||
sendCustomNotification(profile, simpleNotification, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder);
|
||||
|
||||
// sendCustomNotification(vibrateDuration, vibrateTimes, vibratePause, flashTimes, flashColour, originalColour, flashDuration, builder);
|
||||
builder.queue(getQueue());
|
||||
} 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);
|
||||
} else if ((callSpec.command == CallSpec.CALL_START) || (callSpec.command == CallSpec.CALL_END)) {
|
||||
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;
|
||||
}
|
||||
};
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -1044,11 +1060,12 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
||||
@Override
|
||||
public void onTestNewFunction() {
|
||||
try {
|
||||
performInitialized("read characteristic 10")
|
||||
.read(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_10_BUTTON))
|
||||
.queue(getQueue());
|
||||
TransactionBuilder builder = performInitialized("incoming call from peter");
|
||||
NewAlert alert = new NewAlert(AlertCategory.Custom, 1, new String(new byte[] {0x19}));
|
||||
AlertNotificationProfile<MiBand2Support> profile = new AlertNotificationProfile<>(this);
|
||||
profile.newAlert(builder, alert, OverflowStrategy.MAKE_MULTIPLE);
|
||||
builder.queue(getQueue());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,4 +81,15 @@ public class StringUtils {
|
||||
}
|
||||
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