diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c0b2ca2..7e12b00c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ###Changelog +####Version next +* Miband: allow the transfer of activity data without clearing MiBand's memory + ####Version 0.5.3 * Pebble: For generic notifications, support dismissing individual notficications and "Open on Phone" feature (OG & PT) * Pebble: Allow to treat K9 notifcations as generic notifications (if notification mode is set to never) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java index dc51417a..aca51f45 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java @@ -120,10 +120,16 @@ public class AbstractSettingsActivity extends PreferenceActivity { preference.setOnPreferenceChangeListener(listener); // Trigger the listener immediately with the preference's current value. - listener.updateSummary(preference, - PreferenceManager - .getDefaultSharedPreferences(preference.getContext()) - .getString(preference.getKey(), "")); + try { + listener.updateSummary(preference, + PreferenceManager + .getDefaultSharedPreferences(preference.getContext()) + .getString(preference.getKey(), "")); + } catch (ClassCastException cce) { + //the preference is not a string, use the provided summary + //TODO: it shows true/false instead of the xml summary + listener.updateSummary(preference, preference.getSummary()); + } } @Override 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 10f84444..32b7c78c 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 @@ -17,6 +17,8 @@ public final class MiBandConst { public static final String PREF_MIBAND_ADDRESS = "development_miaddr"; // FIXME: should be prefixed mi_ public static final String PREF_MIBAND_ALARMS = "mi_alarms"; public static final String PREF_MIBAND_FITNESS_GOAL = "mi_fitness_goal"; + public static final String PREF_MIBAND_DONT_ACK_TRANSFER = "mi_dont_ack_transfer"; + public static final String ORIGIN_SMS = "sms"; public static final String ORIGIN_INCOMING_CALL = "incoming_call"; 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 c6a5f503..fd16cf35 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 @@ -16,6 +16,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.OR import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_SMS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_ADDRESS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_FITNESS_GOAL; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_DONT_ACK_TRANSFER; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_WEARSIDE; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_USER_ALIAS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_USER_GENDER; @@ -58,6 +59,7 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity { PREF_MIBAND_WEARSIDE, PREF_MIBAND_ADDRESS, PREF_MIBAND_FITNESS_GOAL, + PREF_MIBAND_DONT_ACK_TRANSFER, getNotificationPrefKey(VIBRATION_PROFILE, ORIGIN_SMS), getNotificationPrefKey(VIBRATION_COUNT, ORIGIN_SMS), getNotificationPrefKey(VIBRATION_PROFILE, ORIGIN_INCOMING_CALL), diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandService.java index 9addf457..3d34b439 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandService.java @@ -103,6 +103,8 @@ public class MiBandService { public static final byte NOTIFY_STATUS_MOTOR_TEST = 0x16; + // 0x18 is returned when we cancel data sync, perhaps is an ack for this message + public static final byte NOTIFY_UNKNOWN = -0x1; public static final int NOTIFY_PAIR_CANCEL = 0xef; @@ -148,6 +150,8 @@ public class MiBandService { public static final byte COMMAND_SET_WEAR_LOCATION = 0xf; + public static final byte COMMAND_STOP_SYNC_DATA = 0x11; + public static final byte COMMAND_STOP_MOTOR_VIBRATE = 0x13; /* FURTHER COMMANDS: unchecked therefore left commented @@ -160,8 +164,6 @@ public class MiBandService { public static final COMMAND_SET_REALTIME_STEP = 0x10t - public static final COMMAND_STOP_SYNC_DATA = 0x11t - public static final byte COMMAND_GET_SENSOR_DATA = 0x12t */ 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 d7a02905..cdf19128 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 @@ -2,7 +2,9 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; +import android.content.SharedPreferences; import android.database.sqlite.SQLiteDatabase; +import android.preference.PreferenceManager; import android.widget.Toast; import org.slf4j.Logger; @@ -19,6 +21,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.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandDateConverter; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEOperation; @@ -224,6 +227,18 @@ public class FetchActivityOperation extends AbstractBTLEOperation */ private void sendAckDataTransfer(Calendar time, int bytesTransferred) { byte[] ackTime = MiBandDateConverter.calendarToRawBytes(time); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(GBApplication.getContext()); + + byte[] ackChecksum = new byte[]{ + (byte) (bytesTransferred & 0xff), + (byte) (0xff & (bytesTransferred >> 8)) + }; + if (prefs.getBoolean(MiBandConst.PREF_MIBAND_DONT_ACK_TRANSFER, false)) { + ackChecksum = new byte[]{ + (byte) (~bytesTransferred & 0xff), + (byte) (0xff & (~bytesTransferred >> 8)) + }; + } byte[] ack = new byte[]{ MiBandService.COMMAND_CONFIRM_ACTIVITY_DATA_TRANSFER_COMPLETE, ackTime[0], @@ -232,8 +247,8 @@ public class FetchActivityOperation extends AbstractBTLEOperation ackTime[3], ackTime[4], ackTime[5], - (byte) (bytesTransferred & 0xff), - (byte) (0xff & (bytesTransferred >> 8)) + ackChecksum[0], + ackChecksum[1] }; try { TransactionBuilder builder = performInitialized("send acknowledge"); @@ -246,6 +261,12 @@ public class FetchActivityOperation extends AbstractBTLEOperation //The last data chunk sent by the miband has always length 0. //When we ack this chunk, the transfer is done. if (getDevice().isBusy() && bytesTransferred == 0) { + //if we are not clearing miband's data, we have to stop the sync + if (prefs.getBoolean(MiBandConst.PREF_MIBAND_DONT_ACK_TRANSFER, false)) { + builder = performInitialized("send acknowledge"); + builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), new byte[]{MiBandService.COMMAND_STOP_SYNC_DATA}); + builder.queue(getQueue()); + } handleActivityFetchFinish(); } } catch (IOException ex) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 84da3389..781c6a4f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -187,4 +187,6 @@ Steps Live Activity Steps today, target: %1$s + Do not ack activity data transfer + If the activity data are not acked to the band, they will not be cleared. Useful if GB is used together with other apps. diff --git a/app/src/main/res/xml/miband_preferences.xml b/app/src/main/res/xml/miband_preferences.xml index 5fbbb386..ff5be814 100644 --- a/app/src/main/res/xml/miband_preferences.xml +++ b/app/src/main/res/xml/miband_preferences.xml @@ -164,5 +164,10 @@ android:key="development_miaddr" android:maxLength="17" android:title="@string/pref_title_development_miaddr" /> + \ No newline at end of file