diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java index c5a983f7d..37cd778e5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java @@ -75,6 +75,10 @@ public class DebugActivity extends GBActivity { } } }; + private Button sendChatButton; + private Button sendTelegramButton; + private Button sendTwitterButton; + private Button sendFacebookButton; @Override protected void onCreate(Bundle savedInstanceState) { @@ -114,6 +118,58 @@ public class DebugActivity extends GBActivity { GBApplication.deviceService().onNotification(notificationSpec); } }); + sendChatButton = (Button) findViewById(R.id.sendChatButton); + sendChatButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + NotificationSpec notificationSpec = new NotificationSpec(); + notificationSpec.sender = getResources().getText(R.string.app_name).toString(); + notificationSpec.subject = editContent.getText().toString(); + notificationSpec.body = editContent.getText().toString(); + notificationSpec.type = NotificationType.CHAT; + notificationSpec.id = -1; + GBApplication.deviceService().onNotification(notificationSpec); + } + }); + sendTelegramButton = (Button) findViewById(R.id.sendTelegramButton); + sendTelegramButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + NotificationSpec notificationSpec = new NotificationSpec(); + notificationSpec.sender = getResources().getText(R.string.app_name).toString(); + notificationSpec.subject = editContent.getText().toString(); + notificationSpec.body = editContent.getText().toString(); + notificationSpec.type = NotificationType.TELEGRAM; + notificationSpec.id = -1; + GBApplication.deviceService().onNotification(notificationSpec); + } + }); + sendTwitterButton = (Button) findViewById(R.id.sendTwitterButton); + sendTwitterButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + NotificationSpec notificationSpec = new NotificationSpec(); + notificationSpec.sender = getResources().getText(R.string.app_name).toString(); + notificationSpec.subject = editContent.getText().toString(); + notificationSpec.body = editContent.getText().toString(); + notificationSpec.type = NotificationType.TWITTER; + notificationSpec.id = -1; + GBApplication.deviceService().onNotification(notificationSpec); + } + }); + sendFacebookButton = (Button) findViewById(R.id.sendFacebookButton); + sendFacebookButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + NotificationSpec notificationSpec = new NotificationSpec(); + notificationSpec.sender = getResources().getText(R.string.app_name).toString(); + notificationSpec.subject = editContent.getText().toString(); + notificationSpec.body = editContent.getText().toString(); + notificationSpec.type = NotificationType.FACEBOOK; + notificationSpec.id = -1; + GBApplication.deviceService().onNotification(notificationSpec); + } + }); incomingCallButton = (Button) findViewById(R.id.incomingCallButton); incomingCallButton.setOnClickListener(new View.OnClickListener() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java index 0ab8b8977..0051e3d4d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java @@ -26,6 +26,11 @@ public class MiBand2Service { public static final UUID UUID_CHARACTERISTIC_AUTH = UUID.fromString("00000009-0000-3512-2118-0009af100700"); public static final UUID UUID_UNKNOWN_CHARACTERISTIC10 = UUID.fromString("00000010-0000-3512-2118-0009af100700"); + public static final int ALERT_LEVEL_NONE = 0; + 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; + // set metric distance // set 12 hour time mode diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java index 97dfc4e63..8ea54c8a3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/VibrationProfile.java @@ -4,6 +4,7 @@ import android.content.Context; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertLevel; public class VibrationProfile { public static final Context CONTEXT = GBApplication.getContext(); @@ -42,6 +43,7 @@ public class VibrationProfile { private final int[] onOffSequence; private final short repeat; + private int alertLevel = AlertLevel.MildAlert.getId(); /** * Creates a new profile instance. @@ -67,4 +69,12 @@ public class VibrationProfile { public short getRepeat() { return repeat; } + + public void setAlertLevel(int alertLevel) { + this.alertLevel = alertLevel; + } + + public int getAlertLevel() { + return alertLevel; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java index 67cdaefa2..1caf0dc7f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java @@ -54,7 +54,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactio import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ConditionalWriteAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WriteAction; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertLevel; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.Mi2NotificationStrategy; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.operations.InitOperation; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -291,7 +293,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } private NotificationStrategy getNotificationStrategy() { - return new V2NotificationStrategy(this); + return new Mi2NotificationStrategy(this); } static final byte[] reboot = new byte[]{MiBandService.COMMAND_REBOOT}; @@ -475,7 +477,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } } - private void performPreferredNotification(String task, String notificationOrigin, BtLEAction extraAction) { + private void performPreferredNotification(String task, String notificationOrigin, int alertLevel, BtLEAction extraAction) { try { TransactionBuilder builder = performInitialized(task); Prefs prefs = GBApplication.getPrefs(); @@ -483,6 +485,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { int vibratePause = getPreferredVibratePause(notificationOrigin, prefs); short vibrateTimes = getPreferredVibrateCount(notificationOrigin, prefs); VibrationProfile profile = getPreferredVibrateProfile(notificationOrigin, prefs, vibrateTimes); + profile.setAlertLevel(alertLevel); int flashTimes = getPreferredFlashCount(notificationOrigin, prefs); int flashColour = getPreferredFlashColour(notificationOrigin, prefs); @@ -553,20 +556,47 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { @Override public void onNotification(NotificationSpec notificationSpec) { - // FIXME: these ORIGIN contants do not really make sense anymore + String task; + String origin; + int alertLevel; switch (notificationSpec.type) { case SMS: - performPreferredNotification("sms received", ORIGIN_SMS, null); + task = "sms received"; + origin = ORIGIN_SMS; + alertLevel = MiBand2Service.ALERT_LEVEL_MESSAGE; break; case EMAIL: - performPreferredNotification("email received", ORIGIN_K9MAIL, null); + task = "email received"; + origin = ORIGIN_K9MAIL; + alertLevel = MiBand2Service.ALERT_LEVEL_MESSAGE; + break; + case FACEBOOK: + task = "facebook message received"; + origin = ORIGIN_GENERIC; + alertLevel = MiBand2Service.ALERT_LEVEL_MESSAGE; + break; + case TWITTER: + task = "twitter message received"; + origin = ORIGIN_GENERIC; + alertLevel = MiBand2Service.ALERT_LEVEL_MESSAGE; + break; + case TELEGRAM: + task = "telegram message received"; + origin = ORIGIN_GENERIC; + alertLevel = MiBand2Service.ALERT_LEVEL_MESSAGE; break; case CHAT: - performPreferredNotification("chat message received", ORIGIN_PEBBLEMSG, null); + task = "chat message received"; + origin = ORIGIN_PEBBLEMSG; + alertLevel = MiBand2Service.ALERT_LEVEL_MESSAGE; break; + case UNDEFINED: default: - performPreferredNotification("generic notification received", ORIGIN_GENERIC, null); + task = "generic notification received"; + origin = ORIGIN_GENERIC; + alertLevel = MiBand2Service.ALERT_LEVEL_VIBRATE_ONLY; } + performPreferredNotification(task, origin, alertLevel, null); } @Override @@ -624,8 +654,20 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { protected boolean shouldAbort() { return !isTelephoneRinging(); } + + @Override + public boolean run(BluetoothGatt gatt) { + if (!super.run(gatt)) { + // send a signal to stop the vibration + BluetoothGattCharacteristic characteristic = MiBand2Support.this.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL); + characteristic.setValue(new byte[] {MiBand2Service.ALERT_LEVEL_NONE}); + gatt.writeCharacteristic(characteristic); + return false; + } + return true; + } }; - performPreferredNotification("incoming call", MiBandConst.ORIGIN_INCOMING_CALL, abortAction); + performPreferredNotification("incoming call", MiBandConst.ORIGIN_INCOMING_CALL, MiBand2Service.ALERT_LEVEL_PHONE_CALL, abortAction); } else if ((callSpec.command == CallSpec.CALL_START) || (callSpec.command == CallSpec.CALL_END)) { telephoneRinging = false; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java index c97303608..d3f91e533 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java @@ -15,13 +15,17 @@ public class V2NotificationStrategy implements NotificationStrategy { this.support = support; } + protected AbstractBTLEDeviceSupport getSupport() { + return support; + } + @Override public void sendDefaultNotification(TransactionBuilder builder, BtLEAction extraAction) { VibrationProfile profile = VibrationProfile.getProfile(VibrationProfile.ID_MEDIUM, (short) 3); sendCustomNotification(profile, extraAction, builder); } - private void sendCustomNotification(VibrationProfile vibrationProfile, BtLEAction extraAction, TransactionBuilder builder) { + protected void sendCustomNotification(VibrationProfile vibrationProfile, 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++) { @@ -31,6 +35,14 @@ public class V2NotificationStrategy implements NotificationStrategy { on = Math.min(500, on); // longer than 500ms is not possible builder.write(alert, new byte[]{GattCharacteristic.MILD_ALERT}); //MILD_ALERT lights up GREEN leds, HIGH_ALERT lights up RED leds builder.wait(on); + builder.write(alert, new byte[]{GattCharacteristic.HIGH_ALERT}); + builder.wait(on); + builder.write(alert, new byte[]{0x3}); + builder.wait(on); + builder.write(alert, new byte[]{0x4}); + builder.wait(on); + builder.write(alert, new byte[]{0x5}); + builder.wait(on); builder.write(alert, new byte[]{GattCharacteristic.NO_ALERT}); if (++j < onOffSequence.length) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2NotificationStrategy.java new file mode 100644 index 000000000..42fdad152 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2NotificationStrategy.java @@ -0,0 +1,49 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.miband2; + +import android.bluetooth.BluetoothGattCharacteristic; + +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.devices.miband.NotificationStrategy; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.V2NotificationStrategy; + +public class Mi2NotificationStrategy extends V2NotificationStrategy { + + public Mi2NotificationStrategy(AbstractBTLEDeviceSupport support) { + super(support); + } + + @Override + protected void sendCustomNotification(VibrationProfile vibrationProfile, 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()}); +// builder.wait(on); +// builder.write(alert, new byte[]{GattCharacteristic.NO_ALERT}); + + if (++j < onOffSequence.length) { + int off = Math.max(onOffSequence[j], 25); // wait at least 25ms + builder.wait(off); + } + + if (extraAction != null) { + builder.add(extraAction); + } + } + } + } + + @Override + public void sendCustomNotification(VibrationProfile vibrationProfile, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { + // all other parameters are unfortunately not supported anymore ;-( + sendCustomNotification(vibrationProfile, extraAction, builder); + } +} diff --git a/app/src/main/res/layout/activity_debug.xml b/app/src/main/res/layout/activity_debug.xml index 3a88c2afe..efff97f23 100644 --- a/app/src/main/res/layout/activity_debug.xml +++ b/app/src/main/res/layout/activity_debug.xml @@ -42,7 +42,7 @@ android:layout_column="0" android:layout_gravity="fill_horizontal" android:layout_row="2" - android:text="send as SMS" /> + android:text="SMS" />