mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-25 01:55:50 +01:00
Huami: Display native alarm notification
This commit is contained in:
parent
cb0dfaae79
commit
7512147c34
@ -160,7 +160,7 @@ public class DebugActivity extends AbstractGBActivity {
|
|||||||
editContent = findViewById(R.id.editContent);
|
editContent = findViewById(R.id.editContent);
|
||||||
|
|
||||||
final ArrayList<String> spinnerArray = new ArrayList<>();
|
final ArrayList<String> spinnerArray = new ArrayList<>();
|
||||||
for (NotificationType notificationType : NotificationType.values()) {
|
for (NotificationType notificationType : NotificationType.sortedValues()) {
|
||||||
spinnerArray.add(notificationType.name());
|
spinnerArray.add(notificationType.name());
|
||||||
}
|
}
|
||||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, spinnerArray);
|
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, spinnerArray);
|
||||||
@ -177,7 +177,7 @@ public class DebugActivity extends AbstractGBActivity {
|
|||||||
notificationSpec.body = testString;
|
notificationSpec.body = testString;
|
||||||
notificationSpec.sender = testString;
|
notificationSpec.sender = testString;
|
||||||
notificationSpec.subject = testString;
|
notificationSpec.subject = testString;
|
||||||
notificationSpec.type = NotificationType.values()[sendTypeSpinner.getSelectedItemPosition()];
|
notificationSpec.type = NotificationType.sortedValues()[sendTypeSpinner.getSelectedItemPosition()];
|
||||||
notificationSpec.pebbleColor = notificationSpec.type.color;
|
notificationSpec.pebbleColor = notificationSpec.type.color;
|
||||||
GBApplication.deviceService().onNotification(notificationSpec);
|
GBApplication.deviceService().onNotification(notificationSpec);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.model;
|
package nodomain.freeyourgadget.gadgetbridge.model;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleColor;
|
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleColor;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleIconID;
|
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleIconID;
|
||||||
|
|
||||||
@ -136,4 +139,22 @@ public enum NotificationType {
|
|||||||
return "generic";
|
return "generic";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NotificationType[] sortedValues() {
|
||||||
|
final NotificationType[] sorted = NotificationType.values();
|
||||||
|
Arrays.sort(sorted, new Comparator<NotificationType>() {
|
||||||
|
@Override public int compare(final NotificationType n1, final NotificationType n2) {
|
||||||
|
// Keep unknown first
|
||||||
|
if (n1.equals(NotificationType.UNKNOWN)) {
|
||||||
|
return -1;
|
||||||
|
} else if (n2.equals(NotificationType.UNKNOWN)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n1.name().compareToIgnoreCase(n2.name());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return sorted;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfittrex.Am
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfittrexpro.AmazfitTRexProSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfittrexpro.AmazfitTRexProSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitvergel.AmazfitVergeLSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitvergel.AmazfitVergeLSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitx.AmazfitXSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitx.AmazfitXSupport;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband3.MiBand3Support;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband3.MiBand3Support;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband4.MiBand4Support;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband4.MiBand4Support;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband5.MiBand5Support;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband5.MiBand5Support;
|
||||||
@ -168,7 +169,7 @@ public class DeviceSupportFactory {
|
|||||||
case MIBAND:
|
case MIBAND:
|
||||||
return new ServiceDeviceSupport(new MiBandSupport(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
return new ServiceDeviceSupport(new MiBandSupport(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
case MIBAND2:
|
case MIBAND2:
|
||||||
return new ServiceDeviceSupport(new HuamiSupport(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
return new ServiceDeviceSupport(new MiBand2Support(), ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING);
|
||||||
case MIBAND3:
|
case MIBAND3:
|
||||||
return new ServiceDeviceSupport(new MiBand3Support());
|
return new ServiceDeviceSupport(new MiBand3Support());
|
||||||
case MIBAND4:
|
case MIBAND4:
|
||||||
|
@ -251,7 +251,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_
|
|||||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_YEAR_OF_BIRTH;
|
import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_YEAR_OF_BIRTH;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL;
|
import static nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL;
|
||||||
|
|
||||||
public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
public abstract class HuamiSupport extends AbstractBTLEDeviceSupport {
|
||||||
|
|
||||||
// We introduce key press counter for notification purposes
|
// We introduce key press counter for notification purposes
|
||||||
private static int currentButtonActionId = 0;
|
private static int currentButtonActionId = 0;
|
||||||
@ -296,7 +296,6 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
private final GBDeviceEventFindPhone findPhoneEvent = new GBDeviceEventFindPhone();
|
private final GBDeviceEventFindPhone findPhoneEvent = new GBDeviceEventFindPhone();
|
||||||
|
|
||||||
private RealtimeSamplesSupport realtimeSamplesSupport;
|
private RealtimeSamplesSupport realtimeSamplesSupport;
|
||||||
private boolean alarmClockRinging;
|
|
||||||
|
|
||||||
protected boolean isMusicAppStarted = false;
|
protected boolean isMusicAppStarted = false;
|
||||||
protected MusicSpec bufferMusicSpec = null;
|
protected MusicSpec bufferMusicSpec = null;
|
||||||
@ -738,7 +737,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performPreferredNotification(String task, String notificationOrigin, SimpleNotification simpleNotification, int alertLevel, BtLEAction extraAction) {
|
protected void performPreferredNotification(String task, String notificationOrigin, SimpleNotification simpleNotification, int alertLevel, BtLEAction extraAction) {
|
||||||
try {
|
try {
|
||||||
TransactionBuilder builder = performInitialized(task);
|
TransactionBuilder builder = performInitialized(task);
|
||||||
Prefs prefs = GBApplication.getPrefs();
|
Prefs prefs = GBApplication.getPrefs();
|
||||||
@ -783,18 +782,10 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
/*
|
public void onNotification(NotificationSpec notificationSpec) {
|
||||||
This works on all Huami devices except Mi Band 2
|
final boolean hasExtraHeader = notificationHasExtraHeader();
|
||||||
*/
|
final int maxLength = notificationMaxLength();
|
||||||
protected void sendNotificationNew(NotificationSpec notificationSpec, boolean hasExtraHeader) {
|
|
||||||
sendNotificationNew(notificationSpec, hasExtraHeader, 230);
|
|
||||||
}
|
|
||||||
protected void sendNotificationNew(NotificationSpec notificationSpec, boolean hasExtraHeader, int maxLength) {
|
|
||||||
if (notificationSpec.type == NotificationType.GENERIC_ALARM_CLOCK) {
|
|
||||||
onAlarmClock(notificationSpec);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String senderOrTitle = StringUtils.getFirstOf(notificationSpec.sender, notificationSpec.title);
|
String senderOrTitle = StringUtils.getFirstOf(notificationSpec.sender, notificationSpec.title);
|
||||||
|
|
||||||
@ -853,6 +844,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
prefixlength += 4;
|
prefixlength += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final step: build command
|
||||||
byte[] rawmessage = message.getBytes();
|
byte[] rawmessage = message.getBytes();
|
||||||
int length = Math.min(rawmessage.length, maxLength - prefixlength);
|
int length = Math.min(rawmessage.length, maxLength - prefixlength);
|
||||||
if (length < rawmessage.length) {
|
if (length < rawmessage.length) {
|
||||||
@ -889,6 +881,14 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean notificationHasExtraHeader() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int notificationMaxLength() {
|
||||||
|
return 230;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSetReminders(ArrayList<? extends Reminder> reminders) {
|
public void onSetReminders(ArrayList<? extends Reminder> reminders) {
|
||||||
final TransactionBuilder builder;
|
final TransactionBuilder builder;
|
||||||
@ -1116,38 +1116,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNotification(NotificationSpec notificationSpec) {
|
|
||||||
if (notificationSpec.type == NotificationType.GENERIC_ALARM_CLOCK) {
|
|
||||||
onAlarmClock(notificationSpec);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int alertLevel = HuamiService.ALERT_LEVEL_MESSAGE;
|
|
||||||
if (notificationSpec.type == NotificationType.UNKNOWN) {
|
|
||||||
alertLevel = HuamiService.ALERT_LEVEL_VIBRATE_ONLY;
|
|
||||||
}
|
|
||||||
String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext()).trim();
|
|
||||||
String origin = notificationSpec.type.getGenericType();
|
|
||||||
SimpleNotification simpleNotification = new SimpleNotification(message, BLETypeConversions.toAlertCategory(notificationSpec.type), notificationSpec.type);
|
|
||||||
performPreferredNotification(origin + " received", origin, simpleNotification, alertLevel, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onAlarmClock(NotificationSpec notificationSpec) {
|
|
||||||
alarmClockRinging = true;
|
|
||||||
AbortTransactionAction abortAction = new StopNotificationAction(getCharacteristic(UUID_CHARACTERISTIC_ALERT_LEVEL)) {
|
|
||||||
@Override
|
|
||||||
protected boolean shouldAbort() {
|
|
||||||
return !isAlarmClockRinging();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext());
|
|
||||||
SimpleNotification simpleNotification = new SimpleNotification(message, AlertCategory.HighPriorityAlert, notificationSpec.type);
|
|
||||||
performPreferredNotification("alarm clock ringing", MiBandConst.ORIGIN_ALARM_CLOCK, simpleNotification, HuamiService.ALERT_LEVEL_VIBRATE_ONLY, abortAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeleteNotification(int id) {
|
public void onDeleteNotification(int id) {
|
||||||
alarmClockRinging = false; // we should have the notificationtype at least to check
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1255,11 +1226,6 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAlarmClockRinging() {
|
|
||||||
// don't synchronize, this is not really important
|
|
||||||
return alarmClockRinging;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isTelephoneRinging() {
|
private boolean isTelephoneRinging() {
|
||||||
// don't synchronize, this is not really important
|
// don't synchronize, this is not really important
|
||||||
return telephoneRinging;
|
return telephoneRinging;
|
||||||
@ -2854,8 +2820,8 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSendWeather(WeatherSpec weatherSpec) {
|
public void onSendWeather(WeatherSpec weatherSpec) {
|
||||||
// FIXME: currently HuamiSupport *is* MiBand2 support, so return if we are using Mi Band 2
|
final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
|
||||||
if (gbDevice.getType() == DeviceType.MIBAND2) {
|
if (!coordinator.supportsWeather()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3913,9 +3879,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
requestAlarms(builder);
|
requestAlarms(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {
|
public abstract HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException;
|
||||||
return new MiBand2FWHelper(uri, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UpdateFirmwareOperation createUpdateFirmwareOperation(Uri uri) {
|
public UpdateFirmwareOperation createUpdateFirmwareOperation(Uri uri) {
|
||||||
return new UpdateFirmwareOperation(uri, this);
|
return new UpdateFirmwareOperation(uri, this);
|
||||||
|
@ -53,11 +53,6 @@ public class AmazfitBipSupport extends HuamiSupport {
|
|||||||
return new AmazfitBipTextNotificationStrategy(this);
|
return new AmazfitBipTextNotificationStrategy(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNotification(NotificationSpec notificationSpec) {
|
|
||||||
super.sendNotificationNew(notificationSpec, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFindDevice(boolean start) {
|
public void onFindDevice(boolean start) {
|
||||||
CallSpec callSpec = new CallSpec();
|
CallSpec callSpec = new CallSpec();
|
||||||
|
@ -47,8 +47,13 @@ public class AmazfitBipSSupport extends AmazfitBipSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNotification(NotificationSpec notificationSpec) {
|
protected boolean notificationHasExtraHeader() {
|
||||||
super.sendNotificationNew(notificationSpec, true, 512);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int notificationMaxLength() {
|
||||||
|
return 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,11 +49,10 @@ public class AmazfitGTSSupport extends AmazfitBipSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNotification(NotificationSpec notificationSpec) {
|
protected boolean notificationHasExtraHeader() {
|
||||||
super.sendNotificationNew(notificationSpec, true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {
|
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {
|
||||||
return new AmazfitGTSFWHelper(uri, context);
|
return new AmazfitGTSFWHelper(uri, context);
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitgts2;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitgts2;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ApplicationInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -31,14 +29,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgts2.AmazfitGTS2MiniFWHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgts2.AmazfitGTS2MiniFWHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
|
||||||
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.devices.huami.HuamiIcon;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitgts.AmazfitGTSSupport;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
|
||||||
|
|
||||||
public class AmazfitGTS2MiniSupport extends AmazfitGTS2Support {
|
public class AmazfitGTS2MiniSupport extends AmazfitGTS2Support {
|
||||||
|
|
||||||
@ -53,122 +43,4 @@ public class AmazfitGTS2MiniSupport extends AmazfitGTS2Support {
|
|||||||
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {
|
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {
|
||||||
return new AmazfitGTS2MiniFWHelper(uri, context);
|
return new AmazfitGTS2MiniFWHelper(uri, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void sendNotificationNew(NotificationSpec notificationSpec, boolean hasExtraHeader, int maxLength) {
|
|
||||||
// step 1: bail out if this is an alarm clock notification
|
|
||||||
|
|
||||||
if (notificationSpec.type == NotificationType.GENERIC_ALARM_CLOCK) {
|
|
||||||
onAlarmClock(notificationSpec);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// step 2: (formerly in try block) get notification type
|
|
||||||
AlertCategory alertCategory = AlertCategory.CustomHuami;
|
|
||||||
byte customIconId = HuamiIcon.mapToIconId(notificationSpec.type);
|
|
||||||
|
|
||||||
// step 3: build notification (sender+body)
|
|
||||||
/*
|
|
||||||
* Format followed by the device:
|
|
||||||
* <SENDER> \0 <BODY> \0 <APP SUFFIX>
|
|
||||||
* sender will get ignored except for the icons
|
|
||||||
* specified on the HuamiIcon class.
|
|
||||||
* for email, App Suffix will be taken as sender
|
|
||||||
*/
|
|
||||||
String senderOrTitle = StringUtils.getFirstOf(notificationSpec.sender, notificationSpec.title);
|
|
||||||
boolean acceptsSender = HuamiIcon.acceptsSender(customIconId);
|
|
||||||
String message;
|
|
||||||
|
|
||||||
if (!acceptsSender && !senderOrTitle.equals(notificationSpec.sourceName)) {
|
|
||||||
// make sure we always include the notification sender/title
|
|
||||||
message = "-\0"; //leave title blank, it's useless
|
|
||||||
message += StringUtils.truncate(senderOrTitle, 64) + "\n";
|
|
||||||
} else {
|
|
||||||
message = StringUtils.truncate(senderOrTitle, 64) + "\0";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notificationSpec.subject != null) {
|
|
||||||
message += StringUtils.truncate(notificationSpec.subject, 128) + "\n\n";
|
|
||||||
}
|
|
||||||
if (notificationSpec.body != null) {
|
|
||||||
message += StringUtils.truncate(notificationSpec.body, 512);
|
|
||||||
}
|
|
||||||
if (notificationSpec.body == null && notificationSpec.subject == null) {
|
|
||||||
message += " "; // if we have no body we have to send at least something on some devices, else they reboot (Bip S)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
TransactionBuilder builder = performInitialized("new notification");
|
|
||||||
|
|
||||||
// step 4: append suffix
|
|
||||||
byte[] appSuffix = "\0 \0".getBytes();
|
|
||||||
int suffixlength = appSuffix.length;
|
|
||||||
// The SMS icon for AlertCategory.SMS is unique and not available as iconId
|
|
||||||
if (notificationSpec.type == NotificationType.GENERIC_SMS) {
|
|
||||||
alertCategory = AlertCategory.SMS;
|
|
||||||
}
|
|
||||||
// EMAIL icon does not work in FW 0.0.8.74, it did in 0.0.7.90 (old comment)
|
|
||||||
// EMAIL will take the sender from the suffix instead
|
|
||||||
else if (customIconId == HuamiIcon.EMAIL) {
|
|
||||||
alertCategory = AlertCategory.Email;
|
|
||||||
appSuffix = ("\0"+senderOrTitle+"\0").getBytes();
|
|
||||||
suffixlength = appSuffix.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if I understood correctly, we don't need the extra logic for mi band 2 here
|
|
||||||
int prefixlength = 2;
|
|
||||||
|
|
||||||
if (alertCategory == AlertCategory.CustomHuami) {
|
|
||||||
String appName;
|
|
||||||
prefixlength = 3;
|
|
||||||
final PackageManager pm = getContext().getPackageManager();
|
|
||||||
ApplicationInfo ai = null;
|
|
||||||
try {
|
|
||||||
ai = pm.getApplicationInfo(notificationSpec.sourceAppId, 0);
|
|
||||||
} catch (PackageManager.NameNotFoundException ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ai == null) {
|
|
||||||
appName = "\0" + "UNKNOWN" + "\0";
|
|
||||||
} else {
|
|
||||||
appName = "\0" + pm.getApplicationLabel(ai) + "\0";
|
|
||||||
}
|
|
||||||
appSuffix = appName.getBytes();
|
|
||||||
suffixlength = appSuffix.length;
|
|
||||||
}
|
|
||||||
if (hasExtraHeader) {
|
|
||||||
prefixlength += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// final step: build command
|
|
||||||
byte[] rawmessage = message.getBytes();
|
|
||||||
int length = Math.min(rawmessage.length, maxLength - prefixlength);
|
|
||||||
if (length < rawmessage.length) {
|
|
||||||
length = StringUtils.utf8ByteLength(message, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] command = new byte[length + prefixlength + suffixlength];
|
|
||||||
int pos = 0;
|
|
||||||
command[pos++] = (byte) alertCategory.getId();
|
|
||||||
if (hasExtraHeader) {
|
|
||||||
command[pos++] = 0; // TODO
|
|
||||||
command[pos++] = 0;
|
|
||||||
command[pos++] = 0;
|
|
||||||
command[pos++] = 0;
|
|
||||||
}
|
|
||||||
command[pos++] = 1;
|
|
||||||
if (alertCategory == AlertCategory.CustomHuami) {
|
|
||||||
command[pos] = customIconId;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.arraycopy(rawmessage, 0, command, prefixlength, length);
|
|
||||||
System.arraycopy(appSuffix, 0, command, prefixlength + length, appSuffix.length);
|
|
||||||
|
|
||||||
writeToChunked(builder, 0, command);
|
|
||||||
|
|
||||||
builder.queue(getQueue());
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOG.error("Unable to send notification to device", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,8 @@ public class AmazfitNeoSupport extends MiBand5Support {
|
|||||||
private static final Logger LOG = LoggerFactory.getLogger(AmazfitNeoSupport.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AmazfitNeoSupport.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNotification(NotificationSpec notificationSpec) {
|
protected boolean notificationHasExtraHeader() {
|
||||||
super.sendNotificationNew(notificationSpec, false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -53,8 +53,8 @@ public class AmazfitVergeLSupport extends AmazfitBipSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNotification(NotificationSpec notificationSpec) {
|
protected boolean notificationHasExtraHeader() {
|
||||||
super.sendNotificationNew(notificationSpec, true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
/* Copyright (C) 2017-2021 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>. */
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2;
|
||||||
|
|
||||||
|
import static nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipFWHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2.MiBand2FWHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactionAction;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.actions.StopNotificationAction;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
|
||||||
|
|
||||||
|
public class MiBand2Support extends HuamiSupport {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(MiBand2Support.class);
|
||||||
|
|
||||||
|
private boolean alarmClockRinging;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {
|
||||||
|
return new MiBand2FWHelper(uri, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNotification(NotificationSpec notificationSpec) {
|
||||||
|
if (notificationSpec.type == NotificationType.GENERIC_ALARM_CLOCK) {
|
||||||
|
onAlarmClock(notificationSpec);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int alertLevel = HuamiService.ALERT_LEVEL_MESSAGE;
|
||||||
|
if (notificationSpec.type == NotificationType.UNKNOWN) {
|
||||||
|
alertLevel = HuamiService.ALERT_LEVEL_VIBRATE_ONLY;
|
||||||
|
}
|
||||||
|
String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext()).trim();
|
||||||
|
String origin = notificationSpec.type.getGenericType();
|
||||||
|
SimpleNotification simpleNotification = new SimpleNotification(message, BLETypeConversions.toAlertCategory(notificationSpec.type), notificationSpec.type);
|
||||||
|
performPreferredNotification(origin + " received", origin, simpleNotification, alertLevel, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onAlarmClock(NotificationSpec notificationSpec) {
|
||||||
|
alarmClockRinging = true;
|
||||||
|
AbortTransactionAction abortAction = new StopNotificationAction(getCharacteristic(UUID_CHARACTERISTIC_ALERT_LEVEL)) {
|
||||||
|
@Override
|
||||||
|
protected boolean shouldAbort() {
|
||||||
|
return !isAlarmClockRinging();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext());
|
||||||
|
SimpleNotification simpleNotification = new SimpleNotification(message, AlertCategory.HighPriorityAlert, notificationSpec.type);
|
||||||
|
performPreferredNotification("alarm clock ringing", MiBandConst.ORIGIN_ALARM_CLOCK, simpleNotification, HuamiService.ALERT_LEVEL_VIBRATE_ONLY, abortAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeleteNotification(int id) {
|
||||||
|
alarmClockRinging = false; // we should have the notificationtype at least to check
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAlarmClockRinging() {
|
||||||
|
// don't synchronize, this is not really important
|
||||||
|
return alarmClockRinging;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -36,8 +36,8 @@ public class MiBand4Support extends MiBand3Support {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNotification(NotificationSpec notificationSpec) {
|
protected boolean notificationHasExtraHeader() {
|
||||||
super.sendNotificationNew(notificationSpec, true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user