From 2c1923dd962f4d8441d41b2f2c004ef95c6414db Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sat, 11 Mar 2017 23:37:19 +0100 Subject: [PATCH 01/18] change icon for "find lost device" action, add small padding to app manager icon --- .../res/drawable/ic_action_find_lost_device.xml | 13 +++++++------ app/src/main/res/layout/device_itemv2.xml | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/drawable/ic_action_find_lost_device.xml b/app/src/main/res/drawable/ic_action_find_lost_device.xml index 74f549430..84be5602b 100644 --- a/app/src/main/res/drawable/ic_action_find_lost_device.xml +++ b/app/src/main/res/drawable/ic_action_find_lost_device.xml @@ -1,9 +1,10 @@ + + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + android:fillColor="#000" + android:pathData="M3,17V7H5V17H3M19,17V7H21V17H19M22,9H24V15H22V9M0,15V9H2V15H0M17.96,11.97C17.96,13.87 17.07,15.57 15.68,16.67L14.97,20.95H9L8.27,16.67C6.88,15.57 6,13.87 6,11.97C6,10.07 6.88,8.37 8.27,7.28L9,3H14.97L15.68,7.28C17.07,8.37 17.96,10.07 17.96,11.97M7.5,11.97C7.5,14.45 9.5,16.46 11.97,16.46A4.5,4.5 0 0,0 16.46,11.97C16.46,9.5 14.45,7.5 11.97,7.5A4.47,4.47 0 0,0 7.5,11.97Z" /> diff --git a/app/src/main/res/layout/device_itemv2.xml b/app/src/main/res/layout/device_itemv2.xml index b2911ac86..72a428d5e 100644 --- a/app/src/main/res/layout/device_itemv2.xml +++ b/app/src/main/res/layout/device_itemv2.xml @@ -195,6 +195,7 @@ android:layout_height="48dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" + android:padding="2dp" android:background="?android:attr/selectableItemBackground" android:clickable="true" android:contentDescription="@string/title_activity_appmanager" From 5008f08272261e0fc62d9dd1c08e89370120ac4b Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sun, 12 Mar 2017 09:06:58 +0100 Subject: [PATCH 02/18] Revert "Use constraintlayout for the cardview and few improvements." This partially reverts commit ecd2c166c2aec4e5ec63e2af26aed4ca783c280e because the ConstraintLayout dependency it creates problems in travis and in f-droid build system. #thanksgoogle #wecanthavenicethings :( --- app/build.gradle | 1 - app/src/main/res/layout/device_itemv2.xml | 159 ++++++++++------------ 2 files changed, 73 insertions(+), 87 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 40c95594f..90de6d715 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -80,7 +80,6 @@ dependencies { compile 'org.apache.commons:commons-lang3:3.4' // compile project(":DaoCore") - compile 'com.android.support.constraint:constraint-layout:1.0.2' } preBuild.dependsOn(":GBDaoGenerator:genSources") diff --git a/app/src/main/res/layout/device_itemv2.xml b/app/src/main/res/layout/device_itemv2.xml index 72a428d5e..a8979189d 100644 --- a/app/src/main/res/layout/device_itemv2.xml +++ b/app/src/main/res/layout/device_itemv2.xml @@ -15,20 +15,19 @@ card_view:cardElevation="4dp" card_view:contentPadding="8dp"> - + android:visibility="gone"> + android:layout_marginTop="8dp" /> + tools:text="My Pebble Watch" /> + android:background="?android:attr/selectableItemBackground" + card_view:srcCompat="@drawable/ic_more_vert" /> + android:orientation="vertical"> + android:orientation="vertical"> + card_view:srcCompat="@drawable/ic_activity_graphs" + android:background="?android:attr/selectableItemBackground" + android:contentDescription="@string/controlcenter_start_activitymonitor" /> - + From a6bba1b094d604ac4c67d132c70bf5e7bd7c83ca Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 13 Mar 2017 22:27:59 +0100 Subject: [PATCH 03/18] In CCv2 allow to disconnect with long press in any state expect "not connected" --- .../freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index c92d63348..af7e4dfb4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -79,7 +79,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter Date: Sat, 11 Mar 2017 22:15:44 +0100 Subject: [PATCH 04/18] Some utility methods + tests --- .../gadgetbridge/util/NotificationUtils.java | 22 ++++++-- .../gadgetbridge/util/StringUtils.java | 30 +++++++--- .../gadgetbridge/test/StringUtilsTest.java | 56 +++++++++++++++++++ 3 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/StringUtilsTest.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java index 2623866b2..7e7b8df02 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java @@ -19,6 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.util; import android.content.Context; import android.support.annotation.NonNull; +import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; @@ -47,13 +48,22 @@ public class NotificationUtils { } @NonNull - public static String formatText(String sender, String subject, String body, int lengthBody, int lengthSubject, Context context) { - StringBuilder builder = new StringBuilder(); - builder.append(StringUtils.truncate(body, lengthBody)); - builder.append(StringUtils.truncate(subject, lengthSubject)); - builder.append(StringUtils.formatSender(sender, context)); + public static String formatSender(String sender, Context context) { + if (sender == null || sender.length() == 0) { + return ""; + } + return context.getString(R.string.StringUtils_sender, sender); + } - return builder.toString(); + + @NonNull + public static String formatText(String sender, String subject, String body, int lengthBody, int lengthSubject, Context context) { + String fBody = StringUtils.truncate(body, lengthBody); + String fSubject = StringUtils.truncate(subject, lengthSubject); + String fSender = formatSender(sender, context); + + StringBuilder builder = StringUtils.join(" ", fBody, fSubject, fSender); + return builder.toString().trim(); } public static String getPreferredTextFor(CallSpec callSpec) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java index 1ebe8ee3c..8dcc07a01 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java @@ -16,11 +16,8 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.util; -import android.content.Context; import android.support.annotation.NonNull; -import nodomain.freeyourgadget.gadgetbridge.R; - public class StringUtils { public static String truncate(String s, int maxLength){ @@ -47,12 +44,31 @@ public class StringUtils { return s; } + /** + * Joins the given elements and adds a separator between each element in the resulting string. + * There will be no separator at the start or end of the string. There will be no consecutive + * separators (even in case an element is null or empty). + * @param separator the separator string + * @param elements the elements to concatenate to a new string + * @return the joined strings, separated by the separator + */ @NonNull - public static String formatSender(String sender, Context context) { - if (sender == null || sender.length() == 0) { - return ""; + public static StringBuilder join(String separator, String... elements) { + StringBuilder builder = new StringBuilder(); + if (elements == null) { + return builder; } - return context.getString(R.string.StringUtils_sender, sender); + boolean hasAdded = false; + for (String element : elements) { + if (element != null && element.length() > 0) { + if (hasAdded) { + builder.append(separator); + } + builder.append(element); + hasAdded = true; + } + } + return builder; } @NonNull diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/StringUtilsTest.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/StringUtilsTest.java new file mode 100644 index 000000000..b8cb73600 --- /dev/null +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/StringUtilsTest.java @@ -0,0 +1,56 @@ +package nodomain.freeyourgadget.gadgetbridge.test; + +import org.junit.Test; + +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; + +import static org.junit.Assert.assertEquals; + +public class StringUtilsTest extends TestBase { + private static final String SEP = ":"; + private static final String E1 = "e1"; + private static final String E2 = "e2"; + private static final String E3 = "e3"; + + @Test + public void testJoinNull() { + StringBuilder result = StringUtils.join(SEP, (String[]) null); + assertEquals("", result.toString()); + } + + @Test + public void testJoinNullElement() { + StringBuilder result = StringUtils.join(SEP, (String) null); + assertEquals("", result.toString()); + } + + @Test + public void testJoinSingleElement() { + StringBuilder result = StringUtils.join(SEP, E1); + assertEquals(E1, result.toString()); + } + + @Test + public void testJoinSingleAndNullElement() { + StringBuilder result = StringUtils.join(SEP, E1, null); + assertEquals(E1, result.toString()); + } + + @Test + public void testJoinTwoElements() { + StringBuilder result = StringUtils.join(SEP, E1, E2); + assertEquals(E1 + SEP + E2, result.toString()); + } + + @Test + public void testJoinTwoElementsAndNull() { + StringBuilder result = StringUtils.join(SEP, E1, null, E2); + assertEquals(E1 + SEP + E2, result.toString()); + } + + @Test + public void testJoinThreeElements() { + StringBuilder result = StringUtils.join(SEP, E1, E2, E3); + assertEquals(E1 + SEP + E2 + SEP + E3, result.toString()); + } +} From 8fc6dfeca73f77465f135a0fce39f1016270b79d Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sat, 11 Mar 2017 22:19:10 +0100 Subject: [PATCH 05/18] Improved AlertNotificationProfile AlertLevel, AlertCategory, Control Point --- .../alertnotification/AlertCategory.java | 4 +-- .../AlertNotificationControl.java | 30 ++++++++++++++++ .../AlertNotificationProfile.java | 35 ++++++++++++++++--- .../profiles/alertnotification/Command.java | 24 +++++++++++++ 4 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java index cb5ed147c..a87418688 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java @@ -33,9 +33,10 @@ public enum AlertCategory { VoiceMail(6), Schedule(7), HighPriorityAlert(8), - InstantMessage(9); + InstantMessage(9), // 10-250 reserved for future use // 251-255 defined by service specification + Any(255); private final int id; @@ -91,5 +92,4 @@ public enum AlertCategory { return null; } - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java index c470905c2..ebb111ae1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationControl.java @@ -16,9 +16,39 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification; +import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; + /** * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.alert_notification_control_point.xml */ public class AlertNotificationControl { + private AlertCategory category; + private Command command; + public void setCategory(AlertCategory category) { + this.category = category; + } + + public void setCommand(Command command) { + this.command = command; + } + + public AlertCategory getCategory() { + return category; + } + + public Command getCommand() { + return command; + } + + /** + * Returns the formatted message to be written to the alert notification control point + * characteristic + */ + public byte[] getControlMessage() { + return new byte[] { + BLETypeConversions.fromUint8(command.getId()), + BLETypeConversions.fromUint8(category.getId()) + }; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java index 751f3d47f..37f3ddc00 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java @@ -39,6 +39,20 @@ public class AlertNotificationProfile exten super(support); } + public void configure(TransactionBuilder builder, AlertNotificationControl control) { + BluetoothGattCharacteristic characteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_NOTIFICATION_CONTROL_POINT); + if (characteristic != null) { + builder.write(characteristic, control.getControlMessage()); + } + } + + public void updateAlertLevel(TransactionBuilder builder, AlertLevel level) { + BluetoothGattCharacteristic characteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL); + if (characteristic != null) { + builder.write(characteristic, new byte[] {BLETypeConversions.fromUint8(level.getId())}); + } + } + public void newAlert(TransactionBuilder builder, NewAlert alert, OverflowStrategy strategy) { BluetoothGattCharacteristic characteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_NEW_ALERT); if (characteristic != null) { @@ -52,14 +66,20 @@ public class AlertNotificationProfile 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 (message.length() == 0) { + if (hasAlerted && message.length() == 0) { + // no need to do it again when there is no text content break; } writeAlertMessage(builder, characteristic, alert, message, i); + hasAlerted = true; + } + if (!hasAlerted) { + writeAlertMessage(builder, characteristic, alert, "", 1); } } else { LOG.warn("NEW_ALERT characteristic not available"); @@ -69,13 +89,18 @@ public class AlertNotificationProfile exten protected void writeAlertMessage(TransactionBuilder builder, BluetoothGattCharacteristic characteristic, NewAlert alert, String message, int chunk) { try { ByteArrayOutputStream stream = new ByteArrayOutputStream(100); - stream.write(alert.getCategory().getId()); - stream.write(alert.getNumAlerts()); - stream.write(BLETypeConversions.toUtf8s(message)); + 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 +// stream.write(new byte[] {0}); + } builder.write(characteristic, stream.toByteArray()); } catch (IOException ex) { - // aint gonna happen + // ain't gonna happen LOG.error("Error writing alert message to ByteArrayOutputStream"); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java new file mode 100644 index 000000000..263f06695 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java @@ -0,0 +1,24 @@ +package nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification; + +/** + * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.alert_notification_control_point.xml + */ +public enum Command { + EnableNewIncomingAlertNotification(0), + EnableUnreadCategoryStatusNotification(1), + DisableNewIncomingAlertNotification(2), + DisbleUnreadCategoryStatusNotification(3), + NotifyNewIncomingAlertImmediately(4), + NotifyUnreadCategoryStatusImmediately(5),; + // 6-255 reserved for future use + + private final int id; + + Command(int id) { + this.id = id; + } + + public int getId() { + return id; + } +} From 17ecee0cab5b0a0d6f544922bd9cdf2e0a128d4c Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Tue, 14 Mar 2017 00:44:59 +0100 Subject: [PATCH 06/18] Mi2: initial support for text notifications and icons See #560 --- .../devices/miband/MiBand2Service.java | 39 +++++++++- .../alertnotification/AlertCategory.java | 3 +- .../AlertNotificationProfile.java | 56 +++++++------- .../service/devices/miband/MiBandSupport.java | 11 +-- .../miband/NoNotificationStrategy.java | 5 ++ .../devices/miband/NotificationStrategy.java | 12 ++- .../miband/V1NotificationStrategy.java | 6 ++ .../miband/V2NotificationStrategy.java | 27 +++---- .../miband2/Mi2NotificationStrategy.java | 27 ++++--- .../miband2/Mi2TextNotificationStrategy.java | 74 +++++++++++++++++++ .../devices/miband2/MiBand2Support.java | 29 ++++++-- .../gadgetbridge/util/StringUtils.java | 11 +++ 12 files changed, 229 insertions(+), 71 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java 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 a7adf687e..84d1d781e 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 @@ -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<>(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java index a87418688..3c7e6ae4d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertCategory.java @@ -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; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java index 37f3ddc00..48b115524 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java @@ -56,7 +56,7 @@ public class AlertNotificationProfile 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 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(); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java index fcb5e0092..2df2fee52 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java @@ -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) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java index 0aa68d250..32054d357 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java @@ -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"); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java index 2d23b50f1..896b349cd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java @@ -16,6 +16,8 @@ along with this program. If not, see . */ 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); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java index 3b58940c8..30a4e1866 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java @@ -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 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 ff72eb213..865b30d2e 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 @@ -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 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}); + } } 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 index 497bc2f93..4ec7471f1 100644 --- 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 @@ -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 { - 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); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java new file mode 100644 index 000000000..13f03ffb5 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java @@ -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); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java index 8b8a04ce3..85e272561 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java @@ -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 profile = new AlertNotificationProfile<>(this); + profile.newAlert(builder, alert, OverflowStrategy.MAKE_MULTIPLE); + builder.queue(getQueue()); } catch (IOException e) { - e.printStackTrace(); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java index 8dcc07a01..0a9eaae20 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java @@ -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 ""; + } } From 6989ca9db3322faa8aa1a8da0eeee9853b4130f0 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 14 Mar 2017 21:37:16 +0100 Subject: [PATCH 07/18] Add privacy mode that hides the phone number (#588) --- .../gadgetbridge/impl/GBDeviceService.java | 18 ++++++++----- .../service/devices/hplus/HPlusSupport.java | 26 ++++++++++--------- app/src/main/res/values/arrays.xml | 2 ++ app/src/main/res/values/strings.xml | 2 ++ 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index ea2537e29..36ec75c20 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -73,9 +73,9 @@ public class GBDeviceService implements DeviceService { } protected void invokeService(Intent intent) { - if(LanguageUtils.transliterate()){ - for (String extra: transliterationExtras) { - if (intent.hasExtra(extra)){ + if (LanguageUtils.transliterate()) { + for (String extra : transliterationExtras) { + if (intent.hasExtra(extra)) { intent.putExtra(extra, LanguageUtils.transliterate(intent.getStringExtra(extra))); } } @@ -172,12 +172,15 @@ public class GBDeviceService implements DeviceService { String currentPrivacyMode = GBApplication.getPrefs().getString("pref_call_privacy_mode", GBApplication.getContext().getString(R.string.p_call_privacy_mode_off)); if (context.getString(R.string.p_call_privacy_mode_name).equals(currentPrivacyMode)) { callSpec.name = callSpec.number; - } - else if (context.getString(R.string.p_call_privacy_mode_complete).equals(currentPrivacyMode)) { + } else if (context.getString(R.string.p_call_privacy_mode_complete).equals(currentPrivacyMode)) { callSpec.number = null; callSpec.name = null; - } - else { + } else if (context.getString(R.string.pref_call_privacy_mode_number).equals(currentPrivacyMode)) { + callSpec.name = coalesce(callSpec.name, getContactDisplayNameByNumber(callSpec.number)); + if (!callSpec.name.equals(callSpec.number)) { + callSpec.number = null; + } + } else { callSpec.name = coalesce(callSpec.name, getContactDisplayNameByNumber(callSpec.number)); } @@ -372,6 +375,7 @@ public class GBDeviceService implements DeviceService { /** * Returns contact DisplayName by call number + * * @param number contact number * @return contact DisplayName, if found it */ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index 2ed1dbf6d..18791908d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -669,18 +669,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { byte[] msg = new byte[13]; - //Show call number - for (int i = 0; i < msg.length; i++) - msg[i] = ' '; - - for (int i = 0; i < number.length() && i < (msg.length - 1); i++) - msg[i + 1] = (byte) number.charAt(i); - - msg[0] = HPlusConstants.CMD_SET_INCOMING_CALL_NUMBER; - - builder.write(ctrlCharacteristic, msg); - builder.wait(200); - msg = msg.clone(); //Show call name @@ -697,6 +685,20 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { msg[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT_NAME_CN; builder.write(ctrlCharacteristic, msg); + builder.wait(200); + msg = msg.clone(); + + //Show call number + for (int i = 0; i < msg.length; i++) + msg[i] = ' '; + + for (int i = 0; i < number.length() && i < (msg.length - 1); i++) + msg[i + 1] = (byte) number.charAt(i); + + msg[0] = HPlusConstants.CMD_SET_INCOMING_CALL_NUMBER; + + builder.write(ctrlCharacteristic, msg); + builder.queue(getQueue()); } catch (IOException e) { GB.toast(getContext(), "Error showing incoming call: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 88685f63d..0bac667b8 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -158,12 +158,14 @@ @string/pref_call_privacy_mode_off @string/pref_call_privacy_mode_name + @string/pref_call_privacy_mode_number @string/pref_call_privacy_mode_complete @string/p_call_privacy_mode_off @string/p_call_privacy_mode_name + @string/pref_call_privacy_mode_number @string/p_call_privacy_mode_complete diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 145262648..61453fbe5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -99,8 +99,10 @@ Call Privacy Mode Display name and number Hide name but display number + Hide number but display name Hide name and number + Blacklist Apps Canned Messages From e62a860ee633a0514e497c6f81ebf2aa979760c3 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Tue, 14 Mar 2017 22:03:30 +0100 Subject: [PATCH 08/18] Avoid potential NPE when neither name nor number are available --- .../freeyourgadget/gadgetbridge/impl/GBDeviceService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index 36ec75c20..f48e9d94e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -177,7 +177,7 @@ public class GBDeviceService implements DeviceService { callSpec.name = null; } else if (context.getString(R.string.pref_call_privacy_mode_number).equals(currentPrivacyMode)) { callSpec.name = coalesce(callSpec.name, getContactDisplayNameByNumber(callSpec.number)); - if (!callSpec.name.equals(callSpec.number)) { + if (callSpec.name != null && !callSpec.name.equals(callSpec.number)) { callSpec.number = null; } } else { From 2d60beea1f15d151f2c21f21175306c9399fd64a Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Tue, 14 Mar 2017 22:40:17 +0100 Subject: [PATCH 09/18] Mi2: added some more tested firmware/font versions --- .../service/devices/miband2/Mi2FirmwareInfo.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java index 516b52217..189db116b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java @@ -55,7 +55,15 @@ public class Mi2FirmwareInfo { private static Map crcToVersion = new HashMap<>(); static { + // firmware crcToVersion.put(41899, "1.0.0.39"); + crcToVersion.put(49197, "1.0.0.53"); + crcToVersion.put(51770, "1.0.1.34"); + crcToVersion.put(3929, "1.0.1.39"); + + // fonts + crcToVersion.put(45624, "Font"); + crcToVersion.put(6377, "Font (En)"); } private FirmwareType firmwareType = FirmwareType.FIRMWARE; From 5d96df3508687acf4119d105fcf124201aed84de Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Tue, 14 Mar 2017 23:45:30 +0100 Subject: [PATCH 10/18] Mi2: add hint about intermediate firmware 1.0.0.53 --- .../activities/FwAppInstallerActivity.java | 5 ++ .../activities/InstallActivity.java | 3 ++ .../AbstractMiBandFWInstallHandler.java | 8 +++ .../miband2/MiBand2FWInstallHandler.java | 53 +++++++++++++++++++ .../gadgetbridge/util/CheckSums.java | 34 ++++++++++++ .../gadgetbridge/util/Version.java | 48 +++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 7 files changed, 152 insertions(+) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java index 0ebabb11a..1abd25a34 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java @@ -224,6 +224,11 @@ public class FwAppInstallerActivity extends GBActivity implements InstallActivit fwAppInstallTextView.setText(text); } + @Override + public CharSequence getInfoText() { + return fwAppInstallTextView.getText(); + } + @Override public void setInstallEnabled(boolean enable) { boolean enabled = device != null && device.isConnected() && enable; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java index b00c1dfdb..4af5405e6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java @@ -19,6 +19,8 @@ package nodomain.freeyourgadget.gadgetbridge.activities; import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails; public interface InstallActivity { + CharSequence getInfoText(); + void setInfoText(String text); void setInstallEnabled(boolean enable); @@ -26,4 +28,5 @@ public interface InstallActivity { void clearInstallItems(); void setInstallItem(ItemWithDetails item); + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java index ba009e33a..d52b698b1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java @@ -48,6 +48,14 @@ public abstract class AbstractMiBandFWInstallHandler implements InstallHandler { } } + public Context getContext() { + return mContext; + } + + public AbstractMiBandFWHelper getHelper() { + return helper; + } + protected abstract AbstractMiBandFWHelper createHelper(Uri uri, Context context) throws IOException; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java index af1336aad..8ea09a151 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java @@ -24,10 +24,14 @@ import org.slf4j.LoggerFactory; import java.io.IOException; +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity; import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.FirmwareType; +import nodomain.freeyourgadget.gadgetbridge.util.Version; public class MiBand2FWInstallHandler extends AbstractMiBandFWInstallHandler { private static final Logger LOG = LoggerFactory.getLogger(MiBand2FWInstallHandler.class); @@ -36,6 +40,55 @@ public class MiBand2FWInstallHandler extends AbstractMiBandFWInstallHandler { super(uri, context); } + @Override + public void validateInstallation(InstallActivity installActivity, GBDevice device) { + super.validateInstallation(installActivity, device); + maybeAddFw53Hint(installActivity, device); + } + + private void maybeAddFw53Hint(InstallActivity installActivity, GBDevice device) { + FirmwareType type = getFirmwareType(); + if (type != FirmwareType.FIRMWARE) { + return; + } + + Version deviceVersion = getFirmwareVersionOf(device); + if (deviceVersion != null) { + Version v53 = new Version("1.0.0.53"); + if (deviceVersion.compareTo(v53) < 0) { + String vInstall = getHelper().format(getHelper().getFirmwareVersion()); + if (vInstall == null || new Version(vInstall).compareTo(v53) > 0) { + String newInfoText = getContext().getString(R.string.mi2_fw_installhandler_fw53_hint, v53.get()) + "\n\n" + installActivity.getInfoText(); + installActivity.setInfoText(newInfoText); + } + } + } + } + + private Version getFirmwareVersionOf(GBDevice device) { + String version = device.getFirmwareVersion(); + if (version == null || version.length() == 0) { + return null; + } + if (version.charAt(0) == 'V') { + version = version.substring(1); + } + try { + return new Version(version); + } catch (Exception ex) { + LOG.error("Unable to parse version: " + version); + return null; + } + } + + private FirmwareType getFirmwareType() { + AbstractMiBandFWHelper helper = getHelper(); + if (helper instanceof MiBand2FWHelper) { + return ((MiBand2FWHelper) helper).getFirmwareInfo().getFirmwareType(); + } + return FirmwareType.INVALID; + } + @Override protected AbstractMiBandFWHelper createHelper(Uri uri, Context context) throws IOException { return new MiBand2FWHelper(uri, context); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java index b0a8030e6..e7679301f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java @@ -16,6 +16,13 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.util; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + public class CheckSums { public static int getCRC8(byte[] seq) { int len = seq.length; @@ -51,4 +58,31 @@ public class CheckSums { crc &= 0xffff; return crc; } + + public static void main(String[] args) throws IOException { + if (args == null || args.length == 0) { + throw new IllegalArgumentException("Pass the files to be checksummed as arguments"); + } + for (String name : args) { + try (FileInputStream in = new FileInputStream(name)) { + byte[] bytes = readAll(in, 1000 * 1000); + System.out.println(name + " : " + getCRC16(bytes)); + } + } + } + + public static byte[] readAll(InputStream in, long maxLen) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(8192, in.available())); + byte[] buf = new byte[8192]; + int read = 0; + long totalRead = 0; + while ((read = in.read(buf)) > 0) { + out.write(buf, 0, read); + totalRead += read; + if (totalRead > maxLen) { + throw new IOException("Too much data to read into memory. Got already " + totalRead + buf); + } + } + return out.toByteArray(); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java new file mode 100644 index 000000000..3d363745f --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java @@ -0,0 +1,48 @@ +package nodomain.freeyourgadget.gadgetbridge.util; + +// http://stackoverflow.com/questions/198431/how-do-you-compare-two-version-strings-in-java +public class Version implements Comparable { + + private String version; + + public final String get() { + return this.version; + } + + public Version(String version) { + if(version == null) + throw new IllegalArgumentException("Version can not be null"); + if(!version.matches("[0-9]+(\\.[0-9]+)*")) + throw new IllegalArgumentException("Invalid version format"); + this.version = version; + } + + @Override public int compareTo(Version that) { + if(that == null) + return 1; + String[] thisParts = this.get().split("\\."); + String[] thatParts = that.get().split("\\."); + int length = Math.max(thisParts.length, thatParts.length); + for(int i = 0; i < length; i++) { + int thisPart = i < thisParts.length ? + Integer.parseInt(thisParts[i]) : 0; + int thatPart = i < thatParts.length ? + Integer.parseInt(thatParts[i]) : 0; + if(thisPart < thatPart) + return -1; + if(thisPart > thatPart) + return 1; + } + return 0; + } + + @Override public boolean equals(Object that) { + if(this == that) + return true; + if(that == null) + return false; + if(this.getClass() != that.getClass()) + return false; + return this.compareTo((Version) that) == 0; + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 61453fbe5..4f6039a38 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -406,4 +406,5 @@ (%1$s) You found it! Mi2: Time Format + You need to install version %1$s before installing this firmware! From cf35e84feb17a69368c1be23d428953667abfa6c Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Tue, 14 Mar 2017 23:54:56 +0100 Subject: [PATCH 11/18] Mi2: add hint about font installation for text notifications --- .../devices/miband2/MiBand2FWInstallHandler.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java index 8ea09a151..862bbfeda 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java @@ -44,6 +44,15 @@ public class MiBand2FWInstallHandler extends AbstractMiBandFWInstallHandler { public void validateInstallation(InstallActivity installActivity, GBDevice device) { super.validateInstallation(installActivity, device); maybeAddFw53Hint(installActivity, device); + maybeAddFontHint(installActivity); + } + + private void maybeAddFontHint(InstallActivity installActivity) { + FirmwareType type = getFirmwareType(); + if (type == FirmwareType.FIRMWARE) { + String newInfoText = installActivity.getInfoText() + "\n\n" + "Note: you may install Mili_pro.ft or Mili_pro.ft.en to enable text notifications."; + installActivity.setInfoText(newInfoText); + } } private void maybeAddFw53Hint(InstallActivity installActivity, GBDevice device) { From d408be5ec8701413dc635b7db6bb9431140e9590 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 15 Mar 2017 00:26:39 +0100 Subject: [PATCH 12/18] Mi2: make text/icon notifications confiurable and version dependent --- .../devices/miband/MiBandConst.java | 5 +++++ .../miband/MiBandPreferencesActivity.java | 2 ++ .../miband2/MiBand2FWInstallHandler.java | 3 ++- .../devices/miband2/Mi2FirmwareInfo.java | 1 + .../service/devices/miband2/MiBand2Support.java | 17 +++++++++++++++-- app/src/main/res/values/strings.xml | 3 +++ app/src/main/res/xml/miband_preferences.xml | 7 +++++++ 7 files changed, 35 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java index 44ae13039..998e94b31 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java @@ -21,6 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import nodomain.freeyourgadget.gadgetbridge.util.Version; public final class MiBandConst { private static final Logger LOG = LoggerFactory.getLogger(MiBandConst.class); @@ -35,6 +36,7 @@ public final class MiBandConst { public static final String PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS = "mi_device_time_offset_hours"; public static final String PREF_MI2_DATEFORMAT = "mi2_dateformat"; public static final String PREF_MI2_ACTIVATE_DISPLAY_ON_LIFT = "mi2_activate_display_on_lift_wrist"; + public static final String PREF_MI2_ENABLE_TEXT_NOTIFICATIONS = "mi2_enable_text_notifications"; public static final String PREF_MIBAND_SETUP_BT_PAIRING = "mi_setup_bt_pairing"; @@ -48,6 +50,9 @@ public final class MiBandConst { public static final String MI_AMAZFIT = "Amazfit"; public static final String MI_PRO = "2"; + public static final Version MI2_FW_VERSION_MIN_TEXT_NOTIFICATIONS = new Version("1.0.1.28"); + public static final Version MI2_FW_VERSION_INTERMEDIATE_UPGRADE_53 = new Version("1.0.0.53"); + public static int getNotificationPrefIntValue(String pref, String origin, Prefs prefs, int defaultValue) { String key = getNotificationPrefKey(pref, origin); return prefs.getInt(key, defaultValue); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java index f9cb2439d..a7916376f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java @@ -39,6 +39,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.OR import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_INCOMING_CALL; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ACTIVATE_DISPLAY_ON_LIFT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ENABLE_TEXT_NOTIFICATIONS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_ADDRESS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR; @@ -163,6 +164,7 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity { prefKeys.add(ActivityUser.PREF_USER_STEPS_GOAL); prefKeys.add(PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR); prefKeys.add(PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS); + prefKeys.add(PREF_MI2_ENABLE_TEXT_NOTIFICATIONS); prefKeys.add(getNotificationPrefKey(VIBRATION_COUNT, ORIGIN_ALARM_CLOCK)); prefKeys.add(getNotificationPrefKey(VIBRATION_COUNT, ORIGIN_INCOMING_CALL)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java index 862bbfeda..d0ecec252 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java @@ -28,6 +28,7 @@ import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity; import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.FirmwareType; @@ -63,7 +64,7 @@ public class MiBand2FWInstallHandler extends AbstractMiBandFWInstallHandler { Version deviceVersion = getFirmwareVersionOf(device); if (deviceVersion != null) { - Version v53 = new Version("1.0.0.53"); + Version v53 = MiBandConst.MI2_FW_VERSION_INTERMEDIATE_UPGRADE_53; if (deviceVersion.compareTo(v53) < 0) { String vInstall = getHelper().format(getHelper().getFirmwareVersion()); if (vInstall == null || new Version(vInstall).compareTo(v53) > 0) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java index 189db116b..a08a27afa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2FirmwareInfo.java @@ -58,6 +58,7 @@ public class Mi2FirmwareInfo { // firmware crcToVersion.put(41899, "1.0.0.39"); crcToVersion.put(49197, "1.0.0.53"); + crcToVersion.put(32450, "1.0.1.28"); crcToVersion.put(51770, "1.0.1.34"); crcToVersion.put(3929, "1.0.1.39"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java index 85e272561..9ef66da91 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java @@ -99,6 +99,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.operations.U import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import nodomain.freeyourgadget.gadgetbridge.util.Version; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_FLASH_COLOUR; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_FLASH_COUNT; @@ -304,8 +305,17 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } private NotificationStrategy getNotificationStrategy() { -// return new Mi2NotificationStrategy(this); - return new Mi2TextNotificationStrategy(this); + String firmwareVersion = getDevice().getFirmwareVersion(); + if (firmwareVersion != null) { + Version ver = new Version(firmwareVersion); + if (MiBandConst.MI2_FW_VERSION_MIN_TEXT_NOTIFICATIONS.compareTo(ver) > 0) { + return new Mi2NotificationStrategy(this); + } + } + if (GBApplication.getPrefs().getBoolean(MiBandConst.PREF_MI2_ENABLE_TEXT_NOTIFICATIONS, true)) { + return new Mi2TextNotificationStrategy(this); + } + return new Mi2NotificationStrategy(this); } private static final byte[] startHeartMeasurementManual = new byte[]{0x15, MiBandService.COMMAND_SET_HR_MANUAL, 1}; @@ -990,6 +1000,9 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { versionCmd.hwVersion = info.getHardwareRevision(); // versionCmd.fwVersion = info.getFirmwareRevision(); // always null versionCmd.fwVersion = info.getSoftwareRevision(); + if (versionCmd.fwVersion != null && versionCmd.fwVersion.length() > 0 && versionCmd.fwVersion.charAt(0) == 'V') { + versionCmd.fwVersion = versionCmd.fwVersion.substring(1); + } handleGBDeviceEvent(versionCmd); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4f6039a38..80857bc11 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -407,4 +407,7 @@ You found it! Mi2: Time Format You need to install version %1$s before installing this firmware! + Text notifications + = 1.0.1.28 and Mili_pro.ft* installed.]]> + off diff --git a/app/src/main/res/xml/miband_preferences.xml b/app/src/main/res/xml/miband_preferences.xml index 1c8856822..e1bbb2f9c 100644 --- a/app/src/main/res/xml/miband_preferences.xml +++ b/app/src/main/res/xml/miband_preferences.xml @@ -48,6 +48,13 @@ android:key="mi2_activate_display_on_lift_wrist" android:title="@string/mi2_prefs_activate_display_on_lift" /> + + Date: Wed, 15 Mar 2017 21:26:05 +0100 Subject: [PATCH 13/18] update translations from transifex (thanks!) --- app/src/main/res/values-de/strings.xml | 7 +++++++ app/src/main/res/values-es/strings.xml | 6 ++++++ app/src/main/res/values-fr/strings.xml | 6 ++++++ app/src/main/res/values-he/strings.xml | 1 + app/src/main/res/values-it/strings.xml | 2 ++ app/src/main/res/values-ja/strings.xml | 6 ++++++ 6 files changed, 28 insertions(+) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 242ce8ccf..72c4a6596 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -13,6 +13,12 @@ Gerät löschen %1$s löschen Das wird das Gerät und alle zugehörigen Daten löschen! + Navigations-Menü öffnen + Navigations-Menü schließen + Halte die Karte lange gedrückt, um die Verbindung zu trennen. + Trenne ... + Verbinde ... + Screenshot des Gerätes wird erstellt. Debug App Manager @@ -181,6 +187,7 @@ Keine gültigen Benutzerinformationen angegeben, verwende Dummy-Daten für\'s Erste. Wenn Dein Mi Band vibriert und blinkt, tippe ein paar Mal schnell hintereinander darauf. Installieren + Mache dein Gerät auffindbar. Derzeit verbundene Geräte werden wahrscheinlich nicht erkannt. Aktiviere die Standortbestimmung (zum Beispiel GPS) in Android 6+. Deaktiviere den Privatsphäreschutz für Gadgetbridge, da er zu Abstürzen und Neustarts deines Telefons führen kann. Wenn nach einigen Minuten kein Gerät erkannt wird, versuche es nach einem Neustart deines Telefons erneut. Tipp: Bild des Geräts Name/Alias diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 6e4405ba3..d7b8e2425 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -13,6 +13,12 @@ Borrar Dispositivo Borrar %1$s ¡Esta acción borrará el dispositivo y toda su información asociada! + Abrir el cajón de navegación + Cerrar el cajón de navegación + Mantener pulsado el icono para desconectar + Desconectando + Conectando + Captura de pantalla del dispositivo Depuración Gestor de app diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 84992fdc2..634fc00cf 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -13,6 +13,12 @@ Supprimer l’appareil Supprimer %1$s Ceci va supprimer l’appareil et toutes les données associées ! + Ouvrir le tiroir de navigation + Fermer le tiroir de navigation + Presser longuement l\'icône pour déconnecter + Déconnexion + Connexion + Capture d\'écran de l\'appareil Déboguer Gestionnaire d\'application diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index a04c9706c..ff2299501 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -181,6 +181,7 @@ לא ניתנו נתוני משתמש, נעשה שימוש בנתוני דמה לבינתיים. כאשר ה־Mi Band שלך רוטט ומהבהב, יש לגעת בו מספר פעמים ברצף. התקנה + יש להפעיל את האפשרות לאיתור ההתקן שלך. התקנים שכבר מחוברים כעת לא יתגלו. יש להפעיל מיקום (GPS) באנדרואיד 6+. יש לנטרל את שומר הפרטיות עבור Gadgetbridge כיוון שתכונה זו עשויה להקריס ולהפעיל מחדש את הטלפון שלך. אם לא נמצא אף התקן לאחר מספר דקות יש לנסות שוב לאחר הפעלת הטלפון הנייד שלך מחדש. לתשומת לבך: תמונת ההתקן שם/כינוי diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 93d322fe6..6367a6d15 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -13,6 +13,8 @@ Rimuovi dispositivo Rimuovi %1$s Il dispositivo verrà rimosso e tutti i dati ad esso associati verranno cancellati! + Disconnessione + Connessione Debug Gestione app diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 3bc4b752f..ddf2c425f 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -13,6 +13,12 @@ デバイスを削除 %1$s を削除 これにより、デバイスと関連するデータを削除します! + ナビゲーションドロワーを開く + ナビゲーションドロワーを閉じる + カードを長押しすると切断します + 切断中 + 接続中 + デバイスのスクリーンショットを取得中 デバッグ アプリ管理画面 From f4e955dbe0b471d3ef9613e7cdfe8f62e5194874 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 15 Mar 2017 23:42:30 +0100 Subject: [PATCH 14/18] Updated changelog for 0.18.0 --- CHANGELOG.md | 11 ++++++++--- app/src/main/res/xml/changelog_master.xml | 5 +++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82201e061..12a2b1a32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,15 @@ * Add Czech translation * Add Hebrew translation and transliteration * Consistently display device specific icons already during discovery -* Add sleep chart diplaying the last week of sleep +* Add sleep chart displaying the last week of sleep * Huge speedup for weekly charts when changing days -* Drop support for pre Gadgetbride 0.12.0 database -* Pebble: allow configuration webpages (clay) to access device location +* Drop support for importing pre Gadgetbridge 0.12.0 database +* Pebble: allow configuration web pages (clay) to access device location +* Mi2: Initial support for text notifications, caller ID, and icons (requires font installation) (#560) +* Mi2: Support for flashing Mili_pro.ft* font files +* Mi2: Improved firmware/font updated +* Mi2: Set 12h/24h time format, following the Android configuration (#573) +* Improved BLE discovery and connectivity ####Version 0.17.5 * Automatically start the service on boot (can be turned off) diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index d8314326c..954f33d1b 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -10,6 +10,11 @@ Huge speedup for weekly charts when changing days Drop support for pre Gadgetbride 0.12.0 database Pebble: allow configuration webpages (clay) to access device location + Mi2: Initial support for text notifications, caller ID, and icons (requires font installation) (#560) + Mi2: Support for flashing Mili_pro.ft* font files + Mi2: Improved firmware/font updated + Mi2: Set 12h/24h time format, following the Android configuration (#573) + Improved BLE discovery and connectivity Automatically start the service on boot (can be turned off) From 408dd9c26f9e35f899c58ac5c0c79e9730e0097c Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 16 Mar 2017 17:20:18 +0100 Subject: [PATCH 15/18] Do not try to request k9 permissions in CCv2, we dont need it --- .../gadgetbridge/activities/ControlCenterv2.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java index cfd4ed154..8a7d6ab4d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java @@ -10,6 +10,7 @@ import android.content.pm.PackageManager; import android.graphics.Canvas; import android.os.Build; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.NavigationView; import android.support.v4.app.ActivityCompat; @@ -196,7 +197,7 @@ public class ControlCenterv2 extends AppCompatActivity } @Override - public boolean onNavigationItemSelected(MenuItem item) { + public boolean onNavigationItemSelected(@NonNull MenuItem item) { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); @@ -274,8 +275,6 @@ public class ControlCenterv2 extends AppCompatActivity wantedPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_DENIED) wantedPermissions.add(Manifest.permission.READ_CALENDAR); - if (ContextCompat.checkSelfPermission(this, "com.fsck.k9.permission.READ_MESSAGES") == PackageManager.PERMISSION_DENIED) - wantedPermissions.add("com.fsck.k9.permission.READ_MESSAGES"); if (!wantedPermissions.isEmpty()) ActivityCompat.requestPermissions(this, wantedPermissions.toArray(new String[wantedPermissions.size()]), 0); From 7a6b0ed2b02d4da4a0d39ca92f437773d2475408 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 16 Mar 2017 17:24:15 +0100 Subject: [PATCH 16/18] support material fork of K9 --- .../gadgetbridge/externalevents/NotificationListener.java | 2 +- .../freeyourgadget/gadgetbridge/model/AppNotificationType.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index d7b70c3ec..4aec1b566 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -265,7 +265,7 @@ public class NotificationListener extends NotificationListenerService { notificationSpec.type = AppNotificationType.getInstance().get(source); - if (source.equals("com.fsck.k9")) { + if (source.startsWith("com.fsck.k9")) { // we dont want group summaries at all for k9 if ((notification.flags & Notification.FLAG_GROUP_SUMMARY) == Notification.FLAG_GROUP_SUMMARY) { return; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java index 7f78dc80e..29b2f2b6f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/AppNotificationType.java @@ -33,6 +33,7 @@ public class AppNotificationType extends HashMap { private AppNotificationType() { // Generic Email put("com.fsck.k9", NotificationType.GENERIC_EMAIL); + put("com.fsck.k9.material", NotificationType.GENERIC_EMAIL); put("com.imaeses.squeaky", NotificationType.GENERIC_EMAIL); put("com.android.email", NotificationType.GENERIC_EMAIL); From 6a842c52faeaec16d4f4dee1c733d34eded33038 Mon Sep 17 00:00:00 2001 From: License Bot Date: Thu, 16 Mar 2017 17:36:15 +0100 Subject: [PATCH 17/18] Update license header in all java files. --- .../activities/ControlCenterv2.java | 17 +++++++++++++++++ .../gadgetbridge/adapter/GBDeviceAdapterv2.java | 17 +++++++++++++++++ .../devices/miband/MiBandPairingActivity.java | 3 ++- .../devices/pebble/PebblePairingActivity.java | 3 ++- .../gadgetbridge/impl/GBDeviceService.java | 4 ++-- .../profiles/alertnotification/Command.java | 16 ++++++++++++++++ .../service/devices/hplus/HPlusSupport.java | 3 ++- .../miband2/Mi2TextNotificationStrategy.java | 16 ++++++++++++++++ .../gadgetbridge/util/Version.java | 16 ++++++++++++++++ 9 files changed, 90 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java index 8a7d6ab4d..33d18fdbd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities; import android.Manifest; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index af7e4dfb4..7dc54dbf1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -1,3 +1,20 @@ +/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti, Lem Dulfo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.adapter; import android.app.Activity; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java index 5e5a33f33..deed2c2e0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java index 017a60504..f7823a01e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer +/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index f48e9d94e..7d3428a1c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -1,5 +1,5 @@ -/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, ivanovlev, - Julien Pivotto, Kasha, Steffen Liebergeld +/* Copyright (C) 2015-2017 Alberto, Andreas Shimokawa, Carsten Pfeiffer, + ivanovlev, Julien Pivotto, Kasha, Steffen Liebergeld This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java index 263f06695..e7d4021db 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/Command.java @@ -1,3 +1,19 @@ +/* Copyright (C) 2017 Carsten Pfeiffer + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification; /** diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index 18791908d..96f42311e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2016-2017 Andreas Shimokawa, ivanovlev, João Paulo Barraca +/* Copyright (C) 2016-2017 Alberto, Andreas Shimokawa, ivanovlev, João + Paulo Barraca This file is part of Gadgetbridge. diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java index 13f03ffb5..416da22d5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2TextNotificationStrategy.java @@ -1,3 +1,19 @@ +/* Copyright (C) 2017 Carsten Pfeiffer + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband2; import android.bluetooth.BluetoothGattCharacteristic; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java index 3d363745f..c1db22ec3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java @@ -1,3 +1,19 @@ +/* Copyright (C) 2017 Carsten Pfeiffer + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.util; // http://stackoverflow.com/questions/198431/how-do-you-compare-two-version-strings-in-java From 9eade33d72360fdd6642c6f96f31c52b89afbc63 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 16 Mar 2017 17:36:46 +0100 Subject: [PATCH 18/18] Start VibrationActivity when using "find device" button with Vibratissimo (The activity was inaccessible) --- .../gadgetbridge/adapter/GBDeviceAdapterv2.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index 7dc54dbf1..27e64d649 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -44,11 +44,13 @@ import java.util.List; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms; +import nodomain.freeyourgadget.gadgetbridge.activities.VibrationActivity; import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -78,7 +80,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter