Browse Source

Move fake device offset to Mi Band 1 preferences, remove support for other devices

Reasons for removal:
- I doubt we honored the offset correctly for new features anyway that are available on newer devices
- Newer devices have a display always displaying the wrong time
tags/0.34.0
Andreas Shimokawa 4 months ago
parent
commit
16090f0e21

+ 1
- 1
app/build.gradle View File

@@ -68,7 +68,7 @@ dependencies {

implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "androidx.appcompat:appcompat:1.0.2"
implementation "androidx.preference:preference:1.0.0"
implementation "androidx.preference:preference:1.1.0-alpha05"
implementation "androidx.cardview:cardview:1.0.0"
implementation "androidx.recyclerview:recyclerview:1.0.0"
implementation "androidx.legacy:legacy-support-v4:1.0.0"

+ 2
- 0
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java View File

@@ -671,6 +671,7 @@ public static String packageNameToPebbleMsgSender(String packageName) {
switch (deviceType) {
case MIBAND:
deviceSharedPrefsEdit.putBoolean("low_latency_fw_update", prefs.getBoolean("mi_low_latency_fw_update", true));
deviceSharedPrefsEdit.putInt("device_time_offset_hours", prefs.getInt("mi_device_time_offset_hours", 0));
break;
case AMAZFITCOR:
displayItems = prefs.getStringSet("cor_display_items", null);
@@ -709,6 +710,7 @@ public static String packageNameToPebbleMsgSender(String packageName) {
editor.remove("disconnect_notification_start");
editor.remove("disconnect_notification_end");
editor.remove("mi_low_latency_fw_update");
editor.remove("mi_device_time_offset_hours");
editor.remove("mi2_do_not_disturb");
editor.remove("mi2_do_not_disturb_start");
editor.remove("mi2_do_not_disturb_end");

+ 13
- 0
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java View File

@@ -1,9 +1,12 @@
package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings;

import android.os.Bundle;
import android.text.InputType;
import android.widget.EditText;

import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import androidx.preference.EditTextPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;

@@ -269,6 +272,16 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat {
addPreferenceHandlerFor(PREF_SWIPE_UNLOCK);
addPreferenceHandlerFor(PREF_MI2_DATEFORMAT);
addPreferenceHandlerFor(HuamiConst.PREF_DISPLAY_ITEMS);

EditTextPreference pref = findPreference(MiBandConst.PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS);
if (pref != null) {
pref.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
@Override
public void onBindEditText(@NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
}
});
}
}

static DeviceSpecificSettingsFragment newInstance(String settingsFileSuffix, @NonNull int[] supportedSettings) {

+ 1
- 1
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandConst.java View File

@@ -39,7 +39,7 @@ public final class MiBandConst {
public static final String PREF_MIBAND_BUTTON_ACTION_DELAY = "mi_button_press_count_match_delay";
public static final String PREF_MIBAND_BUTTON_PRESS_BROADCAST = "mi_button_press_broadcast";
public static final String PREF_MIBAND_USE_HR_FOR_SLEEP_DETECTION = "mi_hr_sleep_detection";
public static final String PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS = "mi_device_time_offset_hours";
public static final String PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS = "device_time_offset_hours";
public static final String PREF_MI2_DATEFORMAT = "mi2_dateformat";
public static final String PREF_MI2_GOAL_NOTIFICATION = "mi2_goal_notification";
public static final String PREF_MI2_DISPLAY_ITEM_CLOCK = "clock";

+ 5
- 3
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java View File

@@ -22,6 +22,7 @@ import android.app.Activity;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.ScanFilter;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.ParcelUuid;
@@ -236,8 +237,8 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator {
return location;
}

public static int getDeviceTimeOffsetHours() throws IllegalArgumentException {
Prefs prefs = GBApplication.getPrefs();
public static int getDeviceTimeOffsetHours(String deviceAddress) throws IllegalArgumentException {
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress));
return prefs.getInt(MiBandConst.PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS, 0);
}

@@ -260,7 +261,8 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator {
@Override
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[]{
R.xml.devicesettings_lowlatency_fwupdate
R.xml.devicesettings_lowlatency_fwupdate,
R.xml.devicesettings_fake_timeoffset
};
}


+ 6
- 6
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandDateConverter.java View File

@@ -34,9 +34,9 @@ public class MiBandDateConverter {
* @param value
* @return
*/
public static GregorianCalendar rawBytesToCalendar(byte[] value) {
public static GregorianCalendar rawBytesToCalendar(byte[] value, String deviceAddress) {
if (value.length == 6) {
return rawBytesToCalendar(value, 0);
return rawBytesToCalendar(value, 0, deviceAddress);
}
return createCalendar();
}
@@ -47,7 +47,7 @@ public class MiBandDateConverter {
* @param value
* @return
*/
public static GregorianCalendar rawBytesToCalendar(byte[] value, int offset) {
public static GregorianCalendar rawBytesToCalendar(byte[] value, int offset, String deviceAddress) {
if (value.length - offset >= 6) {
GregorianCalendar timestamp = new GregorianCalendar(
value[offset] + 2000,
@@ -57,7 +57,7 @@ public class MiBandDateConverter {
value[offset + 4],
value[offset + 5]);

int offsetInHours = MiBandCoordinator.getDeviceTimeOffsetHours();
int offsetInHours = MiBandCoordinator.getDeviceTimeOffsetHours(deviceAddress);
if(offsetInHours != 0)
timestamp.add(Calendar.HOUR_OF_DAY,-offsetInHours);

@@ -73,7 +73,7 @@ public class MiBandDateConverter {
* @param timestamp
* @return
*/
public static byte[] calendarToRawBytes(Calendar timestamp) {
public static byte[] calendarToRawBytes(Calendar timestamp, String deviceAddress) {

// The mi-band device currently records sleep
// only if it happens after 10pm and before 7am.
@@ -82,7 +82,7 @@ public class MiBandDateConverter {
// If you usually sleep, say, from 6am to 2pm, set the
// shift to -8, so at 6am the device thinks it's still 10pm
// of the day before.
int offsetInHours = MiBandCoordinator.getDeviceTimeOffsetHours();
int offsetInHours = MiBandCoordinator.getDeviceTimeOffsetHours(deviceAddress);
if(offsetInHours != 0)
timestamp.add(Calendar.HOUR_OF_DAY,offsetInHours);


+ 3
- 42
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLETypeConversions.java View File

@@ -40,22 +40,7 @@ public class BLETypeConversions {
* @return
* @see GattCharacteristic#UUID_CHARACTERISTIC_CURRENT_TIME
*/
public static byte[] calendarToRawBytes(Calendar timestamp, boolean honorDeviceTimeOffset) {

// The mi-band device currently records sleep
// only if it happens after 10pm and before 7am.
// The offset is used to trick the device to record sleep
// in non-standard hours.
// If you usually sleep, say, from 6am to 2pm, set the
// shift to -8, so at 6am the device thinks it's still 10pm
// of the day before.
if (honorDeviceTimeOffset) {
int offsetInHours = MiBandCoordinator.getDeviceTimeOffsetHours();
if (offsetInHours != 0) {
timestamp.add(Calendar.HOUR_OF_DAY, offsetInHours);
}
}

public static byte[] calendarToRawBytes(Calendar timestamp) {
// MiBand2:
// year,year,month,dayofmonth,hour,minute,second,dayofweek,0,0,tz

@@ -78,25 +63,9 @@ public class BLETypeConversions {
/**
* Similar to calendarToRawBytes, but only up to (and including) the MINUTES.
* @param timestamp
* @param honorDeviceTimeOffset
* @return
*/
public static byte[] shortCalendarToRawBytes(Calendar timestamp, boolean honorDeviceTimeOffset) {

// The mi-band device currently records sleep
// only if it happens after 10pm and before 7am.
// The offset is used to trick the device to record sleep
// in non-standard hours.
// If you usually sleep, say, from 6am to 2pm, set the
// shift to -8, so at 6am the device thinks it's still 10pm
// of the day before.
if (honorDeviceTimeOffset) {
int offsetInHours = MiBandCoordinator.getDeviceTimeOffsetHours();
if (offsetInHours != 0) {
timestamp.add(Calendar.HOUR_OF_DAY, offsetInHours);
}
}

public static byte[] shortCalendarToRawBytes(Calendar timestamp) {
// MiBand2:
// year,year,month,dayofmonth,hour,minute

@@ -136,7 +105,7 @@ public class BLETypeConversions {
* @param value
* @return
*/
public static GregorianCalendar rawBytesToCalendar(byte[] value, boolean honorDeviceTimeOffset) {
public static GregorianCalendar rawBytesToCalendar(byte[] value) {
if (value.length >= 7) {
int year = toUint16(value[0], value[1]);
GregorianCalendar timestamp = new GregorianCalendar(
@@ -153,14 +122,6 @@ public class BLETypeConversions {
timeZone.setRawOffset(value[7] * 15 * 60 * 1000);
timestamp.setTimeZone(timeZone);
}

if (honorDeviceTimeOffset) {
int offsetInHours = MiBandCoordinator.getDeviceTimeOffsetHours();
if (offsetInHours != 0) {
timestamp.add(Calendar.HOUR_OF_DAY,-offsetInHours);
}
}

return timestamp;
}


+ 1
- 1
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiBatteryInfo.java View File

@@ -95,7 +95,7 @@ public class HuamiBatteryInfo extends AbstractInfo {
if (mData.length >= 18) {
lastCharge = BLETypeConversions.rawBytesToCalendar(new byte[]{
mData[10], mData[11], mData[12], mData[13], mData[14], mData[15], mData[16], mData[17]
}, true);
});
}

return lastCharge;

+ 3
- 3
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java View File

@@ -237,9 +237,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
public byte[] getTimeBytes(Calendar calendar, TimeUnit precision) {
byte[] bytes;
if (precision == TimeUnit.MINUTES) {
bytes = BLETypeConversions.shortCalendarToRawBytes(calendar, true);
bytes = BLETypeConversions.shortCalendarToRawBytes(calendar);
} else if (precision == TimeUnit.SECONDS) {
bytes = BLETypeConversions.calendarToRawBytes(calendar, true);
bytes = BLETypeConversions.calendarToRawBytes(calendar);
} else {
throw new IllegalArgumentException("Unsupported precision, only MINUTES and SECONDS are supported till now");
}
@@ -251,7 +251,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}

public Calendar fromTimeBytes(byte[] bytes) {
GregorianCalendar timestamp = BLETypeConversions.rawBytesToCalendar(bytes, true);
GregorianCalendar timestamp = BLETypeConversions.rawBytesToCalendar(bytes);
return timestamp;
}


+ 4
- 3
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/BatteryInfo.java View File

@@ -59,13 +59,14 @@ public class BatteryInfo extends AbstractInfo {
return BatteryState.UNKNOWN;
}

public GregorianCalendar getLastChargeTime() {
public GregorianCalendar getLastChargeTime(String deviceAddress) {
GregorianCalendar lastCharge = MiBandDateConverter.createCalendar();

if (mData.length >= 10) {
lastCharge = MiBandDateConverter.rawBytesToCalendar(new byte[]{
mData[1], mData[2], mData[3], mData[4], mData[5], mData[6]
});
mData[1], mData[2], mData[3], mData[4], mData[5], mData[6]},
deviceAddress
);
}

return lastCharge;

+ 4
- 4
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java View File

@@ -625,7 +625,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
Calendar now = GregorianCalendar.getInstance();
Date date = now.getTime();
LOG.info("Sending current time to Mi Band: " + DateTimeUtils.formatDate(date) + " (" + date.toGMTString() + ")");
byte[] nowBytes = MiBandDateConverter.calendarToRawBytes(now);
byte[] nowBytes = MiBandDateConverter.calendarToRawBytes(now, gbDevice.getAddress());
byte[] time = new byte[]{
nowBytes[0],
nowBytes[1],
@@ -943,7 +943,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {

public void logDate(byte[] value, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
GregorianCalendar calendar = MiBandDateConverter.rawBytesToCalendar(value);
GregorianCalendar calendar = MiBandDateConverter.rawBytesToCalendar(value, gbDevice.getAddress());
LOG.info("Got Mi Band Date: " + DateTimeUtils.formatDateTime(calendar.getTime()));
} else {
logMessageContent(value);
@@ -1134,7 +1134,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
* @param characteristic
*/
private void queueAlarm(Alarm alarm, TransactionBuilder builder, BluetoothGattCharacteristic characteristic) {
byte[] alarmCalBytes = MiBandDateConverter.calendarToRawBytes(AlarmUtils.toCalendar(alarm));
byte[] alarmCalBytes = MiBandDateConverter.calendarToRawBytes(AlarmUtils.toCalendar(alarm), gbDevice.getAddress());

byte[] alarmMessage = new byte[]{
MiBandService.COMMAND_SET_TIMER,
@@ -1172,7 +1172,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
BatteryInfo info = new BatteryInfo(value);
batteryCmd.level = ((short) info.getLevelInPercent());
batteryCmd.state = info.getState();
batteryCmd.lastChargeTime = info.getLastChargeTime();
batteryCmd.lastChargeTime = info.getLastChargeTime(gbDevice.getAddress());
batteryCmd.numCharges = info.getNumCharges();
handleGBDeviceEvent(batteryCmd);
}

+ 2
- 2
app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/operations/FetchActivityOperation.java View File

@@ -254,7 +254,7 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
// byte 0 is the data type: 1 means that each minute is represented by a triplet of bytes
int dataType = value[0];
// byte 1 to 6 represent a timestamp
GregorianCalendar timestamp = MiBandDateConverter.rawBytesToCalendar(value, 1);
GregorianCalendar timestamp = MiBandDateConverter.rawBytesToCalendar(value, 1, getDevice().getAddress());

// counter of all data held by the band
int totalDataToRead = (value[7] & 0xff) | ((value[8] & 0xff) << 8);
@@ -405,7 +405,7 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
* @param bytesTransferred
*/
private void sendAckDataTransfer(Calendar time, int bytesTransferred) {
byte[] ackTime = MiBandDateConverter.calendarToRawBytes(time);
byte[] ackTime = MiBandDateConverter.calendarToRawBytes(time, getDevice().getAddress());
Prefs prefs = GBApplication.getPrefs();

byte[] ackChecksum = new byte[]{

+ 8
- 0
app/src/main/res/xml/devicesettings_fake_timeoffset.xml View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference
android:defaultValue="0"
android:key="device_time_offset_hours"
android:maxLength="2"
android:title="@string/miband_prefs_device_time_offset_hours" />
</androidx.preference.PreferenceScreen>

+ 0
- 7
app/src/main/res/xml/miband_preferences.xml View File

@@ -106,13 +106,6 @@
android:summary="%s"
android:title="@string/prefs_title_heartrate_measurement_interval" />

<EditTextPreference
android:defaultValue="0"
android:inputType="numberSigned"
android:key="mi_device_time_offset_hours"
android:maxLength="2"
android:title="@string/miband_prefs_device_time_offset_hours" />

<PreferenceScreen
android:persistent="false"
android:title="@string/mi2_prefs_activate_display_on_lift">

+ 4
- 4
app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/BLETypeConversionsTest.java View File

@@ -17,8 +17,8 @@ public class BLETypeConversionsTest extends TestBase {
byte[] received = new byte[] {
(byte) 0xe1, 0x07, 0x0a, 0x1c, 0x17, 0x1c, 0x00, 0x04
};
GregorianCalendar calRequested = BLETypeConversions.rawBytesToCalendar(requested, false);
GregorianCalendar calReceived = BLETypeConversions.rawBytesToCalendar(received, false);
GregorianCalendar calRequested = BLETypeConversions.rawBytesToCalendar(requested);
GregorianCalendar calReceived = BLETypeConversions.rawBytesToCalendar(received);

assertTrue(calRequested.getTime().equals(calReceived.getTime()));
}
@@ -31,8 +31,8 @@ public class BLETypeConversionsTest extends TestBase {
byte[] received = new byte[] {
(byte) 0xe1,0x07,0x0a,0x09,0x10,0x23,0x00,0x04
};
GregorianCalendar calRequested = BLETypeConversions.rawBytesToCalendar(requested, false);
GregorianCalendar calReceived = BLETypeConversions.rawBytesToCalendar(received, false);
GregorianCalendar calRequested = BLETypeConversions.rawBytesToCalendar(requested);
GregorianCalendar calReceived = BLETypeConversions.rawBytesToCalendar(received);

assertTrue(calRequested.getTime().equals(calReceived.getTime()));
}

Loading…
Cancel
Save