From c3e395818fb87e4ecf05c80f60bfc9e740090026 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Tue, 18 Aug 2015 17:37:51 +0200 Subject: [PATCH 1/7] Adding support for battery events using GBDeviceEvent. - show notification on low battery (closes #40) - Miband specific: add date of last charge and number of charges --- .../deviceevents/GBDeviceEvent.java | 1 + .../GBDeviceEventBatteryInfo.java | 25 ++++++++++++++++++ .../gadgetbridge/impl/GBDevice.java | 17 ++++++------ .../service/AbstractDeviceSupport.java | 25 +++++++++++++++++- .../service/devices/miband/BatteryInfo.java | 26 +++++++++++++++++++ .../service/devices/miband/MiBandSupport.java | 17 +++++++----- .../freeyourgadget/gadgetbridge/util/GB.java | 26 +++++++++++++++++++ app/src/main/res/values/strings.xml | 4 +++ 8 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEvent.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEvent.java index 0aa03f81..5a8246a7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEvent.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEvent.java @@ -15,6 +15,7 @@ public abstract class GBDeviceEvent { SLEEP_MONITOR_RES, SCREENSHOT, DISMISS_NOTIFICATION, + BATTERY_INFO } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java new file mode 100644 index 00000000..2bc311af --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java @@ -0,0 +1,25 @@ +package nodomain.freeyourgadget.gadgetbridge.deviceevents; + + +import java.util.GregorianCalendar; + +public class GBDeviceEventBatteryInfo extends GBDeviceEvent { + public GregorianCalendar lastChargeTime; + public BatteryState state = BatteryState.UNKNOWN; + //TODO: I think the string should be deprecated in favor of the Enum above + public String status; + public short level = 50; + public int numCharges = -1; + + public GBDeviceEventBatteryInfo() { + eventClass = EventClass.BATTERY_INFO; + } + + public enum BatteryState { + UNKNOWN, + CHARGE_FULL, + CHARGE_MEDIUM, + CHARGE_LOW, + CHARGING, + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java index 3bfdf9bf..bf2e213e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java @@ -38,7 +38,8 @@ public class GBDevice implements Parcelable { private String mHardwareVersion = null; private State mState = State.NOT_CONNECTED; private short mBatteryLevel = BATTERY_UNKNOWN; - private String mBatteryState; + //TODO: get rid of String mBatteryStatus in favor of Enum mBatteryState + private String mBatteryStatus; private short mRssi = RSSI_UNKNOWN; private String mBusyTask; @@ -57,7 +58,7 @@ public class GBDevice implements Parcelable { mHardwareVersion = in.readString(); mState = State.values()[in.readInt()]; mBatteryLevel = (short) in.readInt(); - mBatteryState = in.readString(); + mBatteryStatus = in.readString(); mRssi = (short) in.readInt(); mBusyTask = in.readString(); @@ -73,7 +74,7 @@ public class GBDevice implements Parcelable { dest.writeString(mHardwareVersion); dest.writeInt(mState.ordinal()); dest.writeInt(mBatteryLevel); - dest.writeString(mBatteryState); + dest.writeString(mBatteryStatus); dest.writeInt(mRssi); dest.writeString(mBusyTask); } @@ -177,7 +178,7 @@ public class GBDevice implements Parcelable { private void unsetDynamicState() { setBatteryLevel(BATTERY_UNKNOWN); - setBatteryState(null); + setBatteryStatus(null); setFirmwareVersion(null); setRssi(RSSI_UNKNOWN); if (mBusyTask != null) { @@ -284,12 +285,12 @@ public class GBDevice implements Parcelable { /** * Returns a string representation of the battery state. */ - public String getBatteryState() { - return mBatteryState != null ? mBatteryState : GBApplication.getContext().getString(R.string._unknown_); + public String getBatteryStatus() { + return mBatteryStatus != null ? mBatteryStatus : GBApplication.getContext().getString(R.string._unknown_); } - public void setBatteryState(String batteryState) { - mBatteryState = batteryState; + public void setBatteryStatus(String batteryStatus) { + mBatteryStatus = batteryStatus; } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index 64ea42e5..5783aec3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -15,17 +15,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import nodomain.freeyourgadget.gadgetbridge.activities.AppManagerActivity; import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsHost; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.service.receivers.GBCallControlReceiver; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.receivers.GBMusicControlReceiver; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.activities.charts.AbstractChartFragment; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventAppInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; @@ -111,6 +112,9 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { case DISMISS_NOTIFICATION: handleGBDeviceEvent((GBDeviceEventDismissNotification) deviceEvent); break; + case BATTERY_INFO: + handleGBDeviceEvent((GBDeviceEventBatteryInfo) deviceEvent); + break; default: break; } @@ -219,4 +223,23 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { notificationListenerIntent.putExtra("id", deviceEvent.notificationID); LocalBroadcastManager.getInstance(context).sendBroadcast(notificationListenerIntent); } + + public void handleGBDeviceEvent(GBDeviceEventBatteryInfo deviceEvent) { + Context context = getContext(); + LOG.info("Got BATTERY_INFO device event"); + gbDevice.setBatteryLevel(deviceEvent.level); + gbDevice.setBatteryStatus(deviceEvent.status); + + + //TODO: maybe switch to a device-dependent threshold + if (deviceEvent.level < 10) { + GB.updateBatteryNotification(deviceEvent.level, + context.getString(R.string.notif_battery_low_bigtext_last_charge_time, DateFormat.getDateTimeInstance().format(deviceEvent.lastChargeTime.getTime()).toString()) + + context.getString(R.string.notif_battery_low_bigtext_number_of_charges, deviceEvent.numCharges) + , context); + } + + gbDevice.sendDeviceUpdateIntent(context); + } + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java index 8509bc1a..f21bef05 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java @@ -1,5 +1,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband; +import java.util.Calendar; +import java.util.GregorianCalendar; + import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; @@ -31,4 +34,27 @@ public class BatteryInfo extends AbstractInfo { } return GBApplication.getContext().getString(R.string._unknown_); } + + public GregorianCalendar getLastChargeTime() { + GregorianCalendar lastCharge = new GregorianCalendar(); + + if (mData.length >= 10) { + lastCharge.set(Calendar.YEAR, (2000 + mData[1])); + lastCharge.set(Calendar.MONTH, mData[2]); + lastCharge.set(Calendar.DATE, mData[3]); + lastCharge.set(Calendar.HOUR_OF_DAY, mData[4]); + lastCharge.set(Calendar.MINUTE, mData[5]); + lastCharge.set(Calendar.SECOND, mData[6]); + } + + return lastCharge; + } + + public int getNumCharges() { + if (mData.length >= 10) { + return ((0xff & mData[7]) | ((0xff & mData[8]) << 8)); + + } + return -1; + } } 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 8c8e3cea..be9a5db9 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 @@ -18,6 +18,7 @@ import java.util.GregorianCalendar; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; @@ -66,6 +67,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { private DeviceInfo mDeviceInfo; GBDeviceEventVersionInfo versionCmd = new GBDeviceEventVersionInfo(); + GBDeviceEventBatteryInfo batteryCmd = new GBDeviceEventBatteryInfo(); public MiBandSupport() { addSupportedService(MiBandService.UUID_SERVICE_MIBAND_SERVICE); @@ -261,6 +263,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { } return this; } + /** * Part of device initialization process. Do not call manually. * @@ -276,7 +279,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { transaction.write(characteristic, new byte[]{ MiBandService.COMMAND_SET_FITNESS_GOAL, 0, - (byte) (fitnessGoal & 0xff), + (byte) (fitnessGoal & 0xff), (byte) ((fitnessGoal >>> 8) & 0xff) }); } else { @@ -637,6 +640,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { /** * Utility method that may be used to log incoming messages when we don't know how to deal with them yet. + * * @param value */ private void logMessageContent(byte[] value) { @@ -651,13 +655,13 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { * characteristic, * These messages appear to be always 1 byte long, with values that are listed in MiBandService. * It is not excluded that there are further values which are still unknown. - * + *

* Upon receiving known values that request further action by GB, the appropriate method is called. * * @param value */ private void handleNotificationNotif(byte[] value) { - if(value.length != 1) { + if (value.length != 1) { LOG.error("Notifications should be 1 byte long."); LOG.info("RECEIVED DATA WITH LENGTH: " + value.length); for (byte b : value) { @@ -732,9 +736,10 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { private void handleBatteryInfo(byte[] value, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { BatteryInfo info = new BatteryInfo(value); - getDevice().setBatteryLevel((short) info.getLevelInPercent()); - getDevice().setBatteryState(info.getStatus()); - getDevice().sendDeviceUpdateIntent(getContext()); + batteryCmd.level = ((short) info.getLevelInPercent()); + batteryCmd.lastChargeTime = info.getLastChargeTime(); + batteryCmd.numCharges = info.getNumCharges(); + handleGBDeviceEvent(batteryCmd); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java index b7fa7c01..4d624121 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java @@ -44,6 +44,7 @@ import nodomain.freeyourgadget.gadgetbridge.externalevents.TimeChangeReceiver; public class GB { public static final int NOTIFICATION_ID = 1; public static final int NOTIFICATION_ID_INSTALL = 2; + public static final int NOTIFICATION_ID_LOW_BATTERY = 3; private static final Logger LOG = LoggerFactory.getLogger(GB.class); public static final int INFO = 1; @@ -298,4 +299,29 @@ public class GB { NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); nm.notify(NOTIFICATION_ID_INSTALL, notification); } + + private static Notification createBatteryNotification(int level, String text, Context context) { + Intent notificationIntent = new Intent(context, ControlCenter.class); + notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_CLEAR_TASK); + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, + notificationIntent, 0); + + NotificationCompat.Builder nb = new NotificationCompat.Builder(context) + .setContentTitle(context.getString(R.string.notif_battery_low_title)) + .setContentText(context.getString(R.string.notif_battery_low_percent, level)) + .setContentIntent(pendingIntent) + .setSmallIcon(R.drawable.ic_notification) + .setStyle(new NotificationCompat.BigTextStyle().bigText(text)) + .setOngoing(false); + + return nb.build(); + } + + public static void updateBatteryNotification(int level, String text, Context context) { + Notification notification = createBatteryNotification(level, text, context); + + NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + nm.notify(NOTIFICATION_ID_LOW_BATTERY, notification); + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a60ab6c5..7132259b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -166,4 +166,8 @@ Unable to install the given file: $1%s Unable to install the given firmware: it doesn\'t match your Pebble\'s hardware revision. Please wait while determining the installation status... + Gadget battery Low! + Battery left: %s%% + Last charge: %s \n + Number of charges: %s From 0d8adeb7f964650837aaa4566de8f53adc65d171 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Wed, 19 Aug 2015 17:36:53 +0200 Subject: [PATCH 2/7] Some refinements: - only show the bigtext notification if the device has set extended battery info - custom icon for the low battery notification (with license information) - show device name in the notification - set the notification to high priority - the battery threshold is now set in GBDevice --- LICENSE.artwork | 5 ++++- .../GBDeviceEventBatteryInfo.java | 9 ++++++++- .../gadgetbridge/impl/GBDevice.java | 11 +++++++++++ .../service/AbstractDeviceSupport.java | 11 ++++++----- .../freeyourgadget/gadgetbridge/util/GB.java | 18 +++++++++++------- .../ic_notification_low_battery.png | Bin 0 -> 174 bytes .../ic_notification_low_battery.png | Bin 0 -> 151 bytes .../ic_notification_low_battery.png | Bin 0 -> 165 bytes .../ic_notification_low_battery.png | Bin 0 -> 217 bytes app/src/main/res/values/strings.xml | 2 +- 10 files changed, 41 insertions(+), 15 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/ic_notification_low_battery.png create mode 100644 app/src/main/res/drawable-mdpi/ic_notification_low_battery.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_notification_low_battery.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_notification_low_battery.png diff --git a/LICENSE.artwork b/LICENSE.artwork index 3d8766be..5fa78b05 100644 --- a/LICENSE.artwork +++ b/LICENSE.artwork @@ -1,10 +1,13 @@ The following artwork is licensed under the following licenses Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0): - ic_device_pebble.png (by xphnx) + ic_device_pebble.png (by 9) ic_device_miband.png (by xphnx) ic_activitytracker.png (by xphnx) ic_watchface.png (by xphnx) Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0): "GET IT ON F-Droid" button by Laura Kalbag. Source: https://ind.ie/about/blog/f-droid-button/ + +Creative Commons Attribution 3.0 Unported license (CC BY-3.0): + ic_notification_battery_low.png by Picol.org. Source: https://commons.wikimedia.org/wiki/File:Battery_1_Picol_icon.svg diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java index 2bc311af..78c31591 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java @@ -4,7 +4,7 @@ package nodomain.freeyourgadget.gadgetbridge.deviceevents; import java.util.GregorianCalendar; public class GBDeviceEventBatteryInfo extends GBDeviceEvent { - public GregorianCalendar lastChargeTime; + public GregorianCalendar lastChargeTime= null; public BatteryState state = BatteryState.UNKNOWN; //TODO: I think the string should be deprecated in favor of the Enum above public String status; @@ -22,4 +22,11 @@ public class GBDeviceEventBatteryInfo extends GBDeviceEvent { CHARGE_LOW, CHARGING, } + + public boolean extendedInfoAvailable() { + if (numCharges != -1 && lastChargeTime != null) { + return true; + } + return false; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java index bf2e213e..5c7a346e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java @@ -30,6 +30,7 @@ public class GBDevice implements Parcelable { private static final Logger LOG = LoggerFactory.getLogger(GBDevice.class); public static final short RSSI_UNKNOWN = 0; public static final short BATTERY_UNKNOWN = -1; + private static final short BATTERY_THRESHOLD_PERCENT = 10; public static final String EXTRA_DEVICE = "device"; private final String mName; private final String mAddress; @@ -38,6 +39,7 @@ public class GBDevice implements Parcelable { private String mHardwareVersion = null; private State mState = State.NOT_CONNECTED; private short mBatteryLevel = BATTERY_UNKNOWN; + private short mBatteryThresholdPercent = BATTERY_THRESHOLD_PERCENT; //TODO: get rid of String mBatteryStatus in favor of Enum mBatteryState private String mBatteryStatus; private short mRssi = RSSI_UNKNOWN; @@ -293,6 +295,15 @@ public class GBDevice implements Parcelable { mBatteryStatus = batteryStatus; } + + public short getBatteryThresholdPercent() { + return mBatteryThresholdPercent; + } + + public void setBatteryThresholdPercent(short batteryThresholdPercent) { + this.mBatteryThresholdPercent = batteryThresholdPercent; + } + @Override public String toString() { return "Device " + getName() + ", " + getAddress() + ", " + getStateString(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index 5783aec3..037a12f2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -230,12 +230,13 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { gbDevice.setBatteryLevel(deviceEvent.level); gbDevice.setBatteryStatus(deviceEvent.status); - - //TODO: maybe switch to a device-dependent threshold - if (deviceEvent.level < 10) { - GB.updateBatteryNotification(deviceEvent.level, - context.getString(R.string.notif_battery_low_bigtext_last_charge_time, DateFormat.getDateTimeInstance().format(deviceEvent.lastChargeTime.getTime()).toString()) + + if (deviceEvent.level <= gbDevice.getBatteryThresholdPercent()) { + GB.updateBatteryNotification(context.getString(R.string.notif_battery_low_percent, gbDevice.getName(), deviceEvent.level), + deviceEvent.extendedInfoAvailable() ? + context.getString(R.string.notif_battery_low_percent, gbDevice.getName(), deviceEvent.level) + "\n" + + context.getString(R.string.notif_battery_low_bigtext_last_charge_time, DateFormat.getDateTimeInstance().format(deviceEvent.lastChargeTime.getTime()).toString()) + context.getString(R.string.notif_battery_low_bigtext_number_of_charges, deviceEvent.numCharges) + : "" , context); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java index 4d624121..fb1f4bca 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java @@ -300,7 +300,7 @@ public class GB { nm.notify(NOTIFICATION_ID_INSTALL, notification); } - private static Notification createBatteryNotification(int level, String text, Context context) { + private static Notification createBatteryNotification(String text, String bigText, Context context) { Intent notificationIntent = new Intent(context, ControlCenter.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); @@ -308,18 +308,22 @@ public class GB { notificationIntent, 0); NotificationCompat.Builder nb = new NotificationCompat.Builder(context) - .setContentTitle(context.getString(R.string.notif_battery_low_title)) - .setContentText(context.getString(R.string.notif_battery_low_percent, level)) + .setContentTitle( context.getString(R.string.notif_battery_low_title)) + .setContentText(text) .setContentIntent(pendingIntent) - .setSmallIcon(R.drawable.ic_notification) - .setStyle(new NotificationCompat.BigTextStyle().bigText(text)) + .setSmallIcon(R.drawable.ic_notification_low_battery) + .setPriority(NotificationCompat.PRIORITY_HIGH) .setOngoing(false); + if (bigText != null) { + nb.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText)); + } + return nb.build(); } - public static void updateBatteryNotification(int level, String text, Context context) { - Notification notification = createBatteryNotification(level, text, context); + public static void updateBatteryNotification(String text, String bigText, Context context) { + Notification notification = createBatteryNotification(text, bigText, context); NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); nm.notify(NOTIFICATION_ID_LOW_BATTERY, notification); diff --git a/app/src/main/res/drawable-hdpi/ic_notification_low_battery.png b/app/src/main/res/drawable-hdpi/ic_notification_low_battery.png new file mode 100644 index 0000000000000000000000000000000000000000..dad13ba6e3b0f4c85a82556e27ec854fcda88b96 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBN}1CrGd^P7vv73N&yz z`2YX^>C7MNs*;@ecKx4!t|5Y5l&O$`x6ouIpV5NCO9BU8DJaz2N&WNjWoJBl(ZP8C z>`T_|Nnn3 zhdU0sJ!hHP{|kJO=y)I85Z}ymFujqfRdHfN661uu@?GaACo^7gm?6n_L&t%ANz{dg xCD#+LFm2LVkgIapX67a1#TU1&02!ylz)-Tu`g+cKLs_6r44$rjF6*2UngGMeHtYZZ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_notification_low_battery.png b/app/src/main/res/drawable-xhdpi/ic_notification_low_battery.png new file mode 100644 index 0000000000000000000000000000000000000000..f1aff36a375d7fe90eae6dc45cca179c94b05eec GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpUt98VX=kcwMxub<{@Fc5G!IAz+U zOOak1M7%rXY&sVy9H~i5c>i0W-Is%bp=afkNnVSW@kD$(X@CBgs)E^vC7*XN9^dr* zq$zV=Sw}weyek|#Cb4h`C^$4UXfpk>Q;k_H%Tn@x;Yam#atsU(x6P)fSgm1S6LK49 OFN3G6pUXO@geCyV{yXph literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_notification_low_battery.png b/app/src/main/res/drawable-xxhdpi/ic_notification_low_battery.png new file mode 100644 index 0000000000000000000000000000000000000000..60dacdf781a11b1574063cc18de04b9abf3d4689 GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!3p`yMLn>~)y|r7=!9m0!aH)nP zr&nN?pU47^My4rS%mi+KjGtrtS*dex=gjS0Oh6qB4eBidvn<|Tf9|nB@lS&T(^KJ$ zp38e{erYqC%K!KUnable to install the given firmware: it doesn\'t match your Pebble\'s hardware revision. Please wait while determining the installation status... Gadget battery Low! - Battery left: %s%% + %1$s battery left: %2$s%% Last charge: %s \n Number of charges: %s From a6b28a804cddfd035c7545d458e99a7b293b3579 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Wed, 19 Aug 2015 17:38:16 +0200 Subject: [PATCH 3/7] Fix typo (sorry xphnx!) --- LICENSE.artwork | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.artwork b/LICENSE.artwork index 5fa78b05..2d71011a 100644 --- a/LICENSE.artwork +++ b/LICENSE.artwork @@ -1,7 +1,7 @@ The following artwork is licensed under the following licenses Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0): - ic_device_pebble.png (by 9) + ic_device_pebble.png (by xphnx) ic_device_miband.png (by xphnx) ic_activitytracker.png (by xphnx) ic_watchface.png (by xphnx) From eb39ce93670a6d40ea65dd784da54724e97ea67f Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Fri, 21 Aug 2015 08:41:57 +0200 Subject: [PATCH 4/7] Further improvements: - append a string on the control center when the device is charging - battery status string is no more, welcome battery state enum - the notification will not be shown when the device is charging, even if the level is below threshold --- .../gadgetbridge/adapter/GBDeviceAdapter.java | 6 ++++ .../GBDeviceEventBatteryInfo.java | 11 +++---- .../gadgetbridge/impl/GBDevice.java | 16 +++++----- .../service/AbstractDeviceSupport.java | 8 +++-- .../service/devices/miband/BatteryInfo.java | 31 ++++++++++++------- .../service/devices/miband/MiBandSupport.java | 1 + app/src/main/res/values/strings.xml | 4 --- 7 files changed, 44 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java index e671360f..a92bbbdc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java @@ -11,6 +11,7 @@ import android.widget.TextView; import java.util.List; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.R; @@ -59,6 +60,11 @@ public class GBDeviceAdapter extends ArrayAdapter { short batteryLevel = device.getBatteryLevel(); if (batteryLevel != GBDevice.BATTERY_UNKNOWN) { batteryStatusLabel.setText("BAT: " + device.getBatteryLevel() + "%"); + GBDeviceEventBatteryInfo.BatteryState batteryState = device.getBatteryState(); + if (GBDeviceEventBatteryInfo.BatteryState.BATTERY_CHARGING.equals(batteryState) || + GBDeviceEventBatteryInfo.BatteryState.BATTERY_CHARGING_FULL.equals(batteryState)) { + batteryStatusLabel.append(" CHG"); + } } else { batteryStatusLabel.setText(""); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java index 78c31591..2fe75c16 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java @@ -6,8 +6,6 @@ import java.util.GregorianCalendar; public class GBDeviceEventBatteryInfo extends GBDeviceEvent { public GregorianCalendar lastChargeTime= null; public BatteryState state = BatteryState.UNKNOWN; - //TODO: I think the string should be deprecated in favor of the Enum above - public String status; public short level = 50; public int numCharges = -1; @@ -17,10 +15,11 @@ public class GBDeviceEventBatteryInfo extends GBDeviceEvent { public enum BatteryState { UNKNOWN, - CHARGE_FULL, - CHARGE_MEDIUM, - CHARGE_LOW, - CHARGING, + BATTERY_NORMAL, + BATTERY_LOW, + BATTERY_CHARGING, + BATTERY_CHARGING_FULL, + BATTERY_NOT_CHARGING_FULL } public boolean extendedInfoAvailable() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java index 5c7a346e..987d6586 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java @@ -9,6 +9,7 @@ import android.support.v4.content.LocalBroadcastManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo.BatteryState; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; @@ -42,6 +43,7 @@ public class GBDevice implements Parcelable { private short mBatteryThresholdPercent = BATTERY_THRESHOLD_PERCENT; //TODO: get rid of String mBatteryStatus in favor of Enum mBatteryState private String mBatteryStatus; + private BatteryState mBatteryState; private short mRssi = RSSI_UNKNOWN; private String mBusyTask; @@ -180,7 +182,7 @@ public class GBDevice implements Parcelable { private void unsetDynamicState() { setBatteryLevel(BATTERY_UNKNOWN); - setBatteryStatus(null); + setBatteryState(BatteryState.UNKNOWN); setFirmwareVersion(null); setRssi(RSSI_UNKNOWN); if (mBusyTask != null) { @@ -284,18 +286,14 @@ public class GBDevice implements Parcelable { } } - /** - * Returns a string representation of the battery state. - */ - public String getBatteryStatus() { - return mBatteryStatus != null ? mBatteryStatus : GBApplication.getContext().getString(R.string._unknown_); + public BatteryState getBatteryState() { + return mBatteryState; } - public void setBatteryStatus(String batteryStatus) { - mBatteryStatus = batteryStatus; + public void setBatteryState(BatteryState mBatteryState) { + this.mBatteryState = mBatteryState; } - public short getBatteryThresholdPercent() { return mBatteryThresholdPercent; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index 037a12f2..4e32f683 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -228,9 +228,13 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { Context context = getContext(); LOG.info("Got BATTERY_INFO device event"); gbDevice.setBatteryLevel(deviceEvent.level); - gbDevice.setBatteryStatus(deviceEvent.status); + gbDevice.setBatteryState(deviceEvent.state); - if (deviceEvent.level <= gbDevice.getBatteryThresholdPercent()) { + //show the notification if the battery level is below threshold and only if not connected to charger + if (deviceEvent.level <= gbDevice.getBatteryThresholdPercent() && + (GBDeviceEventBatteryInfo.BatteryState.BATTERY_LOW.equals(deviceEvent.state) || + GBDeviceEventBatteryInfo.BatteryState.BATTERY_NORMAL.equals(deviceEvent.state)) + ) { GB.updateBatteryNotification(context.getString(R.string.notif_battery_low_percent, gbDevice.getName(), deviceEvent.level), deviceEvent.extendedInfoAvailable() ? context.getString(R.string.notif_battery_low_percent, gbDevice.getName(), deviceEvent.level) + "\n" + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java index f21bef05..53bf6c5f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java @@ -3,10 +3,15 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband; import java.util.Calendar; import java.util.GregorianCalendar; -import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo.BatteryState; public class BatteryInfo extends AbstractInfo { + public static final byte DEVICE_BATTERY_NORMAL = 0; + public static final byte DEVICE_BATTERY_LOW = 1; + public static final byte DEVICE_BATTERY_CHARGING = 2; + public static final byte DEVICE_BATTERY_CHARGING_FULL = 3; + public static final byte DEVICE_BATTERY_CHARGE_OFF = 4; + public BatteryInfo(byte[] data) { super(data); } @@ -18,21 +23,23 @@ public class BatteryInfo extends AbstractInfo { return 50; // actually unknown } - public String getStatus() { + public BatteryState getState() { if (mData.length >= 10) { int value = mData[9]; switch (value) { - case 1: - return GBApplication.getContext().getString(R.string.battery_low); - case 2: - return GBApplication.getContext().getString(R.string.battery_medium); - case 3: - return GBApplication.getContext().getString(R.string.battery_full); - case 4: - return GBApplication.getContext().getString(R.string.battery_not_charging); + case DEVICE_BATTERY_NORMAL: + return BatteryState.BATTERY_NORMAL; + case DEVICE_BATTERY_LOW: + return BatteryState.BATTERY_LOW; + case DEVICE_BATTERY_CHARGING: + return BatteryState.BATTERY_CHARGING; + case DEVICE_BATTERY_CHARGING_FULL: + return BatteryState.BATTERY_CHARGING_FULL; + case DEVICE_BATTERY_CHARGE_OFF: + return BatteryState.BATTERY_NOT_CHARGING_FULL; } } - return GBApplication.getContext().getString(R.string._unknown_); + return BatteryState.UNKNOWN; } public GregorianCalendar getLastChargeTime() { 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 be9a5db9..db2afa64 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 @@ -737,6 +737,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { if (status == BluetoothGatt.GATT_SUCCESS) { BatteryInfo info = new BatteryInfo(value); batteryCmd.level = ((short) info.getLevelInPercent()); + batteryCmd.state = info.getState(); batteryCmd.lastChargeTime = info.getLastChargeTime(); batteryCmd.numCharges = info.getNumCharges(); handleGBDeviceEvent(batteryCmd); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4bd5358b..37490d5e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -74,10 +74,6 @@ tap a device to connect Cannot connect. BT address invalid? Gadgetbridge running - low - medium - full - not charging installing binary %1$d/%2$d installation failed! installation successful From 7923e153e6cb62b461274b1d20391f5027740c59 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Thu, 27 Aug 2015 11:50:31 +0200 Subject: [PATCH 5/7] Moved the enum to standalone in the model package. --- .../gadgetbridge/adapter/GBDeviceAdapter.java | 8 ++++---- .../deviceevents/GBDeviceEventBatteryInfo.java | 11 ++--------- .../freeyourgadget/gadgetbridge/impl/GBDevice.java | 2 +- .../gadgetbridge/model/BatteryState.java | 10 ++++++++++ .../gadgetbridge/service/AbstractDeviceSupport.java | 5 +++-- .../service/devices/miband/BatteryInfo.java | 2 +- 6 files changed, 21 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryState.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java index a92bbbdc..8cee27dc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java @@ -11,9 +11,9 @@ import android.widget.TextView; import java.util.List; -import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; public class GBDeviceAdapter extends ArrayAdapter { @@ -60,9 +60,9 @@ public class GBDeviceAdapter extends ArrayAdapter { short batteryLevel = device.getBatteryLevel(); if (batteryLevel != GBDevice.BATTERY_UNKNOWN) { batteryStatusLabel.setText("BAT: " + device.getBatteryLevel() + "%"); - GBDeviceEventBatteryInfo.BatteryState batteryState = device.getBatteryState(); - if (GBDeviceEventBatteryInfo.BatteryState.BATTERY_CHARGING.equals(batteryState) || - GBDeviceEventBatteryInfo.BatteryState.BATTERY_CHARGING_FULL.equals(batteryState)) { + BatteryState batteryState = device.getBatteryState(); + if (BatteryState.BATTERY_CHARGING.equals(batteryState) || + BatteryState.BATTERY_CHARGING_FULL.equals(batteryState)) { batteryStatusLabel.append(" CHG"); } } else { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java index 2fe75c16..9371000d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventBatteryInfo.java @@ -3,6 +3,8 @@ package nodomain.freeyourgadget.gadgetbridge.deviceevents; import java.util.GregorianCalendar; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; + public class GBDeviceEventBatteryInfo extends GBDeviceEvent { public GregorianCalendar lastChargeTime= null; public BatteryState state = BatteryState.UNKNOWN; @@ -13,15 +15,6 @@ public class GBDeviceEventBatteryInfo extends GBDeviceEvent { eventClass = EventClass.BATTERY_INFO; } - public enum BatteryState { - UNKNOWN, - BATTERY_NORMAL, - BATTERY_LOW, - BATTERY_CHARGING, - BATTERY_CHARGING_FULL, - BATTERY_NOT_CHARGING_FULL - } - public boolean extendedInfoAvailable() { if (numCharges != -1 && lastChargeTime != null) { return true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java index 987d6586..91a566b9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java @@ -9,7 +9,7 @@ import android.support.v4.content.LocalBroadcastManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo.BatteryState; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryState.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryState.java new file mode 100644 index 00000000..fb82100d --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryState.java @@ -0,0 +1,10 @@ +package nodomain.freeyourgadget.gadgetbridge.model; + +public enum BatteryState { + UNKNOWN, + BATTERY_NORMAL, + BATTERY_LOW, + BATTERY_CHARGING, + BATTERY_CHARGING_FULL, + BATTERY_NOT_CHARGING_FULL +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index 4e32f683..bc4b40a0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -22,6 +22,7 @@ import java.util.Date; import nodomain.freeyourgadget.gadgetbridge.activities.AppManagerActivity; import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsHost; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.service.receivers.GBCallControlReceiver; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; @@ -232,8 +233,8 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { //show the notification if the battery level is below threshold and only if not connected to charger if (deviceEvent.level <= gbDevice.getBatteryThresholdPercent() && - (GBDeviceEventBatteryInfo.BatteryState.BATTERY_LOW.equals(deviceEvent.state) || - GBDeviceEventBatteryInfo.BatteryState.BATTERY_NORMAL.equals(deviceEvent.state)) + (BatteryState.BATTERY_LOW.equals(deviceEvent.state) || + BatteryState.BATTERY_NORMAL.equals(deviceEvent.state)) ) { GB.updateBatteryNotification(context.getString(R.string.notif_battery_low_percent, gbDevice.getName(), deviceEvent.level), deviceEvent.extendedInfoAvailable() ? diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java index 53bf6c5f..64e0ac82 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java @@ -3,7 +3,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband; import java.util.Calendar; import java.util.GregorianCalendar; -import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo.BatteryState; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; public class BatteryInfo extends AbstractInfo { public static final byte DEVICE_BATTERY_NORMAL = 0; From 677e0808bf2a44242acebb765d97f6a1845aeb74 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Thu, 27 Aug 2015 13:12:09 +0200 Subject: [PATCH 6/7] Centralize the calendar conversion to/from byte array. --- .../devices/miband/MiBandCoordinator.java | 37 +++++++++++++++++++ .../service/devices/miband/BatteryInfo.java | 11 ++---- .../service/devices/miband/MiBandSupport.java | 30 +++++++-------- .../operations/FetchActivityOperation.java | 14 ++++--- 4 files changed, 64 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java index 3c33cb09..cdc69b05 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java @@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Calendar; +import java.util.GregorianCalendar; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; @@ -130,4 +131,40 @@ public class MiBandCoordinator implements DeviceCoordinator { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(GBApplication.getContext()); return Integer.parseInt(prefs.getString(MiBandConst.PREF_MIBAND_FITNESS_GOAL, "10000")); } + + /** + * uses the standard algorithm to convert bytes received from the MiBand to a Calendar object + * @param value + * @return + */ + public static GregorianCalendar rawBytesToCalendar(byte[] value) { + GregorianCalendar timestamp = new GregorianCalendar(); + + if (value.length == 6) { + timestamp.set(Calendar.YEAR, (2000 + value[0])); + timestamp.set(Calendar.MONTH, value[1]); + timestamp.set(Calendar.DATE, value[2]); + timestamp.set(Calendar.HOUR_OF_DAY, value[3]); + timestamp.set(Calendar.MINUTE, value[4]); + timestamp.set(Calendar.SECOND, value[5]); + } + + return timestamp; + } + + /** + * uses the standard algorithm to convert a Calendar object to a byte array to send to MiBand + * @param timestamp + * @return + */ + public static byte[] calendarToRawBytes(Calendar timestamp) { + return new byte[]{ + (byte) (timestamp.get(Calendar.YEAR) - 2000), + (byte) timestamp.get(Calendar.MONTH), + (byte) timestamp.get(Calendar.DATE), + (byte) timestamp.get(Calendar.HOUR_OF_DAY), + (byte) timestamp.get(Calendar.MINUTE), + (byte) timestamp.get(Calendar.SECOND) + }; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java index 64e0ac82..ece84e0f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java @@ -1,8 +1,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband; -import java.util.Calendar; import java.util.GregorianCalendar; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; public class BatteryInfo extends AbstractInfo { @@ -46,12 +46,9 @@ public class BatteryInfo extends AbstractInfo { GregorianCalendar lastCharge = new GregorianCalendar(); if (mData.length >= 10) { - lastCharge.set(Calendar.YEAR, (2000 + mData[1])); - lastCharge.set(Calendar.MONTH, mData[2]); - lastCharge.set(Calendar.DATE, mData[3]); - lastCharge.set(Calendar.HOUR_OF_DAY, mData[4]); - lastCharge.set(Calendar.MINUTE, mData[5]); - lastCharge.set(Calendar.SECOND, mData[6]); + lastCharge = MiBandCoordinator.rawBytesToCalendar(new byte[]{ + mData[1], mData[2], mData[3], mData[4], mData[5], mData[6] + }); } return lastCharge; 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 2b420a0b..a905befa 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 @@ -13,7 +13,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Calendar; import java.util.GregorianCalendar; import java.util.UUID; @@ -429,14 +428,14 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { * @param builder */ private MiBandSupport setCurrentTime(TransactionBuilder builder) { - Calendar now = GregorianCalendar.getInstance(); + byte[] nowBytes = MiBandCoordinator.calendarToRawBytes(GregorianCalendar.getInstance()); byte[] time = new byte[]{ - (byte) (now.get(Calendar.YEAR) - 2000), - (byte) now.get(Calendar.MONTH), - (byte) now.get(Calendar.DATE), - (byte) now.get(Calendar.HOUR_OF_DAY), - (byte) now.get(Calendar.MINUTE), - (byte) now.get(Calendar.SECOND), + nowBytes[0], + nowBytes[1], + nowBytes[2], + nowBytes[3], + nowBytes[4], + nowBytes[5], (byte) 0x0f, (byte) 0x0f, (byte) 0x0f, @@ -685,17 +684,18 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { * @param characteristic */ private void queueAlarm(Alarm alarm, TransactionBuilder builder, BluetoothGattCharacteristic characteristic) { - Calendar alarmCal = alarm.getAlarmCal(); + byte[] alarmCalBytes = MiBandCoordinator.calendarToRawBytes(alarm.getAlarmCal()); + byte[] alarmMessage = new byte[]{ (byte) MiBandService.COMMAND_SET_TIMER, (byte) alarm.getIndex(), (byte) (alarm.isEnabled() ? 1 : 0), - (byte) (alarmCal.get(Calendar.YEAR) - 2000), - (byte) alarmCal.get(Calendar.MONTH), - (byte) alarmCal.get(Calendar.DATE), - (byte) alarmCal.get(Calendar.HOUR_OF_DAY), - (byte) alarmCal.get(Calendar.MINUTE), - (byte) alarmCal.get(Calendar.SECOND), + alarmCalBytes[0], + alarmCalBytes[1], + alarmCalBytes[2], + alarmCalBytes[3], + alarmCalBytes[4], + alarmCalBytes[5], (byte) (alarm.isSmartWakeup() ? 30 : 0), (byte) alarm.getRepetitionMask() }; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java index cf05b1b3..28d0af5e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java @@ -19,6 +19,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEOperation; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; @@ -224,14 +225,15 @@ public class FetchActivityOperation extends AbstractBTLEOperation * @param bytesTransferred */ private void sendAckDataTransfer(Calendar time, int bytesTransferred) { + byte[] ackTime = MiBandCoordinator.calendarToRawBytes(time); byte[] ack = new byte[]{ MiBandService.COMMAND_CONFIRM_ACTIVITY_DATA_TRANSFER_COMPLETE, - (byte) (time.get(Calendar.YEAR) - 2000), - (byte) time.get(Calendar.MONTH), - (byte) time.get(Calendar.DATE), - (byte) time.get(Calendar.HOUR_OF_DAY), - (byte) time.get(Calendar.MINUTE), - (byte) time.get(Calendar.SECOND), + ackTime[0], + ackTime[1], + ackTime[2], + ackTime[3], + ackTime[4], + ackTime[5], (byte) (bytesTransferred & 0xff), (byte) (0xff & (bytesTransferred >> 8)) }; From cbea0feb9e72cfa0ff453719ca853d59140ad16f Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Fri, 28 Aug 2015 10:40:25 +0200 Subject: [PATCH 7/7] Centralize the calendar conversion to/from byte array take 2. Move to an independent class. --- .../devices/miband/MiBandCoordinator.java | 35 ---------------- .../devices/miband/MiBandDateConverter.java | 42 +++++++++++++++++++ .../service/devices/miband/BatteryInfo.java | 4 +- .../service/devices/miband/MiBandSupport.java | 5 ++- .../operations/FetchActivityOperation.java | 4 +- 5 files changed, 49 insertions(+), 41 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandDateConverter.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java index cdc69b05..eea1d008 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java @@ -132,39 +132,4 @@ public class MiBandCoordinator implements DeviceCoordinator { return Integer.parseInt(prefs.getString(MiBandConst.PREF_MIBAND_FITNESS_GOAL, "10000")); } - /** - * uses the standard algorithm to convert bytes received from the MiBand to a Calendar object - * @param value - * @return - */ - public static GregorianCalendar rawBytesToCalendar(byte[] value) { - GregorianCalendar timestamp = new GregorianCalendar(); - - if (value.length == 6) { - timestamp.set(Calendar.YEAR, (2000 + value[0])); - timestamp.set(Calendar.MONTH, value[1]); - timestamp.set(Calendar.DATE, value[2]); - timestamp.set(Calendar.HOUR_OF_DAY, value[3]); - timestamp.set(Calendar.MINUTE, value[4]); - timestamp.set(Calendar.SECOND, value[5]); - } - - return timestamp; - } - - /** - * uses the standard algorithm to convert a Calendar object to a byte array to send to MiBand - * @param timestamp - * @return - */ - public static byte[] calendarToRawBytes(Calendar timestamp) { - return new byte[]{ - (byte) (timestamp.get(Calendar.YEAR) - 2000), - (byte) timestamp.get(Calendar.MONTH), - (byte) timestamp.get(Calendar.DATE), - (byte) timestamp.get(Calendar.HOUR_OF_DAY), - (byte) timestamp.get(Calendar.MINUTE), - (byte) timestamp.get(Calendar.SECOND) - }; - } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandDateConverter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandDateConverter.java new file mode 100644 index 00000000..b356a207 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandDateConverter.java @@ -0,0 +1,42 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.miband; + +import java.util.Calendar; +import java.util.GregorianCalendar; + +public class MiBandDateConverter { + /** + * uses the standard algorithm to convert bytes received from the MiBand to a Calendar object + * @param value + * @return + */ + public static GregorianCalendar rawBytesToCalendar(byte[] value) { + GregorianCalendar timestamp = new GregorianCalendar(); + + if (value.length == 6) { + timestamp.set(Calendar.YEAR, (2000 + value[0])); + timestamp.set(Calendar.MONTH, value[1]); + timestamp.set(Calendar.DATE, value[2]); + timestamp.set(Calendar.HOUR_OF_DAY, value[3]); + timestamp.set(Calendar.MINUTE, value[4]); + timestamp.set(Calendar.SECOND, value[5]); + } + + return timestamp; + } + + /** + * uses the standard algorithm to convert a Calendar object to a byte array to send to MiBand + * @param timestamp + * @return + */ + public static byte[] calendarToRawBytes(Calendar timestamp) { + return new byte[]{ + (byte) (timestamp.get(Calendar.YEAR) - 2000), + (byte) timestamp.get(Calendar.MONTH), + (byte) timestamp.get(Calendar.DATE), + (byte) timestamp.get(Calendar.HOUR_OF_DAY), + (byte) timestamp.get(Calendar.MINUTE), + (byte) timestamp.get(Calendar.SECOND) + }; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java index ece84e0f..fa7d6e48 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java @@ -2,7 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband; import java.util.GregorianCalendar; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandDateConverter; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; public class BatteryInfo extends AbstractInfo { @@ -46,7 +46,7 @@ public class BatteryInfo extends AbstractInfo { GregorianCalendar lastCharge = new GregorianCalendar(); if (mData.length >= 10) { - lastCharge = MiBandCoordinator.rawBytesToCalendar(new byte[]{ + lastCharge = MiBandDateConverter.rawBytesToCalendar(new byte[]{ mData[1], mData[2], mData[3], mData[4], mData[5], mData[6] }); } 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 a905befa..9af6ec42 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 @@ -21,6 +21,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInf import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandDateConverter; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State; @@ -428,7 +429,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { * @param builder */ private MiBandSupport setCurrentTime(TransactionBuilder builder) { - byte[] nowBytes = MiBandCoordinator.calendarToRawBytes(GregorianCalendar.getInstance()); + byte[] nowBytes = MiBandDateConverter.calendarToRawBytes(GregorianCalendar.getInstance()); byte[] time = new byte[]{ nowBytes[0], nowBytes[1], @@ -684,7 +685,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { * @param characteristic */ private void queueAlarm(Alarm alarm, TransactionBuilder builder, BluetoothGattCharacteristic characteristic) { - byte[] alarmCalBytes = MiBandCoordinator.calendarToRawBytes(alarm.getAlarmCal()); + byte[] alarmCalBytes = MiBandDateConverter.calendarToRawBytes(alarm.getAlarmCal()); byte[] alarmMessage = new byte[]{ (byte) MiBandService.COMMAND_SET_TIMER, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java index 28d0af5e..e6f3959f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java @@ -19,7 +19,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandDateConverter; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEOperation; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; @@ -225,7 +225,7 @@ public class FetchActivityOperation extends AbstractBTLEOperation * @param bytesTransferred */ private void sendAckDataTransfer(Calendar time, int bytesTransferred) { - byte[] ackTime = MiBandCoordinator.calendarToRawBytes(time); + byte[] ackTime = MiBandDateConverter.calendarToRawBytes(time); byte[] ack = new byte[]{ MiBandService.COMMAND_CONFIRM_ACTIVITY_DATA_TRANSFER_COMPLETE, ackTime[0],