From 43d55b9ac0a84e4b1389a073ed6cd5f02c272e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Fri, 9 Feb 2018 06:55:30 +0100 Subject: [PATCH 001/211] =?UTF-8?q?device,=20System=20Weather,=20Norwegian?= =?UTF-8?q?=20bokm=C3=A5l,=20Android,=20.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/values/strings.xml | 47 +++++++++++++++-------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4bd05160d..161cd9920 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,7 +8,7 @@ Quit Donate Synchronize - Find lost Device + Find lost device Take Screenshot Connect Disconnect @@ -38,9 +38,9 @@ Deactivate Activate HRM Deactivate HRM - Activate system weather app - Deactivate system weather app - Install the weather notification app + Activate System Weather app + Deactivate System Weather app + Install the Weather Notification app Configure Move to top @@ -52,19 +52,19 @@ FW/App installer - You are about to install firmware %s instead of the one currently on your Mi Band. + You are about to install the %s firmware instead of the one currently on your Mi Band. You are about to install the %s firmware on your Amazfit Bip.\n\nPlease make sure to install the .fw file, then the .res file, and finally the .gps file. Your watch will reboot after installing the .fw file.\n\nNote: You do not have to install .res and .gps if these files are exactly the same as the ones previously installed.\n\nPROCEED AT YOUR OWN RISK! You are about to install the %s firmware on your Amazfit Cor.\n\nPlease make sure to install the .fw file, and after that the .res file. Your watch will reboot after installing the .fw file.\n\nNote: You do not have to install .res if it is exactly the same as the one previously installed.\n\nUNTESTED, MAY BRICK YOUR DEVICE, PROCEED AT YOUR OWN RISK! You are about to install the %1$s and %2$s firmware, instead of the ones currently on your Mi Band. This firmware has been tested and is known to be compatible with Gadgetbridge. "This firmware is untested and may not be compatible with Gadgetbridge.\n\nYou are DISCOURAGED from flashing it onto your Mi Band!" - If you still want to proceed and things continue to work properly afterwards, please tell the Gadgetbridge developers to whitelist the %s firmware version + If you still want to proceed and things continue to work properly afterwards, please tell the Gadgetbridge developers to whitelist the %s firmware version. Settings General settings - Connect to device when Bluetooth turned on + Connect to Gadgetbridge device when Bluetooth is turned on Start automatically Reconnect automatically Preferred Audioplayer @@ -73,7 +73,7 @@ Date and Time Sync time - Sync time to device when connecting, and when time or time zone changes on Android + Sync time to Gadgetbridge device when connecting, and when time or time zone changes on Android device Theme Light @@ -90,11 +90,11 @@ Phone Calls SMS Pebble Messages - Support for applications which send notifications to the Pebble via PebbleKit. + Support for apps that send notifications to the Pebble via PebbleKit. Generic notification support …also when screen is on Do Not Disturb - Stop unwanted notifications from being sent in Do Not Disturb mode + Unwanted notifications are stopped in this mode Transliteration Enable this if your device has no support for your language\'s font @@ -136,7 +136,7 @@ Disabling this will also stop the Pebble 2/LE to vibrate on outgoing calls Allow 3rd party Android App access - Enable experimental support for Android Apps using PebbleKit + Enable experimental support for Android apps using PebbleKit Pebble timeline Sunrise and sunset @@ -163,14 +163,14 @@ location acquired Force notification protocol - This option forces using the latest notification protocol depending on the firmware version. ENABLE ONLY IF YOU KNOW WHAT YOU ARE DOING! + This option forces using the latest notification protocol depending on the firmware version. KNOW WHAT YOU ARE DOING! Enable untested features - Enable features that are untested. ENABLE ONLY IF YOU KNOW WHAT YOU ARE DOING! + Enable untested features. KNOW WHAT YOU ARE DOING! Always prefer BLE Use experimental Pebble LE support for all Pebbles, instead of BT classic. This requires pairing to non LE first, and then Pebble LE Pebble 2/LE GATT MTU limit If your Pebble 2/Pebble LE does not work as expected, try this setting to limit the MTU (valid range 20–512) - Enable watch App logging + Enable watch app logging Will cause logs from watch apps to be logged by Gadgetbridge (requires reconnect) Prematurely ACK PebbleKit Will cause messages that are sent to external 3rd party apps to be acknowledged always and immediately @@ -270,7 +270,7 @@ SMS notification Vibration settings Generic notification - Email notification + E-mail notification Incoming call notification Chat Navigation @@ -301,8 +301,8 @@ Fri Sat Smart wakeup - There was an error setting the alarms, please try again! - Alarms sent to device! + There was an error setting the alarms, please try again. + Alarms sent to device. No data. Synchronize device? About to transfer %1$s of data starting from %2$s Daily step target @@ -350,7 +350,7 @@ If the activity data are not acked to the band, they will not be cleared. Useful if GB is used together with other apps. Will keep activity data on the Mi Band even after synchronization. Useful if GB is used together with other apps. Use low-latency mode for firmware flashing - This might help on devices where firmware flashing fails + This might help on devices where firmware flashing fails. Steps history Current steps/min @@ -398,7 +398,7 @@ Inactivity warnings The band will vibrate when you have been inactive for a while Inactivity threshold (in minutes) - Disable the inactivity warnings for a time interval + Disable inactivity warnings for a time interval Start time End time @@ -406,6 +406,7 @@ Simplified Chinese Traditional Chinese English + Norwegian Bokmål Spanish About to transfer data since %1$s @@ -435,10 +436,10 @@ Heart rate Store raw record in the database - If checked the data is stored \"as is\" and is available for later interpretation. NB: the database will be bigger in this case! + Stores the data \"as is\", increasing the database usage to allow for later interpretation. Database management Database management - The database operations use the following path on your device. \nThis path is accessible to other Android applications and your computer. \nExpect to find your exported database (or place the database you want to import) there: + The database operations use the following path on your device. \nThis path is accessible to other Android apps and your computer. \nExpect to find your exported database (or place the database you want to import) there: Legacy database delete Cannot access export path. Please contact the developers. Exported to: %1$s @@ -466,7 +467,7 @@ Pebble pairing - A pairing dialog will pop up on your Android device. If not, look in the notification drawer and accept the pairing request. Also accept it on your Pebble afterwards + A pairing dialog will pop up on your Android device. If not, look in the notification drawer and accept the pairing request. Also accept it on your Pebble afterwards. Make sure that this skin is enabled in the Weather Notification app to get weather information on your Pebble.\n\nNo configuration is needed here.\n\nYou can enable the system weather app of your Pebble from the app management.\n\nSupported watchfaces will show the weather automatically. Enable Bluetooth pairing @@ -503,7 +504,7 @@ Don\'t Pair - Open on phone + Open on Android device Mute Reply From 0e1331f17225d01b5a96b82339e025e18c423586 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 12 Jul 2018 15:45:00 +0300 Subject: [PATCH 002/211] ID115: declare device type --- .../nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java | 1 + app/src/main/res/values/strings.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index 78b79ab38..9b12abf24 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -46,6 +46,7 @@ public enum DeviceType { NO1F1(50, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_no1_f1), TECLASTH30(60, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled, R.string.devicetype_teclast_h30), XWATCH(70, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_xwatch), + ID115(80, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_id115), TEST(1000, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_test); private final int key; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1b574c87c..2ed11b1ac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -565,6 +565,7 @@ No.1 F1 Teclast H30 XWatch + ID115 Choose export location Gadgetbridge notifications From 26a1f97e4315e2feda31de20f80da1eb7f50548d Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 12 Jul 2018 15:47:08 +0300 Subject: [PATCH 003/211] ID115: coordinator --- .../devices/id115/ID115Constants.java | 33 +++++ .../devices/id115/ID115Coordinator.java | 135 ++++++++++++++++++ .../gadgetbridge/util/DeviceHelper.java | 2 + 3 files changed, 170 insertions(+) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java new file mode 100644 index 000000000..459425376 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java @@ -0,0 +1,33 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.id115; + +import java.util.UUID; + +import static nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport.BASE_UUID; + +public class ID115Constants { + public static final UUID UUID_SERVICE_ID115 = UUID.fromString(String.format(BASE_UUID, "0AF0")); + public static final UUID UUID_CHARACTERISTIC_WRITE_NORMAL = UUID.fromString(String.format(BASE_UUID, "0AF6")); + public static final UUID UUID_CHARACTERISTIC_NOTIFY_NORMAL = UUID.fromString(String.format(BASE_UUID, "0AF7")); + public static final UUID UUID_CHARACTERISTIC_WRITE_HEALTH = UUID.fromString(String.format(BASE_UUID, "0AF1")); + public static final UUID UUID_CHARACTERISTIC_NOTIFY_HEALTH = UUID.fromString(String.format(BASE_UUID, "0AF2")); + + public static final byte CMD_ID_WARE_UPDATE = 0x01; + public static final byte CMD_ID_GET_INFO = 0x02; + public static final byte CMD_ID_SETTINGS = 0x03; + public static final byte CMD_ID_BIND_UNBIND = 0x04; + public static final byte CMD_ID_NOTIFY = 0x05; + public static final byte CMD_ID_APP_CONTROL = 0x06; + public static final byte CMD_ID_BLE_CONTROL = 0x07; + public static final byte CMD_ID_HEALTH_DATA = 0x08; + public static final byte CMD_ID_DUMP_STACK = 0x20; + public static final byte CMD_ID_LOG = 0x21; + public static final byte CMD_ID_FACTORY = (byte)0xaa; + public static final byte CMD_ID_DEVICE_RESTART = (byte)0xf0; + + // CMD_ID_SETTINGS + public static final byte CMD_KEY_SET_TIME = 0x01; + public static final byte CMD_KEY_SET_DISPLAY_MODE = 0x2B; + + // CMD_ID_DEVICE_RESTART + public static final byte CMD_KEY_REBOOT = 0x01; +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java new file mode 100644 index 000000000..2a0524f16 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java @@ -0,0 +1,135 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.id115; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.bluetooth.le.ScanFilter; +import android.content.Context; +import android.net.Uri; +import android.os.Build; +import android.os.ParcelUuid; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import java.util.Collection; +import java.util.Collections; + +import nodomain.freeyourgadget.gadgetbridge.GBException; +import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; +import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.Device; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; +import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; + +public class ID115Coordinator extends AbstractDeviceCoordinator { + @NonNull + @Override + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public Collection createBLEScanFilters() { + ParcelUuid service = new ParcelUuid(ID115Constants.UUID_SERVICE_ID115); + ScanFilter filter = new ScanFilter.Builder().setServiceUuid(service).build(); + return Collections.singletonList(filter); + } + + @Override + protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException { + } + + @NonNull + @Override + public DeviceType getSupportedType(GBDeviceCandidate candidate) { + if (candidate.supportsService(ID115Constants.UUID_SERVICE_ID115)) { + return DeviceType.ID115; + } + return DeviceType.UNKNOWN; + } + + @Override + public int getBondingStyle(GBDevice deviceCandidate){ + return BONDING_STYLE_NONE; + } + + @Override + public DeviceType getDeviceType() { + return DeviceType.ID115; + } + + @Nullable + @Override + public Class getPairingActivity() { + return null; + } + + @Override + public boolean supportsActivityDataFetching() { + return false; + } + + @Override + public boolean supportsActivityTracking() { + return false; + } + + @Override + public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { + return null; + } + + @Override + public InstallHandler findInstallHandler(Uri uri, Context context) { + return null; + } + + @Override + public boolean supportsScreenshots() { + return false; + } + + @Override + public boolean supportsAlarmConfiguration() { + return false; + } + + @Override + public boolean supportsSmartWakeup(GBDevice device) { + return false; + } + + @Override + public boolean supportsHeartRateMeasurement(GBDevice device) { + return false; + } + + @Override + public String getManufacturer() { + return null; + } + + @Override + public boolean supportsAppsManagement() { + return false; + } + + @Override + public Class getAppsManagementActivity() { + return null; + } + + @Override + public boolean supportsCalendarEvents() { + return false; + } + + @Override + public boolean supportsRealtimeData() { + return false; + } + + @Override + public boolean supportsWeather() { + return false; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java index 1b3a6279d..12845d701 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java @@ -50,6 +50,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitcor.AmazfitCorC import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2.MiBand2Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2.MiBand2HRXCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband3.MiBand3Coordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.jyou.TeclastH30Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.liveview.LiveviewCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; @@ -211,6 +212,7 @@ public class DeviceHelper { result.add(new EXRIZUK8Coordinator()); result.add(new TeclastH30Coordinator()); result.add(new XWatchCoordinator()); + result.add(new ID115Coordinator()); return result; } From 814ca76733b01cf3bb367945a001928be5bfe588 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 12 Jul 2018 15:48:09 +0300 Subject: [PATCH 004/211] ID115: basic support --- .../service/DeviceSupportFactory.java | 5 + .../service/devices/id115/ID115Support.java | 260 ++++++++++++++++++ 2 files changed, 265 insertions(+) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java index 555bdaec4..23ec774b0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java @@ -31,6 +31,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitcor.AmazfitCorSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband3.MiBand3Support; +import nodomain.freeyourgadget.gadgetbridge.service.devices.id115.ID115Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.liveview.LiveviewSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSupport; @@ -151,6 +152,10 @@ public class DeviceSupportFactory { break; case XWATCH: deviceSupport = new ServiceDeviceSupport(new XWatchSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); + break; + case ID115: + deviceSupport = new ServiceDeviceSupport(new ID115Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); + break; } if (deviceSupport != null) { deviceSupport.setContext(gbDevice, mBtAdapter, mContext); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java new file mode 100644 index 000000000..e1e8af5e2 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -0,0 +1,260 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.id115; + +import android.bluetooth.BluetoothGattCharacteristic; +import android.net.Uri; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Constants; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.Alarm; +import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; +import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; +import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; +import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; +import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; +import nodomain.freeyourgadget.gadgetbridge.service.devices.no1f1.No1F1Support; + +public class ID115Support extends AbstractBTLEDeviceSupport { + private static final Logger LOG = LoggerFactory.getLogger(No1F1Support.class); + + public BluetoothGattCharacteristic normalWriteCharacteristic = null; + public BluetoothGattCharacteristic healthWriteCharacteristic = null; + + public ID115Support() { + super(LOG); + addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS); + addSupportedService(GattService.UUID_SERVICE_GENERIC_ATTRIBUTE); + addSupportedService(ID115Constants.UUID_SERVICE_ID115); + } + + @Override + protected TransactionBuilder initializeDevice(TransactionBuilder builder) { + normalWriteCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_WRITE_NORMAL); + healthWriteCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_WRITE_HEALTH); + + builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); + + setTime(builder) + .setDisplayMode(builder, false) + .setInitialized(builder); + + return builder; + } + + @Override + public boolean useAutoConnect() { + return true; + } + + @Override + public void onNotification(NotificationSpec notificationSpec) { + + } + + @Override + public void onDeleteNotification(int id) { + + } + + @Override + public void onSetTime() { + try { + TransactionBuilder builder = performInitialized("time"); + setTime(builder); + performConnected(builder.getTransaction()); + } catch(IOException e) { + } + } + + @Override + public void onSetAlarms(ArrayList alarms) { + + } + + @Override + public void onSetCallState(CallSpec callSpec) { + + } + + @Override + public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) { + + } + + @Override + public void onSetMusicState(MusicStateSpec stateSpec) { + + } + + @Override + public void onSetMusicInfo(MusicSpec musicSpec) { + + } + + @Override + public void onEnableRealtimeSteps(boolean enable) { + + } + + @Override + public void onInstallApp(Uri uri) { + + } + + @Override + public void onAppInfoReq() { + + } + + @Override + public void onAppStart(UUID uuid, boolean start) { + + } + + @Override + public void onAppDelete(UUID uuid) { + + } + + @Override + public void onAppConfiguration(UUID appUuid, String config, Integer id) { + + } + + @Override + public void onAppReorder(UUID[] uuids) { + + } + + @Override + public void onFetchRecordedData(int dataTypes) { + + } + + @Override + public void onReboot() { + try { + getQueue().clear(); + + TransactionBuilder builder = performInitialized("reboot"); + builder.write(normalWriteCharacteristic, new byte[] { + ID115Constants.CMD_ID_DEVICE_RESTART, ID115Constants.CMD_KEY_REBOOT + }); + performConnected(builder.getTransaction()); + } catch(Exception e) { + } + } + + @Override + public void onHeartRateTest() { + + } + + @Override + public void onEnableRealtimeHeartRateMeasurement(boolean enable) { + + } + + @Override + public void onFindDevice(boolean start) { + + } + + @Override + public void onSetConstantVibration(int integer) { + + } + + @Override + public void onScreenshotReq() { + + } + + @Override + public void onEnableHeartRateSleepSupport(boolean enable) { + + } + + @Override + public void onSetHeartRateMeasurementInterval(int seconds) { + + } + + @Override + public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) { + + } + + @Override + public void onDeleteCalendarEvent(byte type, long id) { + + } + + @Override + public void onSendConfiguration(String config) { + + } + + @Override + public void onTestNewFunction() { + + } + + @Override + public void onSendWeather(WeatherSpec weatherSpec) { + + } + + private void setInitialized(TransactionBuilder builder) { + builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext())); + } + + ID115Support setTime(TransactionBuilder builder) { + Calendar c = GregorianCalendar.getInstance(); + + int day = c.get(Calendar.DAY_OF_WEEK); + + byte dayOfWeek; + if (day == Calendar.SUNDAY) { + dayOfWeek = 6; + } else { + dayOfWeek = (byte)(day - 2); + } + + // TODO: set year + builder.write(normalWriteCharacteristic, new byte[] { + ID115Constants.CMD_ID_SETTINGS, ID115Constants.CMD_KEY_SET_TIME, + 0, 0, + (byte)c.get(Calendar.MONTH), + (byte)c.get(Calendar.DAY_OF_MONTH), + (byte)c.get(Calendar.HOUR_OF_DAY), + (byte)c.get(Calendar.MINUTE), + (byte)c.get(Calendar.SECOND), + dayOfWeek + }); + return this; + } + + ID115Support setDisplayMode(TransactionBuilder builder, boolean vertical) { + byte mode = (byte)(vertical? 2 : 0); + builder.write(normalWriteCharacteristic, new byte[] { + ID115Constants.CMD_ID_SETTINGS, ID115Constants.CMD_KEY_SET_DISPLAY_MODE, + mode + }); + return this; + } +} From 8a0263d3ffb9c3d5d9c3b3d0ce1ab408831d9db5 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 12 Jul 2018 15:56:52 +0300 Subject: [PATCH 005/211] ID115: Fix date calculation --- .../service/devices/id115/ID115Support.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index e1e8af5e2..2bab2e18a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -10,6 +10,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; +import java.util.TimeZone; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Constants; @@ -224,7 +225,7 @@ public class ID115Support extends AbstractBTLEDeviceSupport { } ID115Support setTime(TransactionBuilder builder) { - Calendar c = GregorianCalendar.getInstance(); + Calendar c = Calendar.getInstance(TimeZone.getDefault()); int day = c.get(Calendar.DAY_OF_WEEK); @@ -235,11 +236,12 @@ public class ID115Support extends AbstractBTLEDeviceSupport { dayOfWeek = (byte)(day - 2); } - // TODO: set year + int year = c.get(Calendar.YEAR); builder.write(normalWriteCharacteristic, new byte[] { ID115Constants.CMD_ID_SETTINGS, ID115Constants.CMD_KEY_SET_TIME, - 0, 0, - (byte)c.get(Calendar.MONTH), + (byte)(year & 0xff), + (byte)(year >> 8), + (byte)(1 + c.get(Calendar.MONTH)), (byte)c.get(Calendar.DAY_OF_MONTH), (byte)c.get(Calendar.HOUR_OF_DAY), (byte)c.get(Calendar.MINUTE), From 36b956aed6bcd9c62c0c956006814f3c41aa0921 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Thu, 12 Jul 2018 16:53:57 +0300 Subject: [PATCH 006/211] ID115: set manufacturer string --- .../gadgetbridge/devices/id115/ID115Coordinator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java index 2a0524f16..b791d269f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java @@ -105,7 +105,7 @@ public class ID115Coordinator extends AbstractDeviceCoordinator { @Override public String getManufacturer() { - return null; + return "VeryFit"; } @Override From 4bea2a340704c4c127a0d801b537ed1cae178e53 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Fri, 13 Jul 2018 13:54:19 +0300 Subject: [PATCH 007/211] ID115: fix logger name --- .../gadgetbridge/service/devices/id115/ID115Support.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index 2bab2e18a..4ba904412 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -27,10 +27,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSuppo import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; -import nodomain.freeyourgadget.gadgetbridge.service.devices.no1f1.No1F1Support; public class ID115Support extends AbstractBTLEDeviceSupport { - private static final Logger LOG = LoggerFactory.getLogger(No1F1Support.class); + private static final Logger LOG = LoggerFactory.getLogger(ID115Support.class); public BluetoothGattCharacteristic normalWriteCharacteristic = null; public BluetoothGattCharacteristic healthWriteCharacteristic = null; From c9e7a2ff1dbf9ae5cee8912665ddaef5d28d137c Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Fri, 13 Jul 2018 14:08:11 +0300 Subject: [PATCH 008/211] ID115: notification support --- .../devices/id115/ID115Constants.java | 49 +++++ .../service/devices/id115/ID115Support.java | 193 +++++++++++++++++- 2 files changed, 239 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java index 459425376..de26830ac 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java @@ -2,6 +2,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.id115; import java.util.UUID; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; + import static nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport.BASE_UUID; public class ID115Constants { @@ -28,6 +30,53 @@ public class ID115Constants { public static final byte CMD_KEY_SET_TIME = 0x01; public static final byte CMD_KEY_SET_DISPLAY_MODE = 0x2B; + // CMD_ID_NOTIFY + public static final byte CMD_KEY_NOTIFY_CALL = 0x01; + public static final byte CMD_KEY_NOTIFY_STOP = 0x02; + public static final byte CMD_KEY_NOTIFY_MSG = 0x03; + // CMD_ID_DEVICE_RESTART public static final byte CMD_KEY_REBOOT = 0x01; + + public static byte getNotificationType(NotificationType type) { + switch (type) { +// case GENERIC_EMAIL: +// return 2; // Icon is not supported + case WECHAT: + return 3; +// case QQ: +// return 4; + case FACEBOOK: + return 6; + case TWITTER: + return 7; + case WHATSAPP: + return 8; + case FACEBOOK_MESSENGER: + return 9; + case INSTAGRAM: + return 10; + case LINKEDIN: + return 11; +// case GENERIC_CALENDAR: +// return 12; // Icon is not supported +// case SKYPE: +// return 13; // Icon is not supported +// case LINE: +// return 17; // Icon is not supported +// case VIBER: +// return 18; // Icon is not supported +// case KAKAO_TALK: +// return 19; // Icon is not supported +// case VK: +// return 16; // Icon is not supported +// case GMAIL: +// return 20; // Icon is not supported +// case OUTLOOK: +// return 21; // Icon is not supported +// case SNAPCHAT: +// return 22; // Icon is not supported + } + return 1; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index 4ba904412..bba3f64bb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -1,15 +1,17 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.id115; +import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; import android.net.Uri; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Calendar; -import java.util.GregorianCalendar; import java.util.TimeZone; import java.util.UUID; @@ -22,6 +24,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; @@ -32,8 +35,14 @@ public class ID115Support extends AbstractBTLEDeviceSupport { private static final Logger LOG = LoggerFactory.getLogger(ID115Support.class); public BluetoothGattCharacteristic normalWriteCharacteristic = null; + public BluetoothGattCharacteristic normalNotifyCharacteristic = null; public BluetoothGattCharacteristic healthWriteCharacteristic = null; + byte[] currentNotificationBuffer; + int currentNotificationSize; + int currentNotificationIndex; + byte currentNotificationType; + public ID115Support() { super(LOG); addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS); @@ -44,10 +53,14 @@ public class ID115Support extends AbstractBTLEDeviceSupport { @Override protected TransactionBuilder initializeDevice(TransactionBuilder builder) { normalWriteCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_WRITE_NORMAL); + normalNotifyCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_NOTIFY_NORMAL); healthWriteCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_WRITE_HEALTH); builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); + builder.setGattCallback(this); + builder.notify(normalNotifyCharacteristic, true); + setTime(builder) .setDisplayMode(builder, false) .setInitialized(builder); @@ -62,7 +75,7 @@ public class ID115Support extends AbstractBTLEDeviceSupport { @Override public void onNotification(NotificationSpec notificationSpec) { - + sendMessageNotification(notificationSpec); } @Override @@ -87,7 +100,11 @@ public class ID115Support extends AbstractBTLEDeviceSupport { @Override public void onSetCallState(CallSpec callSpec) { - + if (callSpec.command == CallSpec.CALL_INCOMING) { + sendCallNotification(callSpec); + } else { + sendStopCallNotification(); + } } @Override @@ -219,6 +236,40 @@ public class ID115Support extends AbstractBTLEDeviceSupport { } + @Override + public boolean onCharacteristicChanged(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic) { + if (super.onCharacteristicChanged(gatt, characteristic)) { + return true; + } + + UUID characteristicUUID = characteristic.getUuid(); + byte[] data = characteristic.getValue(); + if (!characteristicUUID.equals(ID115Constants.UUID_CHARACTERISTIC_NOTIFY_NORMAL)) { + return false; + } + + if (data.length < 2) { + LOG.warn("short GATT response"); + return false; + } + if (data[0] == ID115Constants.CMD_ID_NOTIFY) { + if (data.length < 4) { + LOG.warn("short GATT response for NOTIFY"); + return false; + } + if (data[1] == currentNotificationType) { + if (data[3] == currentNotificationIndex) { + if (currentNotificationIndex != currentNotificationSize) { + sendNotificationChunk(currentNotificationIndex + 1); + return true; + } + } + } + } + return false; + } + private void setInitialized(TransactionBuilder builder) { builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext())); } @@ -258,4 +309,140 @@ public class ID115Support extends AbstractBTLEDeviceSupport { }); return this; } + + void sendCallNotification(CallSpec callSpec) { + String number = ""; + if (callSpec.number != null) { + number = callSpec.number; + } + + String name = ""; + if (callSpec.name != null) { + name = callSpec.name; + } + + currentNotificationBuffer = encodeCallNotification(name, number); + currentNotificationSize = (currentNotificationBuffer.length + 15) / 16; + currentNotificationType = ID115Constants.CMD_KEY_NOTIFY_CALL; + sendNotificationChunk(1); + } + + void sendStopCallNotification() { + try { + TransactionBuilder builder = performInitialized("stop_call_notification"); + builder.write(normalWriteCharacteristic, new byte[] { + ID115Constants.CMD_ID_NOTIFY, + ID115Constants.CMD_KEY_NOTIFY_STOP, + 1 + }); + performConnected(builder.getTransaction()); + } catch(IOException e) { + } + } + + void sendMessageNotification(NotificationSpec notificationSpec) { + String phone = ""; + if (notificationSpec.phoneNumber != null) { + phone = notificationSpec.phoneNumber; + } + + String title = ""; + if (notificationSpec.sender != null) { + title = notificationSpec.sender; + } else if (notificationSpec.title != null) { + title = notificationSpec.title; + } else if (notificationSpec.subject != null) { + title = notificationSpec.subject; + } + + String text = ""; + if (notificationSpec.body != null) { + text = notificationSpec.body; + } + + currentNotificationBuffer = encodeMessageNotification(notificationSpec.type, title, phone, text); + currentNotificationSize = (currentNotificationBuffer.length + 15) / 16; + currentNotificationType = ID115Constants.CMD_KEY_NOTIFY_MSG; + sendNotificationChunk(1); + } + + void sendNotificationChunk(int chunkIndex) { + currentNotificationIndex = chunkIndex; + + int offset = (chunkIndex - 1) * 16; + int tailSize = currentNotificationBuffer.length - offset; + int chunkSize = (tailSize > 16)? 16 : tailSize; + + byte raw[] = new byte[16]; + System.arraycopy(currentNotificationBuffer, offset, raw, 0, chunkSize); + + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + outputStream.write(ID115Constants.CMD_ID_NOTIFY); + outputStream.write(currentNotificationType); + outputStream.write((byte)currentNotificationSize); + outputStream.write((byte)currentNotificationIndex); + outputStream.write(raw); + byte cmd[] = outputStream.toByteArray(); + + TransactionBuilder builder = performInitialized("notification"); + builder.write(normalWriteCharacteristic, cmd); + performConnected(builder.getTransaction()); + } catch (IOException e) { + } + } + + byte[] encodeCallNotification(String name, String phone) { + if (name.length() > 20) { + name = name.substring(0, 20); + } + if (phone.length() > 20) { + phone = phone.substring(0, 20); + } + + byte[] name_bytes = name.getBytes(StandardCharsets.UTF_8); + byte[] phone_bytes = phone.getBytes(StandardCharsets.UTF_8); + + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + outputStream.write((byte) phone_bytes.length); + outputStream.write((byte) name_bytes.length); + outputStream.write(phone_bytes); + outputStream.write(name_bytes); + return outputStream.toByteArray(); + } catch (IOException e) { + return null; + } + } + + byte[] encodeMessageNotification(NotificationType type, String title, String phone, String text) { + if (title.length() > 20) { + title = title.substring(0, 20); + } + if (phone.length() > 20) { + phone = phone.substring(0, 20); + } + if (text.length() > 20) { + text = text.substring(0, 20); + } + byte[] title_bytes = title.getBytes(StandardCharsets.UTF_8); + byte[] phone_bytes = phone.getBytes(StandardCharsets.UTF_8); + byte[] text_bytes = text.getBytes(StandardCharsets.UTF_8); + + byte nativeType = ID115Constants.getNotificationType(type); + + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + outputStream.write(nativeType); + outputStream.write((byte) text_bytes.length); + outputStream.write((byte) phone_bytes.length); + outputStream.write((byte) title_bytes.length); + outputStream.write(phone_bytes); + outputStream.write(title_bytes); + outputStream.write(text_bytes); + return outputStream.toByteArray(); + } catch (IOException e) { + return null; + } + } } From d66e9e6a8b497d3b418a6f257e2bb7b2b72cba66 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Fri, 13 Jul 2018 14:22:17 +0300 Subject: [PATCH 009/211] ID115: change device icon --- .../nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java index 9b12abf24..719a09273 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -46,7 +46,7 @@ public enum DeviceType { NO1F1(50, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_no1_f1), TECLASTH30(60, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled, R.string.devicetype_teclast_h30), XWATCH(70, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_xwatch), - ID115(80, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_id115), + ID115(80, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled, R.string.devicetype_id115), TEST(1000, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_test); private final int key; From 02b3f233291b9ac7c53c61dc308337dd153b7128 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Fri, 13 Jul 2018 15:00:16 +0300 Subject: [PATCH 010/211] ID115: set steps goal --- .../devices/id115/ID115Constants.java | 1 + .../service/devices/id115/ID115Support.java | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java index de26830ac..d332744ca 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java @@ -28,6 +28,7 @@ public class ID115Constants { // CMD_ID_SETTINGS public static final byte CMD_KEY_SET_TIME = 0x01; + public static final byte CMD_KEY_SET_GOAL = 0x03; public static final byte CMD_KEY_SET_DISPLAY_MODE = 0x2B; // CMD_ID_NOTIFY diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index bba3f64bb..e2fd4f697 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -17,6 +17,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Constants; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; @@ -63,6 +64,7 @@ public class ID115Support extends AbstractBTLEDeviceSupport { setTime(builder) .setDisplayMode(builder, false) + .setGoal(builder) .setInitialized(builder); return builder; @@ -310,6 +312,23 @@ public class ID115Support extends AbstractBTLEDeviceSupport { return this; } + private ID115Support setGoal(TransactionBuilder transaction) { + ActivityUser activityUser = new ActivityUser(); + int value = activityUser.getStepsGoal(); + + transaction.write(normalWriteCharacteristic, new byte[]{ + ID115Constants.CMD_ID_SETTINGS, + ID115Constants.CMD_KEY_SET_GOAL, + 0, + (byte) (value & 0xff), + (byte) ((value >> 8) & 0xff), + (byte) ((value >> 16) & 0xff), + (byte) ((value >> 24) & 0xff), + 0, 0 + }); + return this; + } + void sendCallNotification(CallSpec callSpec) { String number = ""; if (callSpec.number != null) { From fe9ec9b88adb454150bf7bd6c1a8309ba0a69ae3 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sat, 14 Jul 2018 13:23:21 +0300 Subject: [PATCH 011/211] ID115: screen orientation preference --- .../devices/id115/ID115Constants.java | 4 ++++ .../service/devices/id115/ID115Support.java | 20 +++++++++++++++---- app/src/main/res/values/arrays.xml | 9 +++++++++ app/src/main/res/values/strings.xml | 6 ++++++ app/src/main/res/xml/preferences.xml | 16 +++++++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java index d332744ca..07f422037 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java @@ -7,6 +7,8 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import static nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport.BASE_UUID; public class ID115Constants { + public static final String PREF_SCREEN_ORIENTATION = "id115_screen_orientation"; + public static final UUID UUID_SERVICE_ID115 = UUID.fromString(String.format(BASE_UUID, "0AF0")); public static final UUID UUID_CHARACTERISTIC_WRITE_NORMAL = UUID.fromString(String.format(BASE_UUID, "0AF6")); public static final UUID UUID_CHARACTERISTIC_NOTIFY_NORMAL = UUID.fromString(String.format(BASE_UUID, "0AF7")); @@ -30,6 +32,8 @@ public class ID115Constants { public static final byte CMD_KEY_SET_TIME = 0x01; public static final byte CMD_KEY_SET_GOAL = 0x03; public static final byte CMD_KEY_SET_DISPLAY_MODE = 0x2B; + public static final byte CMD_ARG_HORIZONTAL = 0x00; + public static final byte CMD_ARG_VERTICAL = 0x02; // CMD_ID_NOTIFY public static final byte CMD_KEY_NOTIFY_CALL = 0x01; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index e2fd4f697..c3fce2e67 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -15,6 +15,7 @@ import java.util.Calendar; import java.util.TimeZone; import java.util.UUID; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Constants; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; @@ -63,7 +64,7 @@ public class ID115Support extends AbstractBTLEDeviceSupport { builder.notify(normalNotifyCharacteristic, true); setTime(builder) - .setDisplayMode(builder, false) + .setScreenOrientation(builder) .setGoal(builder) .setInitialized(builder); @@ -303,11 +304,22 @@ public class ID115Support extends AbstractBTLEDeviceSupport { return this; } - ID115Support setDisplayMode(TransactionBuilder builder, boolean vertical) { - byte mode = (byte)(vertical? 2 : 0); + ID115Support setScreenOrientation(TransactionBuilder builder) { + String value = GBApplication.getPrefs().getString(ID115Constants.PREF_SCREEN_ORIENTATION, + "horizontal"); + LOG.warn("value: '" + value + "'"); + + byte orientation; + if (value.equals("horizontal")) { + orientation = ID115Constants.CMD_ARG_HORIZONTAL; + } else { + orientation = ID115Constants.CMD_ARG_VERTICAL; + } + + LOG.warn("Screen orientation: " + orientation); builder.write(normalWriteCharacteristic, new byte[] { ID115Constants.CMD_ID_SETTINGS, ID115Constants.CMD_KEY_SET_DISPLAY_MODE, - mode + orientation }); return this; } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index b1e70e8d7..e8004f907 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -86,6 +86,15 @@ right + + @string/horizontal + @string/vertical + + + horizontal + vertical + + @string/vibration_profile_staccato @string/vibration_profile_short diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2ed11b1ac..7cb4e564d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -192,6 +192,10 @@ All day heart rate measurement HPlus/Makibes settings + + ID115 settings + Screen orientation + Auto export Auto export enabled @@ -252,6 +256,8 @@ Other Left Right + Horizontal + Vertical No valid user data given, using dummy user data for now. When your Mi Band vibrates and blinks, tap it a few times in a row. Install diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 1aba679db..9238ead71 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -507,6 +507,22 @@ + + + + + Date: Sun, 15 Jul 2018 00:46:11 +0300 Subject: [PATCH 012/211] ID115: log IO exceptions --- .../gadgetbridge/service/devices/id115/ID115Support.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index c3fce2e67..522365e4e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -93,6 +93,7 @@ public class ID115Support extends AbstractBTLEDeviceSupport { setTime(builder); performConnected(builder.getTransaction()); } catch(IOException e) { + LOG.warn("Unable to send current time", e); } } @@ -368,6 +369,7 @@ public class ID115Support extends AbstractBTLEDeviceSupport { }); performConnected(builder.getTransaction()); } catch(IOException e) { + LOG.warn("Unable to stop call notification", e); } } @@ -420,6 +422,7 @@ public class ID115Support extends AbstractBTLEDeviceSupport { builder.write(normalWriteCharacteristic, cmd); performConnected(builder.getTransaction()); } catch (IOException e) { + LOG.warn("Unable to send notification chunk", e); } } From e03d80b8e462987e3addd7f4784b1aef641ecc06 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 15 Jul 2018 10:17:01 +0300 Subject: [PATCH 013/211] ID115: set device icon for the main screen --- app/src/main/res/drawable/level_list_device.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/drawable/level_list_device.xml b/app/src/main/res/drawable/level_list_device.xml index 4f4fcd9f8..06aea0aaf 100644 --- a/app/src/main/res/drawable/level_list_device.xml +++ b/app/src/main/res/drawable/level_list_device.xml @@ -13,6 +13,7 @@ + @@ -27,5 +28,6 @@ + \ No newline at end of file From 27ea72202151f28660cd9370e20e301d836312b5 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 16 Jul 2018 13:37:08 +0200 Subject: [PATCH 014/211] bump gradle plugin version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0fbc9d45b..98e051161 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.2' + classpath 'com.android.tools.build:gradle:3.1.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From dc1e8316301270504d2fe8e0a4c6d9af99331738 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 16 Jul 2018 13:38:51 +0200 Subject: [PATCH 015/211] Mi Band 3: Fix Pairing, this MIGHT break pairing for other devices (Bip/Cor/Mi Band 2) --- .../gadgetbridge/devices/miband/MiBand2Service.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java index b52a7b736..3bb2eb843 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java @@ -101,7 +101,7 @@ public class MiBand2Service { /** * In some logs it's 0x0... */ - public static final byte AUTH_BYTE = 0x8; + public static final byte AUTH_BYTE = 0x00; // maybe not really activity data, but steps? public static final byte COMMAND_FETCH_DATA = 0x02; From 46f3686764d14e9f87e97d8ee9c68ccb654e5c41 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 16 Jul 2018 14:19:02 +0200 Subject: [PATCH 016/211] Mi Band 3: Also send AQI for weather to make current temperature appear --- .../service/devices/huami/amazfitbip/AmazfitBipSupport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java index 8ae653ac5..58f2c41c8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java @@ -247,7 +247,7 @@ public class AmazfitBipSupport extends MiBand2Support { LOG.error("Error sending current weather", ex); } - if (gbDevice.getType() == DeviceType.AMAZFITBIP) { + if (gbDevice.getType() != DeviceType.AMAZFITCOR) { try { TransactionBuilder builder; builder = performInitialized("Sending air quality index"); From f2aa71e32cb0f0b2f319c78f32021cb73b964a6c Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 16 Jul 2018 14:36:52 +0200 Subject: [PATCH 017/211] Amazfit Bip: Support Russian language. Closes #1145 --- .../devices/huami/amazfitbip/AmazfitBipSupport.java | 12 ++++++++++-- app/src/main/res/values/arrays.xml | 2 ++ app/src/main/res/values/strings.xml | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java index 58f2c41c8..e4edd33e7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java @@ -50,12 +50,12 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ConditionalWrit 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.amazfitbip.operations.AmazfitBipFetchLogsOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiIcon; -import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.operations.AmazfitBipFetchLogsOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchActivityOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchSportsSummaryOperation; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; import nodomain.freeyourgadget.gadgetbridge.util.Version; @@ -427,6 +427,10 @@ public class AmazfitBipSupport extends MiBand2Support { command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_SPANISH; localeString = "es_ES"; break; + case 4: + command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH; + localeString = "ru_RU"; + break; default: switch (language) { case "zh": @@ -442,6 +446,10 @@ public class AmazfitBipSupport extends MiBand2Support { command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_SPANISH; localeString = "es_ES"; break; + case "ru": + command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH; + localeString = "ru_RU"; + break; default: command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH; localeString = "en_US"; diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index b1e70e8d7..8a55f30e1 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -258,6 +258,7 @@ @string/traditional_chinese @string/english @string/spanish + @string/russian @@ -266,6 +267,7 @@ 1 2 3 + 4 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fd44522e4..dabc94303 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -421,6 +421,7 @@ Traditional Chinese English Spanish + Russian About to transfer data since %1$s From 65fbb4da5b9bf4893f195eb3c85ee206ed8b618b Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Mon, 16 Jul 2018 15:48:37 +0300 Subject: [PATCH 018/211] ID115: wrist setting --- .../devices/id115/ID115Constants.java | 4 ++++ .../service/devices/id115/ID115Support.java | 21 +++++++++++++++++++ app/src/main/res/xml/preferences.xml | 9 ++++++++ 3 files changed, 34 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java index 07f422037..6b4e3c985 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java @@ -7,6 +7,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import static nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport.BASE_UUID; public class ID115Constants { + public static final String PREF_WRIST = "id115_wrist"; public static final String PREF_SCREEN_ORIENTATION = "id115_screen_orientation"; public static final UUID UUID_SERVICE_ID115 = UUID.fromString(String.format(BASE_UUID, "0AF0")); @@ -31,6 +32,9 @@ public class ID115Constants { // CMD_ID_SETTINGS public static final byte CMD_KEY_SET_TIME = 0x01; public static final byte CMD_KEY_SET_GOAL = 0x03; + public static final byte CMD_KEY_SET_HAND = 0x22; + public static final byte CMD_ARG_LEFT = 0x00; + public static final byte CMD_ARG_RIGHT = 0x01; public static final byte CMD_KEY_SET_DISPLAY_MODE = 0x2B; public static final byte CMD_ARG_HORIZONTAL = 0x00; public static final byte CMD_ARG_VERTICAL = 0x02; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index 522365e4e..f4661b703 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -64,6 +64,7 @@ public class ID115Support extends AbstractBTLEDeviceSupport { builder.notify(normalNotifyCharacteristic, true); setTime(builder) + .setWrist(builder) .setScreenOrientation(builder) .setGoal(builder) .setInitialized(builder); @@ -305,6 +306,26 @@ public class ID115Support extends AbstractBTLEDeviceSupport { return this; } + ID115Support setWrist(TransactionBuilder builder) { + String value = GBApplication.getPrefs().getString(ID115Constants.PREF_WRIST, + "left"); + LOG.warn("wrist value: '" + value + "'"); + + byte wrist; + if (value.equals("left")) { + wrist = ID115Constants.CMD_ARG_LEFT; + } else { + wrist = ID115Constants.CMD_ARG_RIGHT; + } + + LOG.warn("Wrist: " + wrist); + builder.write(normalWriteCharacteristic, new byte[] { + ID115Constants.CMD_ID_SETTINGS, ID115Constants.CMD_KEY_SET_HAND, + wrist + }); + return this; + } + ID115Support setScreenOrientation(TransactionBuilder builder) { String value = GBApplication.getPrefs().getString(ID115Constants.PREF_SCREEN_ORIENTATION, "horizontal"); diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 9238ead71..754af49bc 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -514,6 +514,15 @@ + + + Date: Mon, 16 Jul 2018 14:49:58 +0200 Subject: [PATCH 019/211] Update changelog and readme --- CHANGELOG.md | 3 +++ README.md | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 166e3292a..394f48eb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,10 @@ #### Version 0.28.0 (WIP) * Inital support for ZeTime * Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme +* Amazfit Bip: Support setting language to Russian * Mi Band 3: support setting language (english and spanish tested) +* Mi Band 3: Fix pairing +* Mi Band 3: Send AQI to enable display of current temperature #### Version 0.27.1 * Pebble: Change appstore search to point to RomanPort's pebble appstore diff --git a/README.md b/README.md index 7648d0cfc..2ef0d14c1 100644 --- a/README.md +++ b/README.md @@ -26,11 +26,13 @@ vendor's servers. * Pebble 2 [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Pebble) * Mi Band, Mi Band 1A, Mi Band 1S [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band) * Mi Band 2 [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-2) +* Mi Band 3 [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-3) * Amazfit Bip [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip) * Amazfit Cor (no maintainer) [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cor) * HPlus Devices (e.g. ZeBand) [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/HPlus) * Teclast H10, H30 (WIP) * NO.1 F1 (WIP) +* ZeTime (WIP) * Liveview * Vibratissimo (experimental) * XWatch (Affordable Chinese Casio-like smartwatches) @@ -92,6 +94,8 @@ For more information read [this wiki article](https://github.com/Freeyourgadget/ * João Paulo Barraca (HPlus) * Vitaly Svyastyn (NO.1 F1) * Sami Alaoui (Teclast H30) +* "ladbsoft" (XWatch) +* Sebastian Kranz (ZeTime) ## Contribute From 7cad1fe2d3a9d1bc463ceff43138d6d4a83b1d70 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Sun, 15 Jul 2018 06:07:58 +0000 Subject: [PATCH 020/211] Translated using Weblate (Hebrew) Currently translated at 100.0% (501 of 501 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 1e37004d5..a7692dcd3 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -551,4 +551,6 @@ זמן מזערי בין אחזורים מתבצע אחזור כל %s דקות + MyKronoz ZeTime + From b6bd100f286766c392852e7872f08a9af0ea943b Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Mon, 16 Jul 2018 15:50:29 +0300 Subject: [PATCH 021/211] ID115: remove useless debug messages --- .../gadgetbridge/service/devices/id115/ID115Support.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index f4661b703..667819345 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -309,7 +309,6 @@ public class ID115Support extends AbstractBTLEDeviceSupport { ID115Support setWrist(TransactionBuilder builder) { String value = GBApplication.getPrefs().getString(ID115Constants.PREF_WRIST, "left"); - LOG.warn("wrist value: '" + value + "'"); byte wrist; if (value.equals("left")) { @@ -318,7 +317,6 @@ public class ID115Support extends AbstractBTLEDeviceSupport { wrist = ID115Constants.CMD_ARG_RIGHT; } - LOG.warn("Wrist: " + wrist); builder.write(normalWriteCharacteristic, new byte[] { ID115Constants.CMD_ID_SETTINGS, ID115Constants.CMD_KEY_SET_HAND, wrist @@ -329,7 +327,6 @@ public class ID115Support extends AbstractBTLEDeviceSupport { ID115Support setScreenOrientation(TransactionBuilder builder) { String value = GBApplication.getPrefs().getString(ID115Constants.PREF_SCREEN_ORIENTATION, "horizontal"); - LOG.warn("value: '" + value + "'"); byte orientation; if (value.equals("horizontal")) { @@ -338,7 +335,6 @@ public class ID115Support extends AbstractBTLEDeviceSupport { orientation = ID115Constants.CMD_ARG_VERTICAL; } - LOG.warn("Screen orientation: " + orientation); builder.write(normalWriteCharacteristic, new byte[] { ID115Constants.CMD_ID_SETTINGS, ID115Constants.CMD_KEY_SET_DISPLAY_MODE, orientation From aa143577f8ac21270ca0de7a7bb4d3a4634f8a7f Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 16 Jul 2018 15:16:23 +0200 Subject: [PATCH 022/211] Amazfit Cor: Support language switching on newer firmwares I shamelessly assumed the firmware version (chose the version that was included in the same Mi Fit version when bip started to support the new command) --- CHANGELOG.md | 1 + .../service/devices/huami/amazfitbip/AmazfitBipSupport.java | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 394f48eb2..a1aa19197 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Inital support for ZeTime * Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme * Amazfit Bip: Support setting language to Russian +* Amazfit Cor: Support language switching on newer firmwares * Mi Band 3: support setting language (english and spanish tested) * Mi Band 3: Fix pairing * Mi Band 3: Send AQI to enable display of current temperature diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java index e4edd33e7..9d7a7277b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java @@ -462,7 +462,9 @@ public class AmazfitBipSupport extends MiBand2Support { builder.add(new ConditionalWriteAction(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION)) { @Override protected byte[] checkCondition() { - if (gbDevice.getType() == DeviceType.MIBAND3 || (gbDevice.getType() == DeviceType.AMAZFITBIP && new Version(gbDevice.getFirmwareVersion()).compareTo(new Version("0.1.0.77")) >= 0)) { + if (gbDevice.getType() == DeviceType.MIBAND3 || + (gbDevice.getType() == DeviceType.AMAZFITBIP && new Version(gbDevice.getFirmwareVersion()).compareTo(new Version("0.1.0.77")) >= 0) || + (gbDevice.getType() == DeviceType.AMAZFITCOR && new Version(gbDevice.getFirmwareVersion()).compareTo(new Version("1.0.7.23")) >= 0)) { return command_new; } else { return command_old; From eef38d46807804d490333497c543b3839baa0fc8 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 17 Jul 2018 00:29:36 +0200 Subject: [PATCH 023/211] Only use 0x00 as auth flags on Mi Band 3 - to not disturb other devices --- .../devices/miband/MiBand2Service.java | 2 +- .../devices/huami/miband2/MiBand2Support.java | 15 ++++++++++----- .../huami/miband2/operations/InitOperation.java | 10 ++++++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java index 3bb2eb843..59e2e0408 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java @@ -101,7 +101,7 @@ public class MiBand2Service { /** * In some logs it's 0x0... */ - public static final byte AUTH_BYTE = 0x00; + public static final byte AUTH_BYTE = 0x08; // maybe not really activity data, but steps? public static final byte COMMAND_FETCH_DATA = 0x02; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java index ab1d4dbe6..9e95d853b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java @@ -57,6 +57,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.huami.ActivateDisplayOnLift; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService; @@ -69,7 +70,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; -import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample; @@ -84,6 +84,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CalendarEvents; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; @@ -103,13 +104,13 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.Hear import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiDeviceEvent; -import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy; -import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.RealtimeSamplesSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.actions.StopNotificationAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchActivityOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchSportsSummaryOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.InitOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.UpdateFirmwareOperation; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.RealtimeSamplesSupport; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; @@ -209,7 +210,11 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { try { boolean authenticate = needsAuth; needsAuth = false; - new InitOperation(authenticate, this, builder).perform(); + byte authFlags = MiBand2Service.AUTH_BYTE; + if (gbDevice.getType() == DeviceType.MIBAND3) { + authFlags = 0x00; + } + new InitOperation(authenticate, authFlags, this, builder).perform(); characteristicHRControlPoint = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT); } catch (IOException e) { GB.toast(getContext(), "Initializing Mi Band 2 failed", Toast.LENGTH_SHORT, GB.ERROR, e); @@ -219,7 +224,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { /** * Returns the given date/time (calendar) as a byte sequence, suitable for sending to the - * Mi Band 2 (or derivative). The band appears to not handle DST offsets, so we simply add this + * Mi Band 2 (or derivative). The band appears to not handle DST offsets, so we simply add this * to the timezone. * @param calendar * @param precision diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/InitOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/InitOperation.java index 93204f441..d110289eb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/InitOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/InitOperation.java @@ -49,10 +49,12 @@ public class InitOperation extends AbstractBTLEOperation { private final TransactionBuilder builder; private final boolean needsAuth; + private final byte authFlags; - public InitOperation(boolean needsAuth, MiBand2Support support, TransactionBuilder builder) { + public InitOperation(boolean needsAuth, byte authFlags, MiBand2Support support, TransactionBuilder builder) { super(support); this.needsAuth = needsAuth; + this.authFlags = authFlags; this.builder = builder; builder.setGattCallback(this); } @@ -63,7 +65,7 @@ public class InitOperation extends AbstractBTLEOperation { if (needsAuth) { builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.AUTHENTICATING, getContext())); // write key to miband2 - byte[] sendKey = org.apache.commons.lang3.ArrayUtils.addAll(new byte[]{MiBand2Service.AUTH_SEND_KEY, MiBand2Service.AUTH_BYTE}, getSecretKey()); + byte[] sendKey = org.apache.commons.lang3.ArrayUtils.addAll(new byte[]{MiBand2Service.AUTH_SEND_KEY, authFlags}, getSecretKey()); builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_AUTH), sendKey); } else { builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); @@ -73,7 +75,7 @@ public class InitOperation extends AbstractBTLEOperation { } private byte[] requestAuthNumber() { - return new byte[]{MiBand2Service.AUTH_REQUEST_RANDOM_AUTH_NUMBER, MiBand2Service.AUTH_BYTE}; + return new byte[]{MiBand2Service.AUTH_REQUEST_RANDOM_AUTH_NUMBER, authFlags}; } private byte[] getSecretKey() { @@ -105,7 +107,7 @@ public class InitOperation extends AbstractBTLEOperation { // md5?? byte[] eValue = handleAESAuth(value, getSecretKey()); byte[] responseValue = org.apache.commons.lang3.ArrayUtils.addAll( - new byte[]{MiBand2Service.AUTH_SEND_ENCRYPTED_AUTH_NUMBER, MiBand2Service.AUTH_BYTE}, eValue); + new byte[]{MiBand2Service.AUTH_SEND_ENCRYPTED_AUTH_NUMBER, authFlags}, eValue); TransactionBuilder builder = createTransactionBuilder("Sending the encrypted random key to the band"); builder.write(characteristic, responseValue); From 1f6850a4b32568f7eb90f414f18d540ed7fabd2b Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 17 Jul 2018 16:01:41 +0200 Subject: [PATCH 024/211] update changelogs --- CHANGELOG.md | 4 ++-- app/src/main/res/xml/changelog_master.xml | 10 +++++++++- fastlane/metadata/android/en-US/changelogs/134.txt | 7 +++++++ 3 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/134.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index a1aa19197..455bc44d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ### Changelog -#### Version 0.28.0 (WIP) -* Inital support for ZeTime +#### Version 0.28.0 +* Initial support for ZeTime * Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme * Amazfit Bip: Support setting language to Russian * Amazfit Cor: Support language switching on newer firmwares diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index b22a59188..d43375fc0 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,5 +1,13 @@ - + + Initial support for ZeTime + Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme + Amazfit Bip: Support setting language to Russian + Amazfit Cor: Support language switching on newer firmwares + Mi Band 3: support setting language (english and spanish tested) + Mi Band 3: Fix pairing + Mi Band 3: Send AQI to enable display of current temperature + Pebble: Change appstore search to point to RomanPort's pebble appstore Mi Band 3: Allow flashing fonts (untested) diff --git a/fastlane/metadata/android/en-US/changelogs/134.txt b/fastlane/metadata/android/en-US/changelogs/134.txt new file mode 100644 index 000000000..887942422 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/134.txt @@ -0,0 +1,7 @@ +* Initial support for ZeTime +* Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme +* Amazfit Bip: Support setting language to Russian +* Amazfit Cor: Support language switching on newer firmwares +* Mi Band 3: support setting language (english and spanish tested) +* Mi Band 3: Fix pairing +* Mi Band 3: Send AQI to enable display of current temperature From c7125f78cf9e6ecb3c02e0ec1a637ff9bb36e0b0 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 17 Jul 2018 16:12:15 +0200 Subject: [PATCH 025/211] no comment --- app/src/main/res/xml/changelog_master.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index d43375fc0..64ce04aec 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,4 +1,5 @@ + Initial support for ZeTime Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme From 2468ad9d7f9ba0d6904b98e308144d258d4bbf0c Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Tue, 17 Jul 2018 06:46:02 +0000 Subject: [PATCH 026/211] Translated using Weblate (Hebrew) Currently translated at 100.0% (502 of 502 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index a7692dcd3..95dc9117f 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -553,4 +553,6 @@ MyKronoz ZeTime + רוסית + From 7fb0ad0dfd3b068deb3ed5f103574a8560c7be43 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 17 Jul 2018 11:11:30 +0000 Subject: [PATCH 027/211] Translated using Weblate (Russian) Currently translated at 93.8% (471 of 502 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 81 +++++++++++++++++++------- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 522c74578..edc4e8914 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -82,7 +82,7 @@ Когда экран выключен Никогда Конфиденциальность - Вызов режима конфиденциальности + Конфиденциальность вызовов Отображать имя и номер Скрывать имя, но отображать номер Скрывать номер, но отображать имя @@ -159,7 +159,7 @@ Gadgetbridge запущен установка бинарного файла %1$d/%2$d Установка не удалась - Установка завершена + Установлено ВЫ ПЫТАЕТЕСЬ УСТАНОВИТЬ ПРОШИВКУ, ПРОДОЛЖАЙТЕ НА СВОЙ СТРАХ И РИСК.\n\n\n Эта прошивка для ревизии устройства: %s Вы собираетесь установить приложение:\n\n\n%1$s версия %2$s от %3$s\n Недоступно @@ -218,7 +218,7 @@ Чат Навигация Социальные сети - Найти потерянное устройство + Поиск потерянного устройства Отмените, чтобы прекратить вибрацию. Ваша активность Завести Будильник @@ -236,7 +236,7 @@ Будильник был послан на устройство! Нет данных. Синхронизировать устройство? Будет передано %1$s данных, начиная с %2$s - Цель шагов на каждый день + Ежедневная цель шагов Произошла ошибка при выполнении \'%1$s\' Ваша активность (АЛЬФА) Подключиться не удалось: %1$s @@ -316,7 +316,7 @@ Версия прошивки: %1$s Ошибка создания каталога для лог-файлов: %1$s "Версия устройства: " - Происходит обновление прошивки + Обновление прошивки Прошивка не отправлена Пульс Пульс @@ -334,16 +334,16 @@ Ошибка экспорта настроек: %1$s Импортировать данные? Точно перезаписать текущую базу данных? Все текущие данные вашей активности (если они есть) будут утеряны. - Импорт успешно завершён. + Импортировано. Ошибка импорта базы данных: %1$s Ошибка импорта настроек: %1$s Удалить данные по вашей активности? Действительно удалить всю базу данных? Все данные о вашей активности и информация о ваших устройствах будут утеряны. - Данные успешно удалены. + Данные удалены. Удалить базу данных не получилось. Удалить данные по предыдущей активности? Точно удалить старые данные об активности? Все не импортированные данные об активности будут утеряны. - Устаревшие данные по вашей активности успешно удалены. + Устаревшие данные активности удалены. Удалить устаревшие данные по вашей активности не получилось. Перезаписать Отмена @@ -378,7 +378,7 @@ Не удалось выполнить привязку к %1$s. Попытка соединения с: %1$s Включить Bluetooth для обнаружения устройств. - Привязка к %1$s успешно выполнена. + Связано с %1$s. Выполнить сопряжение с %1$s ? Выберите \"Сопряжение\" для сопряжения ваших устройств. Если не получилось, попробуйте снова без сопряжения. Сопряжение @@ -387,19 +387,20 @@ Подключить Заблокированные календари - "Вы собираетесь установить прошивку %s на ваш Amazfit Bip. + Вы собираетесь установить прошивку %s на ваш Amazfit Bip. +\n +\nСоблюдайте последовательность: вначале установите файл .fw, затем .res, и затем .gps. После установки файла .fw часы перезагрузятся. \n -\nПеред этим, пожалуйста, установите файл .gps, файл .res и последним — .fw файл. После установки .fw файла устройство перезагрузится. -\nОбратите внимание: если файлы .gps и .res такие же, как в текущей версии, их не нужно переустанавливать. -\n -\nВы действуете на свой страх и риск!" - Вы собираетесь установить прошивку %s на ваш Amazonfit Cor. -\n -\nПеред этим, пожалуйста, установите файл .res и файл .fw. После установки файла .fw ваше устройство перезагрузится. -\n -\nОбратие внимание: если версия файла .res совпадает с предыдущей, его не нужно переустанавливать. -\n -\nЭту прошивку не проверяли, поэтому есть вероятность сломать ваше устройство. Действуйте на свой страх и риск! +\nОбратите внимание: если файлы .gps и .res такие же, как в текущей версии, их не нужно переустанавливать. +\n +\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! + Вы собираетесь установить прошивку %s на ваш Amazfit Cor. +\n +\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. +\n +\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. +\n +\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! Включить жесты \"провести направо и налево\" в графиках активности Заблокировать Календари @@ -481,4 +482,40 @@ Погода Компас Настройки - + Заблокировать все + Разблокировать все + + + Вы собираетесь установить прошивку %s на ваш Mi Band 3. +\n +\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся. +\n +\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать. +\n +\nНЕ ПРОВЕРЯЛОСЬ, ЕСТЬ ВЕРОЯТНОСТЬ СЛОМАТЬ ВАШЕ УСТРОЙСТВО. ВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК! + Местоположение для погоды (CM/LOS) + + Подключаться только в режиме GATT-клиента + Экспериментальные настройки только для Pebble 2. Попробуйте, если есть проблемы с соединением. + Автоматический экспорт данных + Включить автоматический экспорт + Путь экспорта + Интервал экспорта + Экспортировать каждые %d часов + + Испанский + Русский + + Не измерялось + Активность + Неизвестная активность + Беговая дорожка + Прошивка GPS + Ресурсы + Неизвестное устройство + Pebble + Amazfit Bip + Amazfit Cor + Alipay (ярлык) + Alipay + From cdad2ba67d92223047a46068a477241fb83fa159 Mon Sep 17 00:00:00 2001 From: K0L0B0G Date: Tue, 17 Jul 2018 11:27:54 +0000 Subject: [PATCH 028/211] Translated using Weblate (Russian) Currently translated at 93.8% (471 of 502 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index edc4e8914..5eed409a3 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -518,4 +518,11 @@ Amazfit Cor Alipay (ярлык) Alipay - +Вкл. + Выбрать все + Поделиться + Прошивка + Погода (ярлык) + Будильник + Таймер + From d1253348dccdeaa0cedc43312d97582924a81650 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 19 Jul 2018 12:00:17 +0200 Subject: [PATCH 029/211] Mi Band 3: whitelist tested firmware, res and font --- .../service/devices/huami/miband3/MiBand3FirmwareInfo.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java index fcfda8127..124b96d48 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3FirmwareInfo.java @@ -43,8 +43,13 @@ public class MiBand3FirmwareInfo extends HuamiFirmwareInfo { static { // firmware + crcToVersion.put(55852, "1.2.0.8"); // resources + crcToVersion.put(54724, "1.2.0.8"); + + // font + crcToVersion.put(19775, "1"); } public MiBand3FirmwareInfo(byte[] bytes) { From e96dcc69abbacfea81335ca302b05963f1f4987c Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sat, 21 Jul 2018 17:18:08 +0200 Subject: [PATCH 030/211] Amazfit Bip: try to support weather in newer firmwares --- .../devices/miband/MiBand2Service.java | 2 ++ .../huami/amazfitbip/AmazfitBipSupport.java | 8 +++-- .../devices/huami/miband2/MiBand2Support.java | 32 ++++++++++++++++++- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java index 59e2e0408..8fedb3d58 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java @@ -50,6 +50,8 @@ public class MiBand2Service { public static final UUID UUID_CHARACTERISTIC_AUTH = UUID.fromString("00000009-0000-3512-2118-0009af100700"); public static final UUID UUID_CHARACTERISTIC_DEVICEEVENT = UUID.fromString("00000010-0000-3512-2118-0009af100700"); + public static final UUID UUID_CHARACTERISTIC_CHUNKEDTRANSFER = UUID.fromString("00000020-0000-3512-2118-0009af100700"); + public static final int ALERT_LEVEL_NONE = 0; public static final int ALERT_LEVEL_MESSAGE = 1; public static final int ALERT_LEVEL_PHONE_CALL = 2; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java index 9d7a7277b..f4f288fbb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java @@ -310,7 +310,6 @@ public class AmazfitBipSupport extends MiBand2Support { for (WeatherSpec.Forecast forecast : weatherSpec.forecasts) { condition = HuamiWeatherConditions.mapToAmazfitBipWeatherCode(forecast.conditionCode); - buf.put(condition); buf.put(condition); buf.put((byte) (forecast.maxTemp - 273)); @@ -321,7 +320,12 @@ public class AmazfitBipSupport extends MiBand2Support { } } - builder.write(getCharacteristic(AmazfitBipService.UUID_CHARACTERISTIC_WEATHER), buf.array()); + if (characteristicChunked != null) { + writeToChunked(builder, 1, buf.array()); + } else { + builder.write(getCharacteristic(AmazfitBipService.UUID_CHARACTERISTIC_WEATHER), buf.array()); + } + builder.queue(getQueue()); } catch (Exception ex) { LOG.error("Error sending weather forecast", ex); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java index 9e95d853b..6cda41620 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java @@ -156,7 +156,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } }; - BluetoothGattCharacteristic characteristicHRControlPoint; + private BluetoothGattCharacteristic characteristicHRControlPoint; + protected BluetoothGattCharacteristic characteristicChunked; private boolean needsAuth; private volatile boolean telephoneRinging; @@ -216,6 +217,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } new InitOperation(authenticate, authFlags, this, builder).perform(); characteristicHRControlPoint = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT); + characteristicChunked = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_CHUNKEDTRANSFER); } catch (IOException e) { GB.toast(getContext(), "Initializing Mi Band 2 failed", Toast.LENGTH_SHORT, GB.ERROR, e); } @@ -1609,6 +1611,34 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } + protected void writeToChunked(TransactionBuilder builder, int type, byte[] data) { + final int MAX_CHUNKLENGTH = 17; + int remaining = data.length; + byte count = 0; + while (remaining > 0) { + int copybytes = Math.min(remaining, MAX_CHUNKLENGTH); + byte[] chunk = new byte[copybytes + 3]; + + byte flags = 0; + if (remaining <= MAX_CHUNKLENGTH) { + flags |= 0x80; // last chunk + if (count == 0) { + flags |= 0x40; // weird but true + } + } else if (count > 0) { + flags |= 0x40; // consecutive chunk + } + + chunk[0] = 0; + chunk[1] = (byte) (flags | type); + chunk[2] = (byte) (count & 0xff); + + System.arraycopy(data, count++ * MAX_CHUNKLENGTH, chunk, 3, copybytes); + builder.write(characteristicChunked, chunk); + remaining -= copybytes; + } + } + public void phase2Initialize(TransactionBuilder builder) { LOG.info("phase2Initialize..."); requestBatteryInfo(builder); From 86a15a7c7bd96043e69d1c1982e52aa6dd49bd91 Mon Sep 17 00:00:00 2001 From: K0L0B0G Date: Wed, 18 Jul 2018 07:23:32 +0000 Subject: [PATCH 031/211] Translated using Weblate (Russian) Currently translated at 96.6% (485 of 502 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 5eed409a3..0e1c12f14 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -525,4 +525,5 @@ Погода (ярлык) Будильник Таймер + Велопрогулка From 8141076e25a1e70443cafd85a04dbf3b4077a487 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 18 Jul 2018 07:27:55 +0000 Subject: [PATCH 032/211] Translated using Weblate (Russian) Currently translated at 96.6% (485 of 502 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 0e1c12f14..6953ed01f 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -87,7 +87,7 @@ Скрывать имя, но отображать номер Скрывать номер, но отображать имя Скрывать имя и номер - Нежелательные приложения + Заблокированные приложения Сохранённые сообщения Ответы Общий суффикс @@ -526,4 +526,18 @@ Будильник Таймер Велопрогулка + Тестовое устройство + Mi Band + Mi Band 2 + Mi Band 3 + Vibratissimo + LiveView + HPlus + Makibes F68 + Exrizu K8 + Q8 + Teclast H30 + XWatch + MyKronoz ZeTime + From 290c6c53fb45a59e9b79520f65ee63354d22012a Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sun, 22 Jul 2018 11:52:25 +0200 Subject: [PATCH 033/211] Fix wrong mapping yahoo weather conditions to openweathermap. --- .../nodomain/freeyourgadget/gadgetbridge/model/Weather.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java index f2c5a9cf6..1319db113 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java @@ -433,7 +433,7 @@ public class Weather { return 801; case 45: //thundershowers case 47: //isolated thundershowers - return 621; + return 211; case 3200: //not available default: return -1; From a5dd88df53cefae064be67a218943ee8eafc421a Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sun, 22 Jul 2018 14:52:17 +0200 Subject: [PATCH 034/211] Fix discovery on devices with Android version < Lollipop also reduce the amount of lines logged in discovery activity. --- .../gadgetbridge/activities/DiscoveryActivity.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java index b53f5fd98..94bf18c15 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java @@ -231,9 +231,7 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView public void logMessageContent(byte[] value) { if (value != null) { - for (byte b : value) { - LOG.warn("DATA: " + String.format("0x%2x", b) + " - " + (char) (b & 0xff)); - } + LOG.warn("DATA: " + GB.hexdump(value, 0, value.length)); } } @@ -630,7 +628,7 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView super.onPause(); stopBTDiscovery(); stopBTLEDiscovery(); - if (GB.supportsBluetoothLE()) { + if (GBApplication.isRunningLollipopOrLater()) { stopNewBTLEDiscovery(); } } From 67a1191a3c89e22d7d67708a7935441d20d3bd47 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sun, 22 Jul 2018 16:11:32 +0200 Subject: [PATCH 035/211] Use UTC timezone in GPX points Fixes #1152 --- .../gadgetbridge/export/GPXExporter.java | 2 +- .../gadgetbridge/util/DateTimeUtils.java | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java index 323575782..2773f9208 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java @@ -131,7 +131,7 @@ public class GPXExporter implements ActivityTrackExporter { ser.attribute(NS_DEFAULT, "lon", formatLocation(location.getLongitude())); ser.attribute(NS_DEFAULT, "lat", formatLocation(location.getLatitude())); ser.startTag(NS_DEFAULT, "ele").text(formatLocation(location.getAltitude())).endTag(NS_DEFAULT, "ele"); - ser.startTag(NS_DEFAULT, "time").text(formatTime(point.getTime())).endTag(NS_DEFAULT, "time"); + ser.startTag(NS_DEFAULT, "time").text(DateTimeUtils.formatIso8601UTC(point.getTime())).endTag(NS_DEFAULT, "time"); String description = point.getDescription(); if (description != null) { ser.startTag(NS_DEFAULT, "desc").text(description).endTag(NS_DEFAULT, "desc"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java index b9a577ce8..2977a56fa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java @@ -51,7 +51,12 @@ public class DateTimeUtils { @Override public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) { StringBuffer rfcFormat = super.format(date, toAppendTo, pos); - return rfcFormat.insert(rfcFormat.length() - 2, ":"); + if (this.getTimeZone().equals(TimeZone.getTimeZone("UTC"))) { + rfcFormat.setLength(rfcFormat.length()-5); + return rfcFormat.append("Z"); + } else { + return rfcFormat.insert(rfcFormat.length() - 2, ":"); + } } }; //no public access, we have to workaround Android bugs @@ -64,6 +69,17 @@ public class DateTimeUtils { if(GBApplication.isRunningNougatOrLater()){ return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.US).format(date); } + ISO_8601_FORMAT.setTimeZone(TimeZone.getDefault()); + return ISO_8601_FORMAT.format(date); + } + + public static String formatIso8601UTC(Date date) { + if(GBApplication.isRunningNougatOrLater()){ + final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.US); + sdf.setTimeZone(TimeZone.getTimeZone("UTC")); + return sdf.format(date); + } + ISO_8601_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); return ISO_8601_FORMAT.format(date); } From 2da6749a4091a23ef1560adfd7161bd40bd674c7 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sun, 22 Jul 2018 16:12:09 +0200 Subject: [PATCH 036/211] Add activity kind (if known) to gpx filename Fixes #1161 --- .../FetchSportsDetailsOperation.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchSportsDetailsOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchSportsDetailsOperation.java index 721e4867a..5700a45dc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchSportsDetailsOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchSportsDetailsOperation.java @@ -30,12 +30,14 @@ import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.Logging; +import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary; import nodomain.freeyourgadget.gadgetbridge.export.ActivityTrackExporter; import nodomain.freeyourgadget.gadgetbridge.export.GPXExporter; +import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityTrack; import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; @@ -99,7 +101,22 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { try { ActivityTrack track = parser.parse(buffer.toByteArray()); ActivityTrackExporter exporter = createExporter(); - String fileName = FileUtils.makeValidFileName("gadgetbridge-track-" + DateTimeUtils.formatIso8601(summary.getStartTime()) + ".gpx"); + String trackType = "track"; + switch (summary.getActivityKind()) { + case ActivityKind.TYPE_CYCLING: + trackType = getContext().getString(R.string.activity_type_biking); + break; + case ActivityKind.TYPE_RUNNING: + trackType = getContext().getString(R.string.activity_type_running); + break; + case ActivityKind.TYPE_WALKING: + trackType = getContext().getString(R.string.activity_type_walking); + break; + case ActivityKind.TYPE_SWIMMING: + trackType = getContext().getString(R.string.activity_type_swimming); + break; + } + String fileName = FileUtils.makeValidFileName("gadgetbridge-"+trackType.toLowerCase()+"-" + DateTimeUtils.formatIso8601(summary.getStartTime()) + ".gpx"); File targetFile = new File(FileUtils.getExternalFilesDir(), fileName); try { From 8b445bab20ec0445184c950cc1820922e0d749c4 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 22 Jul 2018 16:31:38 +0200 Subject: [PATCH 037/211] Bump version, add changelog --- CHANGELOG.md | 7 +++++++ app/build.gradle | 4 ++-- app/src/main/res/xml/changelog_master.xml | 7 +++++++ fastlane/metadata/android/en-US/changelogs/135.txt | 5 +++++ 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/135.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 455bc44d9..8d6210945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ### Changelog +#### Version 0.28.1 +* Fix wrong weather icon mapping in rare cases +* Fix device discovery on Android 4.4 +* Amazfit Bip: Use UTC in gpx tracks for better compatibility with external software +* Amazfit Bip: Add the (localized) activity type to the gpx filename +* Amazfit Bip: Fix weather on latest firmwares + #### Version 0.28.0 * Initial support for ZeTime * Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme diff --git a/app/build.gradle b/app/build.gradle index 13bb7b231..26d186448 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,8 +25,8 @@ android { targetSdkVersion 27 // Note: always bump BOTH versionCode and versionName! - versionName "0.28.0" - versionCode 134 + versionName "0.28.1" + versionCode 135 vectorDrawables.useSupportLibrary = true } buildTypes { diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index 64ce04aec..65decd4ac 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -1,5 +1,12 @@ + + Fix wrong weather icon mapping in rare cases + Fix device discovery on Android 4.4 + Amazfit Bip: Use UTC in gpx tracks for better compatibility with external software + Amazfit Bip: Add the (localized) activity type to the gpx filename + Amazfit Bip: Fix weather on latest firmwares + Initial support for ZeTime Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme diff --git a/fastlane/metadata/android/en-US/changelogs/135.txt b/fastlane/metadata/android/en-US/changelogs/135.txt new file mode 100644 index 000000000..f71dfa789 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/135.txt @@ -0,0 +1,5 @@ +* Fix wrong weather icon mapping in rare cases +* Fix device discovery on Android 4.4 +* Amazfit Bip: Use UTC in gpx tracks for better compatibility with external software +* Amazfit Bip: Add the (localized) activity type to the gpx filename +* Amazfit Bip: Fix weather on latest firmwares From 872a91b0b5e89f1558733d8064165719a0b57b3d Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 22 Jul 2018 16:39:37 +0200 Subject: [PATCH 038/211] Fix "Amazfit Bit" typo --- README.md | 2 +- app/src/main/res/values-pt-rBR/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2ef0d14c1..1ae6ce35c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Gadgetbridge ============ Gadgetbridge is an Android (4.4+) application which will allow you to use your -Pebble, Mi Band, Amazfit Bit and HPlus device (and more) without the vendor's closed source application +Pebble, Mi Band, Amazfit Bip and HPlus device (and more) without the vendor's closed source application and without the need to create an account and transmit any of your data to the vendor's servers. diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 615bec7f0..a6b89a5b4 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -388,7 +388,7 @@ Intervalo de exportação Exportar a cada %d hora(s) - Ajustes do Amazfit Bit + Ajustes do Amazfit Bip Permita que seu dispositivo seja detectado. Os dispositivos já pareados não serão detectados. Para o Android 6 ou superior, é necessário habilitar a localização de GPS. Desative o Privacy Guard para o Gadgetbridge, pois o telefone poderá travar ou reiniciar caso esteja ativo. Se nenhum dispositivo for encontrado após alguns minutos, tente novamente após reiniciar seu aparelho telefônico. Medição diária dos batimentos cardíacos A cada minuto From 63cb70ac9a42423ef0534800004ebdb05cfdcc84 Mon Sep 17 00:00:00 2001 From: dakhnod Date: Mon, 23 Jul 2018 02:24:38 +0200 Subject: [PATCH 039/211] Fix missing sourceAppID field --- .../freeyourgadget/gadgetbridge/impl/GBDeviceService.java | 3 ++- .../freeyourgadget/gadgetbridge/model/DeviceService.java | 1 + .../gadgetbridge/service/DeviceCommunicationService.java | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index 71155069e..a2589679b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -142,7 +142,8 @@ public class GBDeviceService implements DeviceService { .putExtra(EXTRA_NOTIFICATION_ID, notificationSpec.id) .putExtra(EXTRA_NOTIFICATION_TYPE, notificationSpec.type) .putExtra(EXTRA_NOTIFICATION_SOURCENAME, notificationSpec.sourceName) - .putExtra(EXTRA_NOTIFICATION_PEBBLE_COLOR, notificationSpec.pebbleColor); + .putExtra(EXTRA_NOTIFICATION_PEBBLE_COLOR, notificationSpec.pebbleColor) + .putExtra(EXTRA_NOTIFICATION_SOURCEAPPID, notificationSpec.sourceAppId); invokeService(intent); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index 19b29939c..09fcc3b32 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -71,6 +71,7 @@ public interface DeviceService extends EventHandler { String EXTRA_NOTIFICATION_PHONENUMBER = "notification_phonenumber"; String EXTRA_NOTIFICATION_SENDER = "notification_sender"; String EXTRA_NOTIFICATION_SOURCENAME = "notification_sourcename"; + String EXTRA_NOTIFICATION_SOURCEAPPID = "notification_sourceappid"; String EXTRA_NOTIFICATION_SUBJECT = "notification_subject"; String EXTRA_NOTIFICATION_TITLE = "notification_title"; String EXTRA_NOTIFICATION_TYPE = "notification_type"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 3003a9394..161e0f20e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -148,6 +148,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOT import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_PEBBLE_COLOR; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_PHONENUMBER; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SENDER; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SOURCEAPPID; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SOURCENAME; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SUBJECT; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TITLE; @@ -348,6 +349,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere notificationSpec.pebbleColor = (byte) intent.getSerializableExtra(EXTRA_NOTIFICATION_PEBBLE_COLOR); notificationSpec.id = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); notificationSpec.flags = intent.getIntExtra(EXTRA_NOTIFICATION_FLAGS, 0); + notificationSpec.sourceAppId = intent.getStringExtra(EXTRA_NOTIFICATION_SOURCEAPPID); if (notificationSpec.type == NotificationType.GENERIC_SMS && notificationSpec.phoneNumber != null) { notificationSpec.id = mRandom.nextInt(); // FIXME: add this in external SMS Receiver? From 63231ec49aef0b71d3d25f7136dfe345c62a70ff Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Fri, 27 Jul 2018 13:14:28 +0200 Subject: [PATCH 040/211] Revert "remove unused getPrimaryActivity() from coodinators, mark Mi Band HRX as non-heartrate" This reverts commit 495ba81edc229f7de574ddbb6ffdaf8a71e5618c. See discussion in https://github.com/Freeyourgadget/Gadgetbridge/issues/1165 --- .../gadgetbridge/devices/DeviceCoordinator.java | 9 +++++++++ .../gadgetbridge/devices/UnknownDeviceCoordinator.java | 5 +++++ .../gadgetbridge/devices/hplus/HPlusCoordinator.java | 5 +++++ .../devices/huami/miband2/MiBand2HRXCoordinator.java | 7 +++++++ .../gadgetbridge/devices/jyou/TeclastH30Coordinator.java | 5 +++++ .../devices/liveview/LiveviewCoordinator.java | 5 +++++ .../gadgetbridge/devices/miband/MiBandCoordinator.java | 5 +++++ .../gadgetbridge/devices/no1f1/No1F1Coordinator.java | 6 ++++++ .../gadgetbridge/devices/pebble/PebbleCoordinator.java | 5 +++++ .../devices/vibratissimo/VibratissimoCoordinator.java | 5 +++++ 10 files changed, 57 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java index 45d4150eb..d02f54ccb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java @@ -123,6 +123,15 @@ public interface DeviceCoordinator { @Nullable Class getPairingActivity(); + /** + * Returns the Activity class that will be used as the primary activity + * for the given device. + * + * @return the primary activity class, or null if none + */ + @Nullable + Class getPrimaryActivity(); + /** * Returns true if activity data fetching is supported by the device * (with this coordinator). diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java index e35417449..171908c1a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java @@ -112,6 +112,11 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator { return ControlCenterv2.class; } + @Override + public Class getPrimaryActivity() { + return null; + } + @Override public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { return new UnknownSampleProvider(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java index 44499980b..036db0110 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java @@ -113,6 +113,11 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator { return null; } + @Override + public Class getPrimaryActivity() { + return ChartsActivity.class; + } + @Override public InstallHandler findInstallHandler(Uri uri, Context context) { return null; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java index f45879b25..65ff8371b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java @@ -16,10 +16,12 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2; +import android.app.Activity; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.net.Uri; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,4 +76,9 @@ public class MiBand2HRXCoordinator extends HuamiCoordinator { return false; } + @Nullable + @Override + public Class getPrimaryActivity() { + return null; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java index 4d3e98dbd..f5f26d2ee 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java @@ -99,6 +99,11 @@ public class TeclastH30Coordinator extends AbstractDeviceCoordinator { return null; } + @Override + public Class getPrimaryActivity() { + return ChartsActivity.class; + } + @Override public InstallHandler findInstallHandler(Uri uri, Context context) { return null; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java index 7b93b6913..41ccdbae6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java @@ -54,6 +54,11 @@ public class LiveviewCoordinator extends AbstractDeviceCoordinator { return null; } + @Override + public Class getPrimaryActivity() { + return null; + } + @Override public InstallHandler findInstallHandler(Uri uri, Context context) { return null; 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 f9a2063c4..0682f722e 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 @@ -110,6 +110,11 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator { return MiBandPairingActivity.class; } + @Override + public Class getPrimaryActivity() { + return ChartsActivity.class; + } + @Override public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { return new MiBandSampleProvider(device, session); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java index 373f59aac..7f9bfeb3f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java @@ -82,6 +82,12 @@ public class No1F1Coordinator extends AbstractDeviceCoordinator { return null; } + @Nullable + @Override + public Class getPrimaryActivity() { + return ChartsActivity.class; + } + @Override public boolean supportsActivityDataFetching() { return true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java index d94a490f7..322dccc7b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java @@ -66,6 +66,11 @@ public class PebbleCoordinator extends AbstractDeviceCoordinator { return PebblePairingActivity.class; } + @Override + public Class getPrimaryActivity() { + return AppManagerActivity.class; + } + @Override protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException { Long deviceId = device.getId(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java index 55ca064bd..e99fc48d5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java @@ -55,6 +55,11 @@ public class VibratissimoCoordinator extends AbstractDeviceCoordinator { return null; } + @Override + public Class getPrimaryActivity() { + return VibrationActivity.class; + } + @Override public InstallHandler findInstallHandler(Uri uri, Context context) { return null; From 2147ab49482b4b607c9ce30e7c30d5c0f493e6bf Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Fri, 27 Jul 2018 15:13:21 +0200 Subject: [PATCH 041/211] Revert "Revert "remove unused getPrimaryActivity() from coodinators, mark Mi Band HRX as non-heartrate"" This reverts commit 63231ec49aef0b71d3d25f7136dfe345c62a70ff. Please note that the comment of the reverted commit was inaccurate, as the Mi Band HRX was left untouched by it and is left untouched byt this commit. --- .../gadgetbridge/devices/DeviceCoordinator.java | 9 --------- .../gadgetbridge/devices/UnknownDeviceCoordinator.java | 5 ----- .../gadgetbridge/devices/hplus/HPlusCoordinator.java | 5 ----- .../devices/huami/miband2/MiBand2HRXCoordinator.java | 7 ------- .../gadgetbridge/devices/jyou/TeclastH30Coordinator.java | 5 ----- .../devices/liveview/LiveviewCoordinator.java | 5 ----- .../gadgetbridge/devices/miband/MiBandCoordinator.java | 5 ----- .../gadgetbridge/devices/no1f1/No1F1Coordinator.java | 6 ------ .../gadgetbridge/devices/pebble/PebbleCoordinator.java | 5 ----- .../devices/vibratissimo/VibratissimoCoordinator.java | 5 ----- 10 files changed, 57 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java index d02f54ccb..45d4150eb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java @@ -123,15 +123,6 @@ public interface DeviceCoordinator { @Nullable Class getPairingActivity(); - /** - * Returns the Activity class that will be used as the primary activity - * for the given device. - * - * @return the primary activity class, or null if none - */ - @Nullable - Class getPrimaryActivity(); - /** * Returns true if activity data fetching is supported by the device * (with this coordinator). diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java index 171908c1a..e35417449 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java @@ -112,11 +112,6 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator { return ControlCenterv2.class; } - @Override - public Class getPrimaryActivity() { - return null; - } - @Override public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { return new UnknownSampleProvider(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java index 036db0110..44499980b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java @@ -113,11 +113,6 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator { return null; } - @Override - public Class getPrimaryActivity() { - return ChartsActivity.class; - } - @Override public InstallHandler findInstallHandler(Uri uri, Context context) { return null; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java index 65ff8371b..f45879b25 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2HRXCoordinator.java @@ -16,12 +16,10 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2; -import android.app.Activity; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.net.Uri; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -76,9 +74,4 @@ public class MiBand2HRXCoordinator extends HuamiCoordinator { return false; } - @Nullable - @Override - public Class getPrimaryActivity() { - return null; - } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java index f5f26d2ee..4d3e98dbd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/jyou/TeclastH30Coordinator.java @@ -99,11 +99,6 @@ public class TeclastH30Coordinator extends AbstractDeviceCoordinator { return null; } - @Override - public Class getPrimaryActivity() { - return ChartsActivity.class; - } - @Override public InstallHandler findInstallHandler(Uri uri, Context context) { return null; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java index 41ccdbae6..7b93b6913 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java @@ -54,11 +54,6 @@ public class LiveviewCoordinator extends AbstractDeviceCoordinator { return null; } - @Override - public Class getPrimaryActivity() { - return null; - } - @Override public InstallHandler findInstallHandler(Uri uri, Context context) { return null; 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 0682f722e..f9a2063c4 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 @@ -110,11 +110,6 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator { return MiBandPairingActivity.class; } - @Override - public Class getPrimaryActivity() { - return ChartsActivity.class; - } - @Override public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { return new MiBandSampleProvider(device, session); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java index 7f9bfeb3f..373f59aac 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/no1f1/No1F1Coordinator.java @@ -82,12 +82,6 @@ public class No1F1Coordinator extends AbstractDeviceCoordinator { return null; } - @Nullable - @Override - public Class getPrimaryActivity() { - return ChartsActivity.class; - } - @Override public boolean supportsActivityDataFetching() { return true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java index 322dccc7b..d94a490f7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java @@ -66,11 +66,6 @@ public class PebbleCoordinator extends AbstractDeviceCoordinator { return PebblePairingActivity.class; } - @Override - public Class getPrimaryActivity() { - return AppManagerActivity.class; - } - @Override protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException { Long deviceId = device.getId(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java index e99fc48d5..55ca064bd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java @@ -55,11 +55,6 @@ public class VibratissimoCoordinator extends AbstractDeviceCoordinator { return null; } - @Override - public Class getPrimaryActivity() { - return VibrationActivity.class; - } - @Override public InstallHandler findInstallHandler(Uri uri, Context context) { return null; From a43934651a25ed947b520dca7df52734112710c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Thu, 26 Jul 2018 20:57:12 +0100 Subject: [PATCH 042/211] Allow devices to not support being found --- .../gadgetbridge/adapter/GBDeviceAdapterv2.java | 2 +- .../gadgetbridge/devices/DeviceCoordinator.java | 6 ++++++ .../gadgetbridge/devices/UnknownDeviceCoordinator.java | 5 +++++ .../gadgetbridge/devices/hplus/HPlusCoordinator.java | 5 +++++ .../gadgetbridge/devices/huami/HuamiCoordinator.java | 5 +++++ .../gadgetbridge/devices/jyou/TeclastH30Coordinator.java | 5 +++++ .../gadgetbridge/devices/liveview/LiveviewCoordinator.java | 5 +++++ .../gadgetbridge/devices/miband/MiBandCoordinator.java | 5 +++++ .../gadgetbridge/devices/no1f1/No1F1Coordinator.java | 5 +++++ .../gadgetbridge/devices/pebble/PebbleCoordinator.java | 5 +++++ .../devices/vibratissimo/VibratissimoCoordinator.java | 5 +++++ .../gadgetbridge/devices/xwatch/XWatchCoordinator.java | 5 +++++ .../gadgetbridge/devices/zetime/ZeTimeCoordinator.java | 5 +++++ 13 files changed, 62 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index 12087694e..449453084 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -249,7 +249,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter Date: Fri, 27 Jul 2018 14:39:01 +0100 Subject: [PATCH 043/211] Add missing break --- .../gadgetbridge/service/DeviceSupportFactory.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java index 33e9f15d5..00ee14f23 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java @@ -152,7 +152,8 @@ public class DeviceSupportFactory { break; case XWATCH: deviceSupport = new ServiceDeviceSupport(new XWatchSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); - case ZETIME: + break; + case ZETIME: deviceSupport = new ServiceDeviceSupport(new ZeTimeDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; } From 14dc3ad9c5ec9511147300a08063250722f7f22c Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 29 Jul 2018 19:34:34 +0300 Subject: [PATCH 044/211] ID115: add supportsFindDevice() function --- .../gadgetbridge/devices/id115/ID115Coordinator.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java index b791d269f..7e7c174bc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java @@ -132,4 +132,9 @@ public class ID115Coordinator extends AbstractDeviceCoordinator { public boolean supportsWeather() { return false; } + + @Override + public boolean supportsFindDevice() { + return false; + } } From 4ee1e6cfca4d1086a85873f3fe9c1f4ba812faa6 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 29 Jul 2018 19:49:45 +0300 Subject: [PATCH 045/211] ID115: generate entities for activity samples --- .../gadgetbridge/daogen/GBDaoGenerator.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java index 8aed0d76e..4ef0d8a1b 100644 --- a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java +++ b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java @@ -70,6 +70,7 @@ public class GBDaoGenerator { addNo1F1ActivitySample(schema, user, device); addXWatchActivitySample(schema, user, device); addZeTimeActivitySample(schema, user, device); + addID115ActivitySample(schema, user, device); addCalendarSyncState(schema, device); @@ -301,6 +302,18 @@ public class GBDaoGenerator { return activitySample; } + private static Entity addID115ActivitySample(Schema schema, Entity user, Entity device) { + Entity activitySample = addEntity(schema, "ID115ActivitySample"); + activitySample.implementsSerializable(); + addCommonActivitySampleProperties("AbstractActivitySample", activitySample, user, device); + activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE); + activitySample.addIntProperty(SAMPLE_RAW_KIND).notNull().codeBeforeGetterAndSetter(OVERRIDE); + activitySample.addIntProperty("caloriesBurnt"); + activitySample.addIntProperty("distanceMeters"); + activitySample.addIntProperty("activeTimeMinutes"); + return activitySample; + } + private static void addCommonActivitySampleProperties(String superClass, Entity activitySample, Entity user, Entity device) { activitySample.setSuperclass(superClass); activitySample.addImport(MAIN_PACKAGE + ".devices.SampleProvider"); From caabe0ed0a45327b25ee7953c9742ac9cdfdc19b Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 29 Jul 2018 21:25:41 +0300 Subject: [PATCH 046/211] ID115: use SendNotificationOperation for message and call notifications --- .../devices/id115/AbstractID115Operation.java | 80 ++++++++ .../service/devices/id115/ID115Support.java | 175 +--------------- .../id115/SendNotificationOperation.java | 193 ++++++++++++++++++ 3 files changed, 283 insertions(+), 165 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/AbstractID115Operation.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/SendNotificationOperation.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/AbstractID115Operation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/AbstractID115Operation.java new file mode 100644 index 000000000..b328cb0ec --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/AbstractID115Operation.java @@ -0,0 +1,80 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.id115; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.widget.Toast; + +import java.io.IOException; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Constants; +import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEOperation; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public abstract class AbstractID115Operation extends AbstractBTLEOperation { + protected BluetoothGattCharacteristic controlCharacteristic = null; + protected BluetoothGattCharacteristic notifyCharacteristic = null; + + protected AbstractID115Operation(ID115Support support) { + super(support); + + if (isHealthOperation()) { + controlCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_WRITE_HEALTH); + notifyCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_NOTIFY_HEALTH); + } else { + controlCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_WRITE_NORMAL); + notifyCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_NOTIFY_NORMAL); + } + } + + @Override + protected void prePerform() throws IOException { + super.prePerform(); + getDevice().setBusyTask("AbstractID115Operation starting..."); // mark as busy quickly to avoid interruptions from the outside + TransactionBuilder builder = performInitialized("disabling some notifications"); + enableNotifications(builder, true); + builder.queue(getQueue()); + } + + @Override + protected void operationFinished() { + operationStatus = OperationStatus.FINISHED; + if (getDevice() != null && getDevice().isConnected()) { + unsetBusy(); + try { + TransactionBuilder builder = performInitialized("reenabling disabled notifications"); + enableNotifications(builder, false); + builder.setGattCallback(null); // unset ourselves from being the queue's gatt callback + builder.queue(getQueue()); + } catch (IOException ex) { + GB.toast(getContext(), "Error enabling ID115 notifications, you may need to connect and disconnect", Toast.LENGTH_LONG, GB.ERROR, ex); + } + } + } + + @Override + public boolean onCharacteristicChanged(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic) { + UUID characteristicUUID = characteristic.getUuid(); + if (notifyCharacteristic.getUuid().equals(characteristicUUID)) { + handleResponse(characteristic.getValue()); + return true; + } else { + return super.onCharacteristicChanged(gatt, characteristic); + } + } + + void enableNotifications(TransactionBuilder builder, boolean enable) { + if (isHealthOperation()) { + builder.notify(getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_NOTIFY_HEALTH), enable); + } else { + builder.notify(getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_NOTIFY_NORMAL), enable); + } + } + + abstract boolean isHealthOperation(); + + abstract void handleResponse(byte[] data); +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index 667819345..1fe8dd4ef 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -37,7 +37,6 @@ public class ID115Support extends AbstractBTLEDeviceSupport { private static final Logger LOG = LoggerFactory.getLogger(ID115Support.class); public BluetoothGattCharacteristic normalWriteCharacteristic = null; - public BluetoothGattCharacteristic normalNotifyCharacteristic = null; public BluetoothGattCharacteristic healthWriteCharacteristic = null; byte[] currentNotificationBuffer; @@ -55,14 +54,10 @@ public class ID115Support extends AbstractBTLEDeviceSupport { @Override protected TransactionBuilder initializeDevice(TransactionBuilder builder) { normalWriteCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_WRITE_NORMAL); - normalNotifyCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_NOTIFY_NORMAL); healthWriteCharacteristic = getCharacteristic(ID115Constants.UUID_CHARACTERISTIC_WRITE_HEALTH); builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); - builder.setGattCallback(this); - builder.notify(normalNotifyCharacteristic, true); - setTime(builder) .setWrist(builder) .setScreenOrientation(builder) @@ -79,7 +74,11 @@ public class ID115Support extends AbstractBTLEDeviceSupport { @Override public void onNotification(NotificationSpec notificationSpec) { - sendMessageNotification(notificationSpec); + try { + new SendNotificationOperation(this, notificationSpec).perform(); + } catch (IOException ex) { + LOG.error("Unable to send ID115 notification", ex); + } } @Override @@ -106,7 +105,11 @@ public class ID115Support extends AbstractBTLEDeviceSupport { @Override public void onSetCallState(CallSpec callSpec) { if (callSpec.command == CallSpec.CALL_INCOMING) { - sendCallNotification(callSpec); + try { + new SendNotificationOperation(this, callSpec).perform(); + } catch (IOException ex) { + LOG.error("Unable to send ID115 notification", ex); + } } else { sendStopCallNotification(); } @@ -241,40 +244,6 @@ public class ID115Support extends AbstractBTLEDeviceSupport { } - @Override - public boolean onCharacteristicChanged(BluetoothGatt gatt, - BluetoothGattCharacteristic characteristic) { - if (super.onCharacteristicChanged(gatt, characteristic)) { - return true; - } - - UUID characteristicUUID = characteristic.getUuid(); - byte[] data = characteristic.getValue(); - if (!characteristicUUID.equals(ID115Constants.UUID_CHARACTERISTIC_NOTIFY_NORMAL)) { - return false; - } - - if (data.length < 2) { - LOG.warn("short GATT response"); - return false; - } - if (data[0] == ID115Constants.CMD_ID_NOTIFY) { - if (data.length < 4) { - LOG.warn("short GATT response for NOTIFY"); - return false; - } - if (data[1] == currentNotificationType) { - if (data[3] == currentNotificationIndex) { - if (currentNotificationIndex != currentNotificationSize) { - sendNotificationChunk(currentNotificationIndex + 1); - return true; - } - } - } - } - return false; - } - private void setInitialized(TransactionBuilder builder) { builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext())); } @@ -359,23 +328,6 @@ public class ID115Support extends AbstractBTLEDeviceSupport { return this; } - void sendCallNotification(CallSpec callSpec) { - String number = ""; - if (callSpec.number != null) { - number = callSpec.number; - } - - String name = ""; - if (callSpec.name != null) { - name = callSpec.name; - } - - currentNotificationBuffer = encodeCallNotification(name, number); - currentNotificationSize = (currentNotificationBuffer.length + 15) / 16; - currentNotificationType = ID115Constants.CMD_KEY_NOTIFY_CALL; - sendNotificationChunk(1); - } - void sendStopCallNotification() { try { TransactionBuilder builder = performInitialized("stop_call_notification"); @@ -389,111 +341,4 @@ public class ID115Support extends AbstractBTLEDeviceSupport { LOG.warn("Unable to stop call notification", e); } } - - void sendMessageNotification(NotificationSpec notificationSpec) { - String phone = ""; - if (notificationSpec.phoneNumber != null) { - phone = notificationSpec.phoneNumber; - } - - String title = ""; - if (notificationSpec.sender != null) { - title = notificationSpec.sender; - } else if (notificationSpec.title != null) { - title = notificationSpec.title; - } else if (notificationSpec.subject != null) { - title = notificationSpec.subject; - } - - String text = ""; - if (notificationSpec.body != null) { - text = notificationSpec.body; - } - - currentNotificationBuffer = encodeMessageNotification(notificationSpec.type, title, phone, text); - currentNotificationSize = (currentNotificationBuffer.length + 15) / 16; - currentNotificationType = ID115Constants.CMD_KEY_NOTIFY_MSG; - sendNotificationChunk(1); - } - - void sendNotificationChunk(int chunkIndex) { - currentNotificationIndex = chunkIndex; - - int offset = (chunkIndex - 1) * 16; - int tailSize = currentNotificationBuffer.length - offset; - int chunkSize = (tailSize > 16)? 16 : tailSize; - - byte raw[] = new byte[16]; - System.arraycopy(currentNotificationBuffer, offset, raw, 0, chunkSize); - - try { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - outputStream.write(ID115Constants.CMD_ID_NOTIFY); - outputStream.write(currentNotificationType); - outputStream.write((byte)currentNotificationSize); - outputStream.write((byte)currentNotificationIndex); - outputStream.write(raw); - byte cmd[] = outputStream.toByteArray(); - - TransactionBuilder builder = performInitialized("notification"); - builder.write(normalWriteCharacteristic, cmd); - performConnected(builder.getTransaction()); - } catch (IOException e) { - LOG.warn("Unable to send notification chunk", e); - } - } - - byte[] encodeCallNotification(String name, String phone) { - if (name.length() > 20) { - name = name.substring(0, 20); - } - if (phone.length() > 20) { - phone = phone.substring(0, 20); - } - - byte[] name_bytes = name.getBytes(StandardCharsets.UTF_8); - byte[] phone_bytes = phone.getBytes(StandardCharsets.UTF_8); - - try { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - outputStream.write((byte) phone_bytes.length); - outputStream.write((byte) name_bytes.length); - outputStream.write(phone_bytes); - outputStream.write(name_bytes); - return outputStream.toByteArray(); - } catch (IOException e) { - return null; - } - } - - byte[] encodeMessageNotification(NotificationType type, String title, String phone, String text) { - if (title.length() > 20) { - title = title.substring(0, 20); - } - if (phone.length() > 20) { - phone = phone.substring(0, 20); - } - if (text.length() > 20) { - text = text.substring(0, 20); - } - byte[] title_bytes = title.getBytes(StandardCharsets.UTF_8); - byte[] phone_bytes = phone.getBytes(StandardCharsets.UTF_8); - byte[] text_bytes = text.getBytes(StandardCharsets.UTF_8); - - byte nativeType = ID115Constants.getNotificationType(type); - - try { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - outputStream.write(nativeType); - outputStream.write((byte) text_bytes.length); - outputStream.write((byte) phone_bytes.length); - outputStream.write((byte) title_bytes.length); - outputStream.write(phone_bytes); - outputStream.write(title_bytes); - outputStream.write(text_bytes); - return outputStream.toByteArray(); - } catch (IOException e) { - return null; - } - } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/SendNotificationOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/SendNotificationOperation.java new file mode 100644 index 000000000..b7f468cd6 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/SendNotificationOperation.java @@ -0,0 +1,193 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.id115; + +import android.widget.Toast; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Constants; +import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public class SendNotificationOperation extends AbstractID115Operation { + private static final Logger LOG = LoggerFactory.getLogger(SendNotificationOperation.class); + + byte[] currentNotificationBuffer; + int currentNotificationSize; + int currentNotificationIndex; + byte currentNotificationType; + + SendNotificationOperation(ID115Support support, NotificationSpec notificationSpec) + { + super(support); + + String phone = ""; + if (notificationSpec.phoneNumber != null) { + phone = notificationSpec.phoneNumber; + } + + String title = ""; + if (notificationSpec.sender != null) { + title = notificationSpec.sender; + } else if (notificationSpec.title != null) { + title = notificationSpec.title; + } else if (notificationSpec.subject != null) { + title = notificationSpec.subject; + } + + String text = ""; + if (notificationSpec.body != null) { + text = notificationSpec.body; + } + + currentNotificationBuffer = encodeMessageNotification(notificationSpec.type, title, phone, text); + currentNotificationSize = (currentNotificationBuffer.length + 15) / 16; + currentNotificationType = ID115Constants.CMD_KEY_NOTIFY_MSG; + } + + SendNotificationOperation(ID115Support support, CallSpec callSpec) + { + super(support); + + String number = ""; + if (callSpec.number != null) { + number = callSpec.number; + } + + String name = ""; + if (callSpec.name != null) { + name = callSpec.name; + } + + currentNotificationBuffer = encodeCallNotification(name, number); + currentNotificationSize = (currentNotificationBuffer.length + 15) / 16; + currentNotificationType = ID115Constants.CMD_KEY_NOTIFY_CALL; + } + + @Override + boolean isHealthOperation() { + return false; + } + + @Override + protected void doPerform() throws IOException { + sendNotificationChunk(1); + } + + void sendNotificationChunk(int chunkIndex) throws IOException { + currentNotificationIndex = chunkIndex; + + int offset = (chunkIndex - 1) * 16; + int tailSize = currentNotificationBuffer.length - offset; + int chunkSize = (tailSize > 16)? 16 : tailSize; + + byte raw[] = new byte[16]; + System.arraycopy(currentNotificationBuffer, offset, raw, 0, chunkSize); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + outputStream.write(ID115Constants.CMD_ID_NOTIFY); + outputStream.write(currentNotificationType); + outputStream.write((byte)currentNotificationSize); + outputStream.write((byte)currentNotificationIndex); + outputStream.write(raw); + byte cmd[] = outputStream.toByteArray(); + + TransactionBuilder builder = performInitialized("send notification chunk"); + builder.write(controlCharacteristic, cmd); + builder.queue(getQueue()); + } + + void handleResponse(byte[] data) { + if (!isOperationRunning()) { + LOG.error("ignoring notification because operation is not running. Data length: " + data.length); + getSupport().logMessageContent(data); + return; + } + + if (data.length < 2) { + LOG.warn("short GATT response"); + return; + } + if (data[0] == ID115Constants.CMD_ID_NOTIFY) { + if (data.length < 4) { + LOG.warn("short GATT response for NOTIFY"); + return; + } + if (data[1] == currentNotificationType) { + if (data[3] == currentNotificationIndex) { + if (currentNotificationIndex != currentNotificationSize) { + try { + sendNotificationChunk(currentNotificationIndex + 1); + } catch (IOException ex) { + GB.toast(getContext(), "Error sending ID115 notification, you may need to connect and disconnect", Toast.LENGTH_LONG, GB.ERROR, ex); + } + } else { + LOG.info("Notification transfer has finished."); + operationFinished(); + } + } + } + } + } + + byte[] encodeCallNotification(String name, String phone) { + if (name.length() > 20) { + name = name.substring(0, 20); + } + if (phone.length() > 20) { + phone = phone.substring(0, 20); + } + + byte[] name_bytes = name.getBytes(StandardCharsets.UTF_8); + byte[] phone_bytes = phone.getBytes(StandardCharsets.UTF_8); + + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + outputStream.write((byte) phone_bytes.length); + outputStream.write((byte) name_bytes.length); + outputStream.write(phone_bytes); + outputStream.write(name_bytes); + return outputStream.toByteArray(); + } catch (IOException e) { + return null; + } + } + + byte[] encodeMessageNotification(NotificationType type, String title, String phone, String text) { + if (title.length() > 20) { + title = title.substring(0, 20); + } + if (phone.length() > 20) { + phone = phone.substring(0, 20); + } + if (text.length() > 20) { + text = text.substring(0, 20); + } + byte[] title_bytes = title.getBytes(StandardCharsets.UTF_8); + byte[] phone_bytes = phone.getBytes(StandardCharsets.UTF_8); + byte[] text_bytes = text.getBytes(StandardCharsets.UTF_8); + + byte nativeType = ID115Constants.getNotificationType(type); + + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + outputStream.write(nativeType); + outputStream.write((byte) text_bytes.length); + outputStream.write((byte) phone_bytes.length); + outputStream.write((byte) title_bytes.length); + outputStream.write(phone_bytes); + outputStream.write(title_bytes); + outputStream.write(text_bytes); + return outputStream.toByteArray(); + } catch (IOException e) { + return null; + } + } +} From fd7a0cb124074c7c71d4305cc7e548b5aa4943fd Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Mon, 30 Jul 2018 23:23:13 +0300 Subject: [PATCH 047/211] ID115: fetching activity data --- .../devices/id115/ID115Constants.java | 3 + .../devices/id115/ID115Coordinator.java | 6 +- .../devices/id115/ID115SampleProvider.java | 61 +++++++ .../devices/id115/FetchActivityOperation.java | 160 ++++++++++++++++++ .../service/devices/id115/ID115Support.java | 9 +- 5 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115SampleProvider.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/FetchActivityOperation.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java index 6b4e3c985..e7be5e6ec 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Constants.java @@ -44,6 +44,9 @@ public class ID115Constants { public static final byte CMD_KEY_NOTIFY_STOP = 0x02; public static final byte CMD_KEY_NOTIFY_MSG = 0x03; + // CMD_ID_HEALTH_DATA + public static final byte CMD_KEY_FETCH_ACTIVITY_TODAY = 0x03; + // CMD_ID_DEVICE_RESTART public static final byte CMD_KEY_REBOOT = 0x01; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java index 7e7c174bc..e920287fa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115Coordinator.java @@ -65,17 +65,17 @@ public class ID115Coordinator extends AbstractDeviceCoordinator { @Override public boolean supportsActivityDataFetching() { - return false; + return true; } @Override public boolean supportsActivityTracking() { - return false; + return true; } @Override public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { - return null; + return new ID115SampleProvider(device, session); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115SampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115SampleProvider.java new file mode 100644 index 000000000..83115e350 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/id115/ID115SampleProvider.java @@ -0,0 +1,61 @@ +package nodomain.freeyourgadget.gadgetbridge.devices.id115; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import de.greenrobot.dao.AbstractDao; +import de.greenrobot.dao.Property; +import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; +import nodomain.freeyourgadget.gadgetbridge.entities.ID115ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.entities.ID115ActivitySampleDao; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; + +public class ID115SampleProvider extends AbstractSampleProvider { + public ID115SampleProvider(GBDevice device, DaoSession session) { + super(device, session); + } + + @Override + public AbstractDao getSampleDao() { + return getSession().getID115ActivitySampleDao(); + } + + @Nullable + @Override + protected Property getRawKindSampleProperty() { + return ID115ActivitySampleDao.Properties.RawKind; + } + + @NonNull + @Override + protected Property getTimestampSampleProperty() { + return ID115ActivitySampleDao.Properties.Timestamp; + } + + @NonNull + @Override + protected Property getDeviceIdentifierSampleProperty() { + return ID115ActivitySampleDao.Properties.DeviceId; + } + + @Override + public int normalizeType(int rawType) { + return rawType; + } + + @Override + public int toRawActivityKind(int activityKind) { + return activityKind; + } + + @Override + public float normalizeIntensity(int rawIntensity) { + return rawIntensity; + } + + @Override + public ID115ActivitySample createActivitySample() { + return new ID115ActivitySample(); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/FetchActivityOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/FetchActivityOperation.java new file mode 100644 index 000000000..060ba8b45 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/FetchActivityOperation.java @@ -0,0 +1,160 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.id115; + +import android.widget.Toast; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; +import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Constants; +import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.ID115ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public class FetchActivityOperation extends AbstractID115Operation { + private static final Logger LOG = LoggerFactory.getLogger(FetchActivityOperation.class); + private byte expectedCmd; + private byte expectedSeq; + private ArrayList packets; + + protected FetchActivityOperation(ID115Support support) { + super(support); + } + + @Override + boolean isHealthOperation() { + return true; + } + + @Override + protected void doPerform() throws IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + outputStream.write(ID115Constants.CMD_ID_HEALTH_DATA); + outputStream.write(ID115Constants.CMD_KEY_FETCH_ACTIVITY_TODAY); + outputStream.write(0x01); + outputStream.write(0x00); + outputStream.write(0x00); + byte cmd[] = outputStream.toByteArray(); + + expectedCmd = ID115Constants.CMD_KEY_FETCH_ACTIVITY_TODAY; + expectedSeq = 1; + packets = new ArrayList<>(); + + TransactionBuilder builder = performInitialized("send activity fetch request"); + builder.write(controlCharacteristic, cmd); + builder.queue(getQueue()); + } + + @Override + void handleResponse(byte[] data) { + if (!isOperationRunning()) { + LOG.error("ignoring notification because operation is not running. Data length: " + data.length); + getSupport().logMessageContent(data); + return; + } + + if (data.length < 4) { + LOG.warn("short GATT response"); + return; + } + + if (data[0] == ID115Constants.CMD_ID_HEALTH_DATA) { + if (data[1] == (byte)0xEE) { + LOG.info("Activity data transfer has finished."); + parseAndStore(); + operationFinished(); + } else { + if ((data[1] != expectedCmd) || (data[2] != expectedSeq)) { + GB.toast(getContext(), "Error fetching ID115 activity data, you may need to connect and disconnect", Toast.LENGTH_LONG, GB.ERROR); + operationFinished(); + return; + } + expectedSeq += 1; + + byte payload[] = new byte[data.length - 4]; + System.arraycopy(data, 4, payload, 0, payload.length); + packets.add(payload); + } + } + } + + void parseAndStore() { + if (packets.size() <= 1) { + return; + } + + byte[] header = packets.get(0); + int year = ((header[1] & 0xFF) << 8) | (header[0] & 0xFF); + int month = header[2] & 0xFF; + int day = header[3] & 0xFF; + int sampleDurationMinutes = header[6] & 0xFF; + Calendar calendar = new GregorianCalendar(year, month - 1, day); + int ts = (int)(calendar.getTimeInMillis() / 1000); + int dt = sampleDurationMinutes * 60; + + ArrayList samples = new ArrayList<>(); + + for (int i = 2; i < packets.size(); i++) { + byte[] packet = packets.get(i); + for (int j = 0; j <= packet.length - 5; j += 5) { + byte[] sampleData = new byte[5]; + System.arraycopy(packet, j, sampleData, 0, sampleData.length); + + ID115ActivitySample sample = parseSample(sampleData); + if (sample != null) { + sample.setTimestamp(ts); + sample.setRawKind(ActivityKind.TYPE_ACTIVITY); + samples.add(sample); + } + ts += dt; + } + } + + try (DBHandler dbHandler = GBApplication.acquireDB()) { + ID115ActivitySample[] sampleArray = samples.toArray(new ID115ActivitySample[0]); + long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId(); + long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId(); + for (ID115ActivitySample sample: sampleArray) { + sample.setUserId(userId); + sample.setDeviceId(deviceId); + } + + ID115SampleProvider provider = new ID115SampleProvider(getDevice(), dbHandler.getDaoSession()); + provider.addGBActivitySamples(sampleArray); + } catch (Exception ex) { + GB.toast(getContext(), "Error saving activity data: " + ex.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + } + } + + ID115ActivitySample parseSample(byte[] data) { + int d01 = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF); + int d12 = ((data[2] & 0xFF) << 8) | (data[1] & 0xFF); + int d23 = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF); + int d34 = ((data[4] & 0xFF) << 8) | (data[3] & 0xFF); + int stepCount = (d01 >> 2) & 0xFFF; + int activeTime = (d12 >> 6) & 0xF; + int calories = (d23 >> 2) & 0x3FF; + int distance = (d34 >> 4); + + if (stepCount == 0) { + return null; + } + + ID115ActivitySample sample = new ID115ActivitySample(); + sample.setSteps(stepCount); + sample.setActiveTimeMinutes(activeTime); + sample.setCaloriesBurnt(calories); + sample.setDistanceMeters(distance); + return sample; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index 1fe8dd4ef..95dfb2337 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -64,6 +64,9 @@ public class ID115Support extends AbstractBTLEDeviceSupport { .setGoal(builder) .setInitialized(builder); + getDevice().setFirmwareVersion("N/A"); + getDevice().setFirmwareVersion2("N/A"); + return builder; } @@ -167,7 +170,11 @@ public class ID115Support extends AbstractBTLEDeviceSupport { @Override public void onFetchRecordedData(int dataTypes) { - + try { + new FetchActivityOperation(this).perform(); + } catch (IOException ex) { + LOG.error("Unable to fetch ID115 activity data", ex); + } } @Override From 9a13d5ea4a7f10bd6d4a21e984e46afa350ceb6f Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Mon, 30 Jul 2018 23:24:20 +0300 Subject: [PATCH 048/211] ID115: code cleanup --- .../gadgetbridge/service/devices/id115/ID115Support.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java index 95dfb2337..9635fbe7d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/id115/ID115Support.java @@ -1,15 +1,12 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.id115; -import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; import android.net.Uri; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Calendar; import java.util.TimeZone; @@ -26,7 +23,6 @@ import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; -import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; @@ -39,11 +35,6 @@ public class ID115Support extends AbstractBTLEDeviceSupport { public BluetoothGattCharacteristic normalWriteCharacteristic = null; public BluetoothGattCharacteristic healthWriteCharacteristic = null; - byte[] currentNotificationBuffer; - int currentNotificationSize; - int currentNotificationIndex; - byte currentNotificationType; - public ID115Support() { super(LOG); addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS); From 163b547395903dd30e3c110231896afec0d751df Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Mon, 30 Jul 2018 22:48:11 +0200 Subject: [PATCH 049/211] Remove level_list_device.xml, just use the DeviceType icon --- .../adapter/GBDeviceAdapterv2.java | 4 +-- .../main/res/drawable/level_list_device.xml | 31 ------------------- 2 files changed, 1 insertion(+), 34 deletions(-) delete mode 100644 app/src/main/res/drawable/level_list_device.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index 449453084..a23624049 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -108,9 +108,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 14a086c1f34ba0017f8ac9221a9e1a18eca9f05b Mon Sep 17 00:00:00 2001 From: szilardx <15869670+szilardx@users.noreply.github.com> Date: Sun, 29 Jul 2018 12:27:27 +0200 Subject: [PATCH 050/211] Add missing ActivityPoints and timestamp --- .../amazfitbip/ActivityDetailsParser.java | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java index eaec8cc8e..298d9ccb1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java @@ -21,7 +21,10 @@ import org.slf4j.LoggerFactory; import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.ArrayList; import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary; @@ -126,6 +129,37 @@ public class ActivityDetailsParser { throw new GBException("Error parsing activity details: " + ex.getMessage(), ex); } + try{ + int pointer = 0; + List activityPointList = activityTrack.getTrackPoints(); + Date gpsStartTime = null; + List gpsEntryIndexes = new ArrayList<>(); + while (pointer < activityPointList.size()){ + if (activityPointList.get(pointer).getLocation() == null){ + pointer++; + continue; + } + gpsEntryIndexes.add(pointer); + if (!(activityPointList.get(pointer).getTime().equals(activityPointList.get(pointer+1).getTime()))){ + gpsStartTime = activityPointList.get(pointer).getTime(); + break; + } + pointer++; + } + long differenceInSec = TimeUnit.SECONDS.convert(Math.abs(gpsStartTime.getTime() - baseDate.getTime()), TimeUnit.MILLISECONDS); + + double multiplier = (double) differenceInSec / (double) (gpsEntryIndexes.size()); + + for (int j = 0; j < gpsEntryIndexes.size(); j++){ + long timeOffsetSeconds = Math.round(j * multiplier); + activityPointList.get(gpsEntryIndexes.get(j)).setTime(makeAbsolute(timeOffsetSeconds)); + } + + } + catch (Exception ex){ + throw new GBException("Error cleaning activity details: " + ex.getMessage(), ex); + } + return activityTrack; } @@ -144,7 +178,7 @@ public class ActivityDetailsParser { convertHuamiValueToDecimalDegrees(baseLatitude), baseAltitude); - ActivityPoint ap = getActivityPointFor(timeOffset); + ActivityPoint ap = getActivityPointFor(timeOffset, coordinate); ap.setLocation(coordinate); add(ap); @@ -197,6 +231,19 @@ public class ActivityDetailsParser { return new ActivityPoint(time); } + private ActivityPoint getActivityPointFor(long timeOffsetSeconds, GPSCoordinate gpsCoordinate) { + Date time = makeAbsolute(timeOffsetSeconds); + if (lastActivityPoint != null) { + if (lastActivityPoint.getTime().equals(time)) { + if (lastActivityPoint.getLocation() != null && !lastActivityPoint.getLocation().equals(gpsCoordinate)) { + return new ActivityPoint(time); + } + return lastActivityPoint; + } + } + return new ActivityPoint(time); + } + private Date makeAbsolute(long timeOffsetSeconds) { return new Date(baseDate.getTime() + timeOffsetSeconds * 1000); } From 7f1c0521eadb282a3c7ad45ffa1dfc361d452dd1 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 1 Aug 2018 00:38:45 +0200 Subject: [PATCH 051/211] Small fixes to activity point timestamp fixup --- .../amazfitbip/ActivityDetailsParser.java | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java index 298d9ccb1..3ddb2f9e5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java @@ -47,7 +47,7 @@ public class ActivityDetailsParser { public static final BigDecimal HUAMI_TO_DECIMAL_DEGREES_DIVISOR = new BigDecimal(3000000.0); private final BaseActivitySummary summary; private final ActivityTrack activityTrack; -// private final int version; + // private final int version; private final Date baseDate; private long baseLongitude; private long baseLatitude; @@ -129,38 +129,47 @@ public class ActivityDetailsParser { throw new GBException("Error parsing activity details: " + ex.getMessage(), ex); } - try{ + fixupMissingTimestamps(activityTrack); + + return activityTrack; + } + + private void fixupMissingTimestamps(ActivityTrack activityTrack) throws GBException { + try { int pointer = 0; List activityPointList = activityTrack.getTrackPoints(); Date gpsStartTime = null; - List gpsEntryIndexes = new ArrayList<>(); - while (pointer < activityPointList.size()){ - if (activityPointList.get(pointer).getLocation() == null){ + List entriesToFixUp = new ArrayList<>(); + while (pointer < activityPointList.size() + 1) { + ActivityPoint activityPoint = activityPointList.get(pointer); + if (activityPoint.getLocation() == null) { pointer++; continue; } - gpsEntryIndexes.add(pointer); - if (!(activityPointList.get(pointer).getTime().equals(activityPointList.get(pointer+1).getTime()))){ - gpsStartTime = activityPointList.get(pointer).getTime(); + if (activityPoint.getTime().equals(activityPointList.get(pointer + 1).getTime())) { + entriesToFixUp.add(activityPoint); + } else { + // found the first activity point with a proper timestamp + entriesToFixUp.add(activityPoint); + gpsStartTime = activityPointList.get(pointer + 1).getTime(); break; } pointer++; } - long differenceInSec = TimeUnit.SECONDS.convert(Math.abs(gpsStartTime.getTime() - baseDate.getTime()), TimeUnit.MILLISECONDS); + if (gpsStartTime != null) { + // now adjust those entries without a timestamp + long differenceInSec = TimeUnit.SECONDS.convert(Math.abs(gpsStartTime.getTime() - baseDate.getTime()), TimeUnit.MILLISECONDS); - double multiplier = (double) differenceInSec / (double) (gpsEntryIndexes.size()); + double multiplier = (double) differenceInSec / (double) (entriesToFixUp.size()); - for (int j = 0; j < gpsEntryIndexes.size(); j++){ - long timeOffsetSeconds = Math.round(j * multiplier); - activityPointList.get(gpsEntryIndexes.get(j)).setTime(makeAbsolute(timeOffsetSeconds)); + for (int j = 0; j < entriesToFixUp.size(); j++) { + long timeOffsetSeconds = Math.round(j * multiplier); + entriesToFixUp.get(j).setTime(makeAbsolute(timeOffsetSeconds)); + } } - - } - catch (Exception ex){ + } catch (Exception ex) { throw new GBException("Error cleaning activity details: " + ex.getMessage(), ex); } - - return activityTrack; } private int consumeGPSAndUpdateBaseLocation(byte[] bytes, int offset, long timeOffset) { @@ -235,7 +244,7 @@ public class ActivityDetailsParser { Date time = makeAbsolute(timeOffsetSeconds); if (lastActivityPoint != null) { if (lastActivityPoint.getTime().equals(time)) { - if (lastActivityPoint.getLocation() != null && !lastActivityPoint.getLocation().equals(gpsCoordinate)) { + if (lastActivityPoint.getLocation() != null && !lastActivityPoint.getLocation().equals(gpsCoordinate)) { return new ActivityPoint(time); } return lastActivityPoint; From df84927954e0697b290d1225d18250967d51477f Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 1 Aug 2018 19:33:02 +0200 Subject: [PATCH 052/211] Fix filename generation and add testcasce Fixes #1169 --- .../gadgetbridge/util/FileUtils.java | 2 +- .../gadgetbridge/test/FileUtilsTest.java | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/FileUtilsTest.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java index 9ec1ad2da..6500a5b43 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java @@ -318,6 +318,6 @@ public class FileUtils { * @return the valid file name */ public static String makeValidFileName(String name) { - return name.replaceAll("\0/:\\r\\n\\\\", "_"); + return name.replaceAll("[\0/:\\r\\n\\\\]", "_"); } } \ No newline at end of file diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/FileUtilsTest.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/FileUtilsTest.java new file mode 100644 index 000000000..a715a958f --- /dev/null +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/FileUtilsTest.java @@ -0,0 +1,19 @@ +package nodomain.freeyourgadget.gadgetbridge.test; + +import org.junit.Test; + +import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; + +import static org.junit.Assert.assertEquals; + +public class FileUtilsTest extends TestBase { + + @Test + public void testValidFileName() { + String tempName = "foo:bar"; + assertEquals("foo_bar", FileUtils.makeValidFileName(tempName)); + + tempName = "fo\no::bar"; + assertEquals("fo_o__bar", FileUtils.makeValidFileName(tempName)); + } +} From 16fb1a584d204d0ac471b0d2ed4c72f0d3141f5b Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 1 Aug 2018 19:48:05 +0200 Subject: [PATCH 053/211] Errors during activity track timestamp fixup should be non-fatal So just log them. #1134 --- .../devices/huami/amazfitbip/ActivityDetailsParser.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java index 3ddb2f9e5..1b11daab5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java @@ -134,7 +134,7 @@ public class ActivityDetailsParser { return activityTrack; } - private void fixupMissingTimestamps(ActivityTrack activityTrack) throws GBException { + private void fixupMissingTimestamps(ActivityTrack activityTrack) { try { int pointer = 0; List activityPointList = activityTrack.getTrackPoints(); @@ -168,7 +168,7 @@ public class ActivityDetailsParser { } } } catch (Exception ex) { - throw new GBException("Error cleaning activity details: " + ex.getMessage(), ex); + LOG.warn("Error cleaning activity details", ex); } } From a356c1f7bd58a395c6fc14acf86fcdeee40b2bc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 28 Jul 2018 16:48:33 +0200 Subject: [PATCH 054/211] Splash screen (cherry picked from commit 076f818) --- app/src/main/AndroidManifest.xml | 2 +- app/src/main/res/drawable/splash.xml | 13 +++++++++++++ app/src/main/res/values/styles.xml | 8 +++++++- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/drawable/splash.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bf3ae12fb..bd42dd7d8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -45,7 +45,7 @@ + android:theme="@style/SplashTheme"> diff --git a/app/src/main/res/drawable/splash.xml b/app/src/main/res/drawable/splash.xml new file mode 100644 index 000000000..5aba0c99d --- /dev/null +++ b/app/src/main/res/drawable/splash.xml @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 2c0439864..c56e0e950 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,4 +1,4 @@ - + From c708bc6e5299024b5609edeccc6679bd80408efc Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Wed, 1 Aug 2018 21:52:35 +0200 Subject: [PATCH 055/211] Use a vector resource instead of the raster background image Create a specific splash file for android version <21 without the drawable --- app/src/main/res/drawable-v21/splash.xml | 11 +++++++++++ app/src/main/res/drawable/gadgetbridge_img.png | Bin 8139 -> 0 bytes app/src/main/res/drawable/gadgetbridge_img.xml | 12 ++++++++++++ app/src/main/res/drawable/splash.xml | 6 ------ .../activity_controlcenterv2_content_main.xml | 4 +++- 5 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 app/src/main/res/drawable-v21/splash.xml delete mode 100644 app/src/main/res/drawable/gadgetbridge_img.png create mode 100644 app/src/main/res/drawable/gadgetbridge_img.xml diff --git a/app/src/main/res/drawable-v21/splash.xml b/app/src/main/res/drawable-v21/splash.xml new file mode 100644 index 000000000..10bcca000 --- /dev/null +++ b/app/src/main/res/drawable-v21/splash.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/gadgetbridge_img.png b/app/src/main/res/drawable/gadgetbridge_img.png deleted file mode 100644 index 176a54e0f759ef5c87cff2e1496c8db336fa5256..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8139 zcmaKxRZtvEu(olR;O_43?hApy;!fD$5+o274Z3)cC0MW^0Ty@n#UV&=_uv+S%i%k9 z>c9N2y62s)zLJF2KvPZFOxzb-(NC9$+_e zV5wz`u7g9^A0ig-IPRsYN-nfJkMr7uh3@UqW^g|EEno540IEF z&a|b#m9Lr%zLUQGgn#JA4=o;AWYi=uhTZ;gHNixCoNn>=+TXX&U5O zu6Dr|gyAVlVfO7Ee)dJ@Y@C%fkCOU?G%9w*fJP|w??QeC z{C9^X3tq~-S&dr|Xq~OwT9b;HJ#NI3+rpu@6CKIX=fJsG@CW@m{}?%X$M^nis%Lt! z1DSVKC?DEAY|MJr45Mfn!I0I*0cjcCPcgUb6lgNNNulb)S;SR|f9t)d7D0B0CsIgo z1^~6vp}WDm=ZA~wMyK(V4pKLzhJSx7#ykUBG;ao9StZb+l68}3#e8xX9SimVu_NbJ zbvt65(=v6PM?rPdY!~S4dhG_4)8av`Y1lHfHVzEkZsRNIQBuiOW4SlIix`j|SeB#X z+r^WMPrs7hyG4%buPljZq?J;d_XLAlQ@Zog}bWWlF)Ln|nWC zIg+e!9|;+r;uP4iDhA^v%6@( zn*HlPv#z*~rvZ}`q-ss#s*f0TGjylOEUjBd1|74ynu&&~H@^-0XR69uXKllelAe$I z%xC-MG}PmCJlmL!r^OZhv;8r3!0|%VRLv+sSCSA^dcA|v1FA? zM80X`LUzxLt~kj)pxfx+0Q8fg+dsZj8rPjG#0$E)aAbb>hT=bza(cp(UEJ7 z+K}e;jS4NpN5cxBf4@L3a0E~sOvLFI^n~wLPC0kFqYfFmsp629vc##4ecvZm6*2yX z{VjF`zorWv93B-C-k4|c1(F@{oFvY0mXpx9U zotVxW5fF^vwK2(Wa4{8}G-&MM`XHzM5780hO_vZAQsGBJOY4n0&R{vsI%3nPSP!gD zjI#G;<0Q05l>EGC=2 ze54s!5}zI8nZ}9&6+V}bE(x-L`W|mcx#PFVz;be!RaM&%*0VN2P0=vxdBv#hNzd82 zN&D<6kxQn1xlpuLhx33|vh4_8zqU}NJJ(W%3E(1xaTtsAw+yTF*=kcY(&+%=o!-I_ z)~$xjEb*XyxzeTBG<~0lxFrsJ+qvAr1Twy@wv@J=bu|_gAT@Lz$ss?%p!Zw|<9WnV z>-p3?5TGg+rF@j+B?<*RGtn7u^*auin~dT-BO5MI31%^Ij)BS z>QKv~G+<4t&p%)HPo@jUTS=<O*GTZ?uB0c8kjbIjS*8?g=OZIQFP*cKAC?aieCU#h(=j-}SSmk^+Ct6Qnw zuT$4!AIbsAO_5vXfb3<0UK)PBpcF*28}^fWI_OR2i2C#|*nT)!)Kg?a_+>25ai=&X z8Ei#P&DdwFucsBg7DtYG!ipw5+bLIp5TG3onU*nMmEZW%+j-f4?M^Ejd}eb9hls8b zu2e(@N(6q^nGfU455G}UI)K5UGWkY5d%&-3-TdjLBtk4qr9I}@%%<4WdRVzQnt#m8 z8JJ8=iEN1p;W8o{%n&I|Hf;|{-t#TCN>wszB*g0ZiCYZ z;YR`{6vpKEA}yKewWgu?1#k-nwjBj=zKxoe;W5qeEN9W2W-ML)oAIOkjqvS7P`770 z%iT_Ngh6ZCn-Hx=M)7K@7K-HR#Vn$RjB*nH)AcLV;KMJ)(_pq}Ig-sCn<>S`ouJe6=sAw z_J@(Gv`_=()5T2p=Rz(c*q&B2k!Kb@6NOZ#haRq1FV??66shp7lmLXjE z`Q_vHE7k0;0_J$@;9r%GBU~ItuxTDWTk!3N_764kPPvC2s;Y(#Mi*z_^Wg+OyUj*R zSZ_T90x+z4(25IbSCYsK=p4OR`m+rQaMP=@DALx+?Wd_&1Ovs8)63qQmqS;Knl}3B z1JbXiOS0FgbB$Op43#IUI4ei+q!lpf=X&bIBJ*E!dg608pJi2F5+{v^$0Td!(zk|Z5+m_CPRWLXkAlrjewh!U_ zGC~6;O3S!bg*Far;7*2<4G5XMGvx;)HZMS*xJEY$c8pZ6I;LE%xkB08t~kP~7F#Iu zj^NQbx$bzA{wt1_oqid2gmQICqB;zb$HOzAMqf9tGtosrkYh_1=^~h#VIgHpx5>)6 zlC$dk)2CThh*sejw)x5N1~I?V9vKZz>z-@6ojPqc);ZO*Mm|mE*kebMgYFwop>GFk z>_P9p<~7{2aqg$NW#Z5Ns9gHqFPRtxB+x4_%>ia0XIT3dq()ewm?$co4m7ru{9rn% zBYeIJRQ`NW(BcOO-;Fml%vzeE`a6$0doq-*#rq|ke~+R90~>LAu_ZKgX?6e0xNku% z0Y}b)-m1hK8e!GdHoNQ=?y!V!Nfs+lz6KV-e@!yC;;#k3DBM^%)w-gF8LV5!E+BHn z>-~O1AinLzQZd;yRlE<2!gtt)7h?3OZB9qI4&3#&3glJ*>?21bEYy=0R(4C#@qi<* zu!f5X)EyQL&+qkuHgPbSYOpl!|3)vt?u{zGUrpbYp+lx0h(2RY&2` z3Ag4Bx1%miE@$A_(@-0yqOm`3XiaICqzaoyh0(4HfPZl2coYYMYmhm=mr7pF%oc(R z1{`d?-GtZryPcPXYm_3BAo0dj3Uu0a+uK$ISR2YyAkP@rXSjbPAL ztN2(<+zw>x(qAcg86-LU^R(DnOArLnJMNjvlh*(Dqj^xa=&F6HaAwqCL_;H5xO{Bh z{7pyluDBI3rKxy&GhQ9mNqjHsr&juF>;{qsFOntUK|U(FmbTw{70>GX8a{N!uw%{p z2WHozp$;Ir>s4bVv*lP zc}8Q#TPAEH;&QA1&NSIsn?JgeZrJ5VE*tP8$D>zY5L>RxFl#KBlXzyI7Jk4=bZ1rY!n zz8TQBr5c$IZsUO3f!9i&5bladSQE%c6ks9>-F5o2psiqpS#8|<^|qhyE#g1HwI*lr znHp?ONFOZxj$o>J;N$_uye-5*%-{d2^@y(@o5F{by zEzw}J97?rWriZ8iROI6vRm6m2868wL4+iW%Swdv}PWX41yRNZB3d`^^x{vCXOn}{N z2lad39gNEKgzz8A1X!)6ZxM~x&~2u61E0b-1Hd_$dVXjLXISJg{w;g-UUuzkSO3SY z;@S`woz-8ms1H2=^R3C#_kr9jYN>t&NTYX1qRwGu00WT?}DvC zl9fa6-arX^hw{5U)H!dYi-v^)#99-_`q-1GfBj0oWTS#I7EsC9(ckleY7*VJ3 zi>jy|WcE8tjygMQK)NhXDam%$a%ZIW76@XO#mTif+Qud%yd}=rbwQu8WI3KyN~6k> zyHNE|5l{9UlVSDJo+l=sUd%w{;{s*(d*70G;vUfhi2{3hs)=(4mOY!!C^Er8W{KK^S}=-W?zZL#byV$tFk1-jXTs>#IOvPI6ZfDUFiC!ocL z8I;<5`n3`i%%k6Afwro8;sF3F%+G0uuUo8>PM40G*AJl9wSLU+>%jZkGaM$so@Xnz z`M1tigNTQtrw?Ndi?KeK<5VZmps6HYRRdmu){R6~6Zeaz*OzU^{Z`mv-_H9=7o6g( zB)Pc>I{1#N8SyVb|T8e zmnhB}`~Adp)AwiyuE(V{&lJ0_DA&o-zqPzi^0yCKRIercdSk1YrJfzsKEK0T z#O(d%?{~i4S*iwqz3quj`5JA^LDNrnYhngIP0eHeKl!qXMW)&&o-gyH^UH={sP%wZnTzLg+bL^SP!_~RPF1@1{Ccq^aq0+Ju+twS=o{HiZT zb=s$zoZZ03>o!_uIwY1rNB%N)D}^;j?<;d#Nm7#}o@vQzAMy!%Ep1q|5ufGf?`>aXKW+h|PC<$xz>R7&UYmfk zGx$M=g`6u?DJv>rT2#!@y)%-`wo6=(EUHURgQmQlsd ztE(WkGA0YIT>-#bl)no1xRnlwkCO5bgS(47BD*y`%z<+yh>bt3| zvW`n7NYPP|bJVd(Ct%&*q@KIr-yFLWOk$X3kNxi&yKf8a5U>uPtfaZbAfKtTE48T( zPdaIC2rB>rd2#x^Iy3H)XhM|H4n%THj%QRVww{%u<&15pGCd`b3Prnck8JL7)s&hu zVSxmrMBmIkYkNz5qav4^t{2mw&rZ!6J=cu%NFJ44HQ@U})S!lC4>tl^R~nHommMxI zISb#@7{pNP(|Xytr96(8XW?3<+}QIjixB30j>Iihhk_gGaJj#Cqn_hGv2@FT&0-*J zIp@S^)ie&(0z$YlHSH44hB{5@!`86_#_!xFmJm*+r8udK;CsbQ=lv#OCe_ zoErZTF|t2+Atm2ArWlobR_^2KOTjI=5SfRQnP;~RdQQEQZ&WIUY z>ibiWeq?tR{b6R+?IU2hEHLIRIc;tw5Ld|EP!Zb0^-*hP@g*7n~u0|U{UX%OBgs)g6B-!sb*XuCG51H&vCeE#RoN4^x;oLns(n;YV>WiF1 z{%50!ACbL&MMBie%KnWtIfb}3VVwJ$o6c#SL;$k4CRU@t4`1CJu$teBq3ZwS=BiiT zGkV+PAh7h>=p)V}QjbJ#DzP8?!?@Q%7uq_Iiyousq5(5!XU5%|_#S$vx+-pG04qYj zl1sJFF{Uc0euGAfM2XthLOViHdxl7tGhX~wzU(3~?g3QlG5k+Mb{cQdh7h=^oLy<$ ztQ8_1sI!w&9=ebN-OIzA_T!{}aK%d2L-m2?vIO<3-d{CrdS3c(?5!ick~=dp!g*gJ z6N+)J0`eiA$)biX2|a`>v(lZi*0gc**qxG_(46d)8#E!m?4OWRc3Z6SA$ds|am!83 zktR6_;LC{wJ|t4C!}zB|GhF`D**J=4zU(+iOagG!?phn&@(RW-#n6!bAQMJ*iPIM= z;fGT%gxNrTV4v=2U-zD42{+mHxYao$=q_lCW5o{Qq=^0PPQRlC)tgiTcxHV;m2~k| z0SdP>!Wzer+x<8NMa1x9{tE1jSe0US#_@q6SR4AW&<24Jgre%m4GZ6GgTW953{QR9 z5-gJy!UL2a0Y_7$6<`Krg1noTyhDNmNE>%^;8Kox3#J_d4$hy)xcJ1{LZFO&BK-b?JxzI6_f;?5knm1}tl zafV(J&w{a;HRJY$xt2?0aWD+f1>7lU(!NsG9byygm52NtQns?$7j&rGCe9@Q1n_MY z&ei`3Z2UarZL&L^BY3N_Q`!sSF~IhU`rr@YS4r?@$O(aq7`VnNRN&ALK6ByZ+wJC{ zVJ?-A%9b0i!6{H?`l4yh}baeNCi8(Wa+c2z%4 zv2FAZm?|Q3kX5+%7yUcR_b41NhNI0VQ?m{OmC}~#mP6r$&v2w^20Eo?0P+4lKYe+nMa!8p6Zm=Uf z;f=P-U&y`8oGm4)N0fzS=Xp@;aJn6qw+{6ti^~fj%n`q^e&xviZ6l{L5}wb_n0ePV z@U*Xm4KOEkHZjG16fs$mduzEV8XBo<+NRB;ut%XQVzRY}2c{1C(bGay#W@@?jV<=b zAg_B?Vsbmr)jOM6FL^PV9O&Oqf4TRIr=P^I5$K}Qu=#C7w8&L(j3xCfFWJoEOXgb? z!p7($jrDT3cscgz4PDOK?!DXjl&3ohS|c$Khtg2(i=pE6qa=+E7$6E0A|Npb=#Jl$ zzWBlL@&_>iiPe}7Cf<(v4JazLkQn_V7BmU)?&6<1@em zUv?nAfrs2oFtIY>sdwu~v<=QgF2n9!9RU2yO$bS0*zHLaER_C2iaC+1();S-a43x= zUOt*I|EDR9Fj@mBbRj8!CjL)bSGo!nSd@kB(5#O=r%gSAGrIN-oZ1rQK9IkLG1&eW zEldZvr~nCnLE_I_<6N~cReNeoh9bPC6)g02RH#Mr-*`h#Fo4N^8cHCJ;=iL^HIisY zzCgD(MN0i6kdPn$L8uUsk9`hvoum9A<9xr%s;PQ0nD#JismLZw50h5BN~cf7}(!aC^ug|cKQ6CB^n_6Wc#f@9eQ3L9XRkz1oU%j}+_DJlPAWyp2q5?Sy3E*2fim4S7B&b8f% zb3tx4$!6|~!iJ2j%tnIA3_KzLHU7eKFomvY!a}q)8$=10+KC;ZP?+A>Vb32A1FfE( zCvB4fZ#fO2ur$rtoz<$6M4}MSXydzLC(?SBC#tNp3uX#+VOEK5Xrd{pB}I}~?Pf%> z{IJ4^dM*pbfo0lW3sRAt++gYA0I9y2Jj3Z0QVd~83QIRO2=hGD7%7Jo9`U5v)pJGl zza{?PN;?Vg*kDd8rnW{;yrca8*8M*g{*R8o_DScjeEh#G|AF(W@fZFtPqqNxSFm#A zV#671U$y_D{_-&ZV(ZSkc1Es|14mo@{tuJ?OkkXO#7qBQj)2AI7i2cSBYuzRrgyKu P^9brH@02SQ--rGWqXnK@ diff --git a/app/src/main/res/drawable/gadgetbridge_img.xml b/app/src/main/res/drawable/gadgetbridge_img.xml new file mode 100644 index 000000000..25dec7b26 --- /dev/null +++ b/app/src/main/res/drawable/gadgetbridge_img.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/splash.xml b/app/src/main/res/drawable/splash.xml index 5aba0c99d..b0916a7f0 100644 --- a/app/src/main/res/drawable/splash.xml +++ b/app/src/main/res/drawable/splash.xml @@ -4,10 +4,4 @@ - - - - diff --git a/app/src/main/res/layout/activity_controlcenterv2_content_main.xml b/app/src/main/res/layout/activity_controlcenterv2_content_main.xml index 0c4c48949..08bd36fe5 100644 --- a/app/src/main/res/layout/activity_controlcenterv2_content_main.xml +++ b/app/src/main/res/layout/activity_controlcenterv2_content_main.xml @@ -15,7 +15,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" - android:src="@drawable/gadgetbridge_img" /> + android:alpha="0.1" + android:tint="?attr/textColorPrimary" + app:srcCompat="@drawable/gadgetbridge_img" /> Date: Wed, 1 Aug 2018 22:56:01 +0200 Subject: [PATCH 056/211] Amazfit Cor: Allow setting menu items (Also rename/refactor stuff from Mi Band 2 to Huami - still WIP) --- .../service/DeviceSupportFactory.java | 4 +- ...ation.java => AbstractHuamiOperation.java} | 7 +- .../MiBand2Support.java => HuamiSupport.java} | 80 +++++++++---------- .../actions/StopNotificationAction.java | 2 +- .../huami/amazfitbip/AmazfitBipSupport.java | 8 +- .../AmazfitBipTextNotificationStrategy.java | 4 +- .../AmazfitBipFetchLogsOperation.java | 2 +- .../huami/amazfitcor/AmazfitCorSupport.java | 52 +++++++++++- .../miband2/Mi2NotificationStrategy.java | 5 +- .../miband2/Mi2TextNotificationStrategy.java | 3 +- .../operations/AbstractFetchOperation.java | 10 +-- .../operations/FetchActivityOperation.java | 6 +- .../FetchSportsDetailsOperation.java | 6 +- .../FetchSportsSummaryOperation.java | 6 +- .../operations/InitOperation.java | 8 +- .../operations/UpdateFirmwareOperation.java | 10 +-- app/src/main/res/values/arrays.xml | 34 ++++++++ app/src/main/res/values/strings.xml | 2 + app/src/main/res/values/values.xml | 1 + app/src/main/res/xml/preferences.xml | 12 +++ 20 files changed, 182 insertions(+), 80 deletions(-) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/{miband2/AbstractMiBand2Operation.java => AbstractHuamiOperation.java} (85%) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/{miband2/MiBand2Support.java => HuamiSupport.java} (96%) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/{miband2 => }/actions/StopNotificationAction.java (98%) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/{miband2 => }/operations/AbstractFetchOperation.java (97%) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/{miband2 => }/operations/FetchActivityOperation.java (98%) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/{miband2 => }/operations/FetchSportsDetailsOperation.java (98%) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/{miband2 => }/operations/FetchSportsSummaryOperation.java (99%) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/{miband2 => }/operations/InitOperation.java (96%) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/{miband2 => }/operations/UpdateFirmwareOperation.java (98%) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java index 65c3ebc2f..32257f69a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java @@ -29,11 +29,11 @@ import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitcor.AmazfitCorSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband3.MiBand3Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.id115.ID115Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.liveview.LiveviewSupport; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.MiBandSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.no1f1.No1F1Support; @@ -116,7 +116,7 @@ public class DeviceSupportFactory { deviceSupport = new ServiceDeviceSupport(new MiBandSupport(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; case MIBAND2: - deviceSupport = new ServiceDeviceSupport(new MiBand2Support(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING)); + deviceSupport = new ServiceDeviceSupport(new HuamiSupport(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; case MIBAND3: deviceSupport = new ServiceDeviceSupport(new MiBand3Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/AbstractMiBand2Operation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/AbstractHuamiOperation.java similarity index 85% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/AbstractMiBand2Operation.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/AbstractHuamiOperation.java index 4cc5b2768..6ad851019 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/AbstractMiBand2Operation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/AbstractHuamiOperation.java @@ -14,13 +14,14 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2; +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.AbstractMiBandOperation; -public abstract class AbstractMiBand2Operation extends AbstractMiBandOperation { - protected AbstractMiBand2Operation(MiBand2Support support) { +public abstract class AbstractHuamiOperation extends AbstractMiBandOperation { + protected AbstractHuamiOperation(HuamiSupport support) { super(support); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java similarity index 96% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 6cda41620..70d72a6f0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2; +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; @@ -102,13 +102,13 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotificat import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.HeartRateProfile; import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiBatteryInfo; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiDeviceEvent; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.actions.StopNotificationAction; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchActivityOperation; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchSportsSummaryOperation; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.InitOperation; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.UpdateFirmwareOperation; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2NotificationStrategy; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2TextNotificationStrategy; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.actions.StopNotificationAction; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchActivityOperation; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchSportsSummaryOperation; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.InitOperation; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.UpdateFirmwareOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.RealtimeSamplesSupport; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -135,7 +135,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.VI import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.getNotificationPrefIntValue; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.getNotificationPrefStringValue; -public class MiBand2Support extends AbstractBTLEDeviceSupport { +public class HuamiSupport extends AbstractBTLEDeviceSupport { // We introduce key press counter for notification purposes private static int currentButtonActionId = 0; @@ -143,9 +143,9 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { private static long currentButtonPressTime = 0; private static long currentButtonTimerActivationTime = 0; - private static final Logger LOG = LoggerFactory.getLogger(MiBand2Support.class); - private final DeviceInfoProfile deviceInfoProfile; - private final HeartRateProfile heartRateProfile; + private static final Logger LOG = LoggerFactory.getLogger(HuamiSupport.class); + private final DeviceInfoProfile deviceInfoProfile; + private final HeartRateProfile heartRateProfile; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -170,11 +170,11 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { private RealtimeSamplesSupport realtimeSamplesSupport; private boolean alarmClockRinging; - public MiBand2Support() { + public HuamiSupport() { this(LOG); } - public MiBand2Support(Logger logger) { + public HuamiSupport(Logger logger) { super(logger); addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS); addSupportedService(GattService.UUID_SERVICE_GENERIC_ATTRIBUTE); @@ -253,19 +253,19 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return timestamp; } - public MiBand2Support setCurrentTimeWithService(TransactionBuilder builder) { + public HuamiSupport setCurrentTimeWithService(TransactionBuilder builder) { GregorianCalendar now = BLETypeConversions.createCalendar(); byte[] bytes = getTimeBytes(now, TimeUnit.SECONDS); builder.write(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_CURRENT_TIME), bytes); return this; } - public MiBand2Support setLowLatency(TransactionBuilder builder) { + public HuamiSupport setLowLatency(TransactionBuilder builder) { // TODO: low latency? return this; } - public MiBand2Support setHighLatency(TransactionBuilder builder) { + public HuamiSupport setHighLatency(TransactionBuilder builder) { // TODO: high latency? return this; } @@ -283,7 +283,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { // MB2: AVL // TODO: tear down the notifications on quit - public MiBand2Support enableNotifications(TransactionBuilder builder, boolean enable) { + public HuamiSupport enableNotifications(TransactionBuilder builder, boolean enable) { builder.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_NOTIFICATION), enable); builder.notify(getCharacteristic(GattService.UUID_SERVICE_CURRENT_TIME), enable); // Notify CHARACTERISTIC9 to receive random auth code @@ -291,7 +291,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - public MiBand2Support enableFurtherNotifications(TransactionBuilder builder, boolean enable) { + public HuamiSupport enableFurtherNotifications(TransactionBuilder builder, boolean enable) { builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), enable); builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_6_BATTERY_INFO), enable); builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_DEVICEEVENT), enable); @@ -310,7 +310,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return super.connect(); } - private MiBand2Support sendDefaultNotification(TransactionBuilder builder, SimpleNotification simpleNotification, short repeat, BtLEAction extraAction) { + private HuamiSupport sendDefaultNotification(TransactionBuilder builder, SimpleNotification simpleNotification, short repeat, BtLEAction extraAction) { LOG.info("Sending notification to MiBand: (" + repeat + " times)"); NotificationStrategy strategy = getNotificationStrategy(); for (short i = 0; i < repeat; i++) { @@ -330,7 +330,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { * @param extraAction an extra action to be executed after every vibration and flash sequence. Allows to abort the repetition, for example. * @param builder */ - private MiBand2Support sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { + private HuamiSupport sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { getNotificationStrategy().sendCustomNotification(vibrationProfile, simpleNotification, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder); LOG.info("Sending notification to MiBand"); return this; @@ -355,14 +355,14 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { private static final byte[] startHeartMeasurementContinuous = new byte[]{0x15, MiBandService.COMMAND_SET__HR_CONTINUOUS, 1}; private static final byte[] stopHeartMeasurementContinuous = new byte[]{0x15, MiBandService.COMMAND_SET__HR_CONTINUOUS, 0}; - private MiBand2Support requestBatteryInfo(TransactionBuilder builder) { + private HuamiSupport requestBatteryInfo(TransactionBuilder builder) { LOG.debug("Requesting Battery Info!"); BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_6_BATTERY_INFO); builder.read(characteristic); return this; } - public MiBand2Support requestDeviceInfo(TransactionBuilder builder) { + public HuamiSupport requestDeviceInfo(TransactionBuilder builder) { LOG.debug("Requesting Device Info!"); deviceInfoProfile.requestDeviceInfo(builder); return this; @@ -375,7 +375,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { * @return */ - private MiBand2Support setFitnessGoal(TransactionBuilder transaction) { + private HuamiSupport setFitnessGoal(TransactionBuilder transaction) { LOG.info("Attempting to set Fitness Goal..."); BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_8_USER_SETTINGS); if (characteristic != null) { @@ -399,7 +399,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { * @return */ - private MiBand2Support setUserInfo(TransactionBuilder transaction) { + private HuamiSupport setUserInfo(TransactionBuilder transaction) { BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_8_USER_SETTINGS); if (characteristic == null) { return this; @@ -460,7 +460,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { * @param builder * @return */ - private MiBand2Support setWearLocation(TransactionBuilder builder) { + private HuamiSupport setWearLocation(TransactionBuilder builder) { LOG.info("Attempting to set wear location..."); BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_8_USER_SETTINGS); if (characteristic != null) { @@ -519,7 +519,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { * * @param builder */ - private MiBand2Support setHeartrateSleepSupport(TransactionBuilder builder) { + private HuamiSupport setHeartrateSleepSupport(TransactionBuilder builder) { final boolean enableHrSleepSupport = MiBandCoordinator.getHeartrateSleepSupport(getDevice().getAddress()); if (characteristicHRControlPoint != null) { builder.notify(characteristicHRControlPoint, true); @@ -535,7 +535,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - private MiBand2Support setHeartrateMeasurementInterval(TransactionBuilder builder, int minutes) { + private HuamiSupport setHeartrateMeasurementInterval(TransactionBuilder builder, int minutes) { if (characteristicHRControlPoint != null) { builder.notify(characteristicHRControlPoint, true); LOG.info("Setting heart rate measurement interval to " + minutes + " minutes"); @@ -744,7 +744,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } } - public MiBand2Support sendReboot(TransactionBuilder builder) { + public HuamiSupport sendReboot(TransactionBuilder builder) { builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_FIRMWARE), new byte[] { MiBand2Service.COMMAND_FIRMWARE_REBOOT}); return this; } @@ -1312,7 +1312,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { * Fetch the events from the android device calendars and set the alarms on the miband. * @param builder */ - private MiBand2Support sendCalendarEvents(TransactionBuilder builder) { + private HuamiSupport sendCalendarEvents(TransactionBuilder builder) { BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION); Prefs prefs = GBApplication.getPrefs(); @@ -1402,7 +1402,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } - private MiBand2Support setDateDisplay(TransactionBuilder builder) { + private HuamiSupport setDateDisplay(TransactionBuilder builder) { DateTimeDisplay dateTimeDisplay = HuamiCoordinator.getDateDisplay(getContext()); LOG.info("Setting date display to " + dateTimeDisplay); switch (dateTimeDisplay) { @@ -1416,7 +1416,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - private MiBand2Support setTimeFormat(TransactionBuilder builder) { + private HuamiSupport setTimeFormat(TransactionBuilder builder) { boolean is24Format = DateFormat.is24HourFormat(getContext()); LOG.info("Setting 24h time format to " + is24Format); if (is24Format) { @@ -1427,7 +1427,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - private MiBand2Support setGoalNotification(TransactionBuilder builder) { + private HuamiSupport setGoalNotification(TransactionBuilder builder) { boolean enable = HuamiCoordinator.getGoalNotification(); LOG.info("Setting goal notification to " + enable); if (enable) { @@ -1438,7 +1438,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - private MiBand2Support setActivateDisplayOnLiftWrist(TransactionBuilder builder) { + private HuamiSupport setActivateDisplayOnLiftWrist(TransactionBuilder builder) { ActivateDisplayOnLift displayOnLift = HuamiCoordinator.getActivateDisplayOnLiftWrist(getContext()); LOG.info("Setting activate display on lift wrist to " + displayOnLift); @@ -1469,7 +1469,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - protected MiBand2Support setDisplayItems(TransactionBuilder builder) { + protected HuamiSupport setDisplayItems(TransactionBuilder builder) { Set pages = HuamiCoordinator.getDisplayItems(); LOG.info("Setting display items to " + (pages == null ? "none" : pages)); @@ -1497,7 +1497,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - private MiBand2Support setRotateWristToSwitchInfo(TransactionBuilder builder) { + private HuamiSupport setRotateWristToSwitchInfo(TransactionBuilder builder) { boolean enable = HuamiCoordinator.getRotateWristToSwitchInfo(); LOG.info("Setting rotate wrist to cycle info to " + enable); if (enable) { @@ -1508,12 +1508,12 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - private MiBand2Support setDisplayCaller(TransactionBuilder builder) { + private HuamiSupport setDisplayCaller(TransactionBuilder builder) { builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_ENABLE_DISPLAY_CALLER); return this; } - private MiBand2Support setDoNotDisturb(TransactionBuilder builder) { + private HuamiSupport setDoNotDisturb(TransactionBuilder builder) { DoNotDisturb doNotDisturb = HuamiCoordinator.getDoNotDisturb(getContext()); LOG.info("Setting do not disturb to " + doNotDisturb); switch (doNotDisturb) { @@ -1546,7 +1546,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - private MiBand2Support setInactivityWarnings(TransactionBuilder builder) { + private HuamiSupport setInactivityWarnings(TransactionBuilder builder) { boolean enable = HuamiCoordinator.getInactivityWarnings(); LOG.info("Setting inactivity warnings to " + enable); @@ -1600,7 +1600,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - private MiBand2Support setDistanceUnit(TransactionBuilder builder) { + private HuamiSupport setDistanceUnit(TransactionBuilder builder) { MiBandConst.DistanceUnit unit = HuamiCoordinator.getDistanceUnit(); LOG.info("Setting distance unit to " + unit); if (unit == MiBandConst.DistanceUnit.METRIC) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/actions/StopNotificationAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java similarity index 98% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/actions/StopNotificationAction.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java index 97e41aaef..702b212aa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/actions/StopNotificationAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java @@ -14,7 +14,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.actions; +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.actions; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java index f4f288fbb..482d00dcd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java @@ -51,16 +51,16 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotificat 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.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.operations.AmazfitBipFetchLogsOperation; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchActivityOperation; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchSportsSummaryOperation; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchActivityOperation; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchSportsSummaryOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; import nodomain.freeyourgadget.gadgetbridge.util.Version; -public class AmazfitBipSupport extends MiBand2Support { +public class AmazfitBipSupport extends HuamiSupport { private static final Logger LOG = LoggerFactory.getLogger(AmazfitBipSupport.class); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipTextNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipTextNotificationStrategy.java index 60547c9ce..e62961720 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipTextNotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipTextNotificationStrategy.java @@ -26,14 +26,14 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotificat import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.OverflowStrategy; import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2TextNotificationStrategy; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; // This class in no longer in use except for incoming calls class AmazfitBipTextNotificationStrategy extends Mi2TextNotificationStrategy { - AmazfitBipTextNotificationStrategy(MiBand2Support support) { + AmazfitBipTextNotificationStrategy(HuamiSupport support) { super(support); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/operations/AmazfitBipFetchLogsOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/operations/AmazfitBipFetchLogsOperation.java index 0aa62184f..1386477fe 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/operations/AmazfitBipFetchLogsOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/operations/AmazfitBipFetchLogsOperation.java @@ -38,7 +38,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WaitAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSupport; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.AbstractFetchOperation; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.AbstractFetchOperation; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java index 60164c544..2d5490abb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java @@ -19,14 +19,64 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitcor; import android.content.Context; import android.net.Uri; -import java.io.IOException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.util.Set; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitcor.AmazfitCorFWHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitcor.AmazfitCorService; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSupport; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class AmazfitCorSupport extends AmazfitBipSupport { + private static final Logger LOG = LoggerFactory.getLogger(AmazfitCorSupport.class); + + @Override + protected AmazfitCorSupport setDisplayItems(TransactionBuilder builder) { + + Prefs prefs = GBApplication.getPrefs(); + Set pages = prefs.getStringSet("cor_display_items", null); + LOG.info("Setting display items to " + (pages == null ? "none" : pages)); + byte[] command = AmazfitCorService.COMMAND_CHANGE_SCREENS.clone(); + + if (pages != null) { + if (pages.contains("status")) { + command[1] |= 0x02; + } + if (pages.contains("notification")) { + command[1] |= 0x04; + } + if (pages.contains("activity")) { + command[1] |= 0x08; + } + if (pages.contains("weather")) { + command[1] |= 0x10; + } + if (pages.contains("alarm")) { + command[1] |= 0x20; + } + if (pages.contains("timer")) { + command[1] |= 0x40; + } + if (pages.contains("settings")) { + command[1] |= 0x80; + } + if (pages.contains("alipay")) { + command[2] |= 0x01; + } + } + builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), command); + + return this; + } + @Override public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException { return new AmazfitCorFWHelper(uri, context); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2NotificationStrategy.java index 880ad8eaa..7628a17a0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2NotificationStrategy.java @@ -24,13 +24,14 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.V2NotificationStrategy; -public class Mi2NotificationStrategy extends V2NotificationStrategy { +public class Mi2NotificationStrategy extends V2NotificationStrategy { private final BluetoothGattCharacteristic alertLevelCharacteristic; - public Mi2NotificationStrategy(MiBand2Support support) { + public Mi2NotificationStrategy(HuamiSupport support) { super(support); alertLevelCharacteristic = support.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2TextNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2TextNotificationStrategy.java index b69ea329b..292aeebb8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2TextNotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/Mi2TextNotificationStrategy.java @@ -30,12 +30,13 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotificat import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.OverflowStrategy; import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiIcon; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; public class Mi2TextNotificationStrategy extends Mi2NotificationStrategy { private final BluetoothGattCharacteristic newAlertCharacteristic; - public Mi2TextNotificationStrategy(MiBand2Support support) { + public Mi2TextNotificationStrategy(HuamiSupport support) { super(support); newAlertCharacteristic = support.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_NEW_ALERT); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/AbstractFetchOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java similarity index 97% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/AbstractFetchOperation.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java index 1d0b5e72c..1909df9f5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/AbstractFetchOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java @@ -15,7 +15,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations; +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; @@ -40,8 +40,8 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceBusyAction; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.AbstractMiBand2Operation; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuamiOperation; import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -49,7 +49,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB; * An operation that fetches activity data. For every fetch, a new operation must * be created, i.e. an operation may not be reused for multiple fetches. */ -public abstract class AbstractFetchOperation extends AbstractMiBand2Operation { +public abstract class AbstractFetchOperation extends AbstractHuamiOperation { private static final Logger LOG = LoggerFactory.getLogger(AbstractFetchOperation.class); protected byte lastPacketCounter; @@ -59,7 +59,7 @@ public abstract class AbstractFetchOperation extends AbstractMiBand2Operation { protected Calendar startTimestamp; protected int expectedDataLength; - public AbstractFetchOperation(MiBand2Support support) { + public AbstractFetchOperation(HuamiSupport support) { super(support); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchActivityOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java similarity index 98% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchActivityOperation.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java index c68b178da..be8ab5309 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchActivityOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java @@ -14,7 +14,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations; +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations; import android.text.format.DateUtils; import android.widget.Toast; @@ -42,7 +42,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.User; import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WaitAction; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -55,7 +55,7 @@ public class FetchActivityOperation extends AbstractFetchOperation { private List samples = new ArrayList<>(60*24); // 1day per default - public FetchActivityOperation(MiBand2Support support) { + public FetchActivityOperation(HuamiSupport support) { super(support); setName("fetching activity data"); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchSportsDetailsOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java similarity index 98% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchSportsDetailsOperation.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java index 5700a45dc..2a403c34d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchSportsDetailsOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java @@ -15,7 +15,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations; +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations; import android.support.annotation.NonNull; import android.widget.Toast; @@ -43,7 +43,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WaitAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.ActivityDetailsParser; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -59,7 +59,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { private ByteArrayOutputStream buffer; - public FetchSportsDetailsOperation(@NonNull BaseActivitySummary summary, @NonNull MiBand2Support support, @NonNull String lastSyncTimeKey) { + public FetchSportsDetailsOperation(@NonNull BaseActivitySummary summary, @NonNull HuamiSupport support, @NonNull String lastSyncTimeKey) { super(support); setName("fetching sport details"); this.summary = summary; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchSportsSummaryOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java similarity index 99% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchSportsSummaryOperation.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java index fb2d6bad1..b58726a2c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/FetchSportsSummaryOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java @@ -14,7 +14,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations; +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; @@ -46,7 +46,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WaitAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.BipActivityType; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.util.GB; /** @@ -58,7 +58,7 @@ public class FetchSportsSummaryOperation extends AbstractFetchOperation { private ByteArrayOutputStream buffer = new ByteArrayOutputStream(140); - public FetchSportsSummaryOperation(MiBand2Support support) { + public FetchSportsSummaryOperation(HuamiSupport support) { super(support); setName("fetching sport summaries"); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/InitOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java similarity index 96% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/InitOperation.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java index d110289eb..977d9cfe9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/InitOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java @@ -14,7 +14,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations; +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; @@ -41,17 +41,17 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEOperation; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.util.GB; -public class InitOperation extends AbstractBTLEOperation { +public class InitOperation extends AbstractBTLEOperation { private static final Logger LOG = LoggerFactory.getLogger(InitOperation.class); private final TransactionBuilder builder; private final boolean needsAuth; private final byte authFlags; - public InitOperation(boolean needsAuth, byte authFlags, MiBand2Support support, TransactionBuilder builder) { + public InitOperation(boolean needsAuth, byte authFlags, HuamiSupport support, TransactionBuilder builder) { super(support); this.needsAuth = needsAuth; this.authFlags = authFlags; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/UpdateFirmwareOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java similarity index 98% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/UpdateFirmwareOperation.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java index a711c1ee0..08ba6a04a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband2/operations/UpdateFirmwareOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java @@ -14,7 +14,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations; +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; @@ -39,13 +39,13 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceBusyAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareInfo; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.AbstractMiBand2Operation; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuamiOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; -public class UpdateFirmwareOperation extends AbstractMiBand2Operation { +public class UpdateFirmwareOperation extends AbstractHuamiOperation { private static final Logger LOG = LoggerFactory.getLogger(UpdateFirmwareOperation.class); protected final Uri uri; @@ -54,7 +54,7 @@ public class UpdateFirmwareOperation extends AbstractMiBand2Operation { protected final Prefs prefs = GBApplication.getPrefs(); protected HuamiFirmwareInfo firmwareInfo; - public UpdateFirmwareOperation(Uri uri, MiBand2Support support) { + public UpdateFirmwareOperation(Uri uri, HuamiSupport support) { super(support); this.uri = uri; fwCControlChar = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_FIRMWARE); diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 1aa7a7b9e..955282199 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -217,6 +217,7 @@ @string/p_menuitem_settings @string/p_menuitem_alipay + @string/p_menuitem_status @string/p_menuitem_activity @@ -227,6 +228,39 @@ @string/p_menuitem_settings + + @string/menuitem_status + @string/menuitem_notifications + @string/menuitem_activity + @string/menuitem_weather + @string/menuitem_alarm + @string/menuitem_timer + @string/menuitem_settings + @string/menuitem_alipay + + + + @string/p_menuitem_status + @string/p_menuitem_notifications + @string/p_menuitem_activity + @string/p_menuitem_weather + @string/p_menuitem_alarm + @string/p_menuitem_timer + @string/p_menuitem_settings + @string/p_menuitem_alipay + + + + @string/p_menuitem_status + @string/p_menuitem_notifications + @string/p_menuitem_activity + @string/p_menuitem_weather + @string/p_menuitem_alarm + @string/p_menuitem_timer + @string/p_menuitem_settings + + + @string/unit_metric @string/unit_imperial diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 48322a5c9..6fc6c7f29 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -251,6 +251,7 @@ Device specific settings Mi Band / Amazfit settings Amazfit Bip settings + Amazfit Cor settingss Male Female Other @@ -582,6 +583,7 @@ Alipay (Shortcut) Weather (Shortcut) Status + Notifications Activity Weather Alarm diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml index 5e90e5b5f..90ebb612b 100644 --- a/app/src/main/res/values/values.xml +++ b/app/src/main/res/values/values.xml @@ -29,6 +29,7 @@ compass settings alipay + notifications off on diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 754af49bc..e4da96578 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -202,6 +202,18 @@ android:summary="@string/mi2_prefs_display_items_summary" android:title="@string/mi2_prefs_display_items"/> + + + Date: Wed, 1 Aug 2018 22:58:41 +0200 Subject: [PATCH 057/211] add missing file --- .../huami/amazfitcor/AmazfitCorService.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java new file mode 100644 index 000000000..3db34b267 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java @@ -0,0 +1,25 @@ +/* Copyright (C) 2015-2018 Andreas Shimokawa, Carsten Pfeiffer + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + +package nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitcor; + +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service.DISPLAY_ITEM_BIT_CLOCK; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service.ENDPOINT_DISPLAY_ITEMS; + +public class AmazfitCorService { + public static final byte[] COMMAND_CHANGE_SCREENS = new byte[]{ENDPOINT_DISPLAY_ITEMS, DISPLAY_ITEM_BIT_CLOCK, 0x20, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; +} From f464604b2724f0675738e8762f6aa43b12ba7cba Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Wed, 1 Aug 2018 23:13:36 +0200 Subject: [PATCH 058/211] Amazfit Cor: Fix notification menu not being enabled --- .../service/devices/huami/amazfitcor/AmazfitCorSupport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java index 2d5490abb..1af80624f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java @@ -50,7 +50,7 @@ public class AmazfitCorSupport extends AmazfitBipSupport { if (pages.contains("status")) { command[1] |= 0x02; } - if (pages.contains("notification")) { + if (pages.contains("notifications")) { command[1] |= 0x04; } if (pages.contains("activity")) { From cc7f6d72632cfd9304c60d6cca12c9b9052d0314 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 2 Aug 2018 10:55:30 +0200 Subject: [PATCH 059/211] More Huami refactoring - Rename MiBand2Service to HuamiService - Move preferences around (Mi Band 2 has its own device specific settings now) - Fix Cor menu items not syncing immediately in settings - Try to support settings menu items on Mi Band 3 (buggy, disabled code for now) --- .../activities/SettingsActivity.java | 61 +++++++ .../HuamiService.java} | 4 +- .../huami/amazfitbip/AmazfitBipService.java | 6 +- .../huami/amazfitcor/AmazfitCorService.java | 4 +- .../huami/miband2/MiBand2Coordinator.java | 4 +- .../devices/huami/miband3/MiBand3Service.java | 25 +++ .../miband/MiBandPreferencesActivity.java | 29 --- .../service/devices/huami/HuamiSupport.java | 166 +++++++++--------- .../huami/actions/StopNotificationAction.java | 4 +- .../huami/amazfitbip/AmazfitBipSupport.java | 15 +- .../AmazfitBipFetchLogsOperation.java | 6 +- .../huami/amazfitcor/AmazfitCorSupport.java | 4 +- .../devices/huami/miband3/MiBand3Support.java | 46 ++++- .../operations/AbstractFetchOperation.java | 14 +- .../operations/FetchActivityOperation.java | 6 +- .../FetchSportsDetailsOperation.java | 6 +- .../FetchSportsSummaryOperation.java | 6 +- .../huami/operations/InitOperation.java | 32 ++-- .../operations/UpdateFirmwareOperation.java | 28 +-- app/src/main/res/values/arrays.xml | 24 +++ app/src/main/res/values/strings.xml | 5 +- app/src/main/res/values/values.xml | 1 + app/src/main/res/xml/miband_preferences.xml | 24 --- app/src/main/res/xml/preferences.xml | 39 ++++ 24 files changed, 350 insertions(+), 209 deletions(-) rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/{miband/MiBand2Service.java => huami/HuamiService.java} (99%) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Service.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java index dd383d033..10d079d61 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java @@ -60,7 +60,9 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DISPLAY_ITEMS; +import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ENABLE_TEXT_NOTIFICATIONS; import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_HEIGHT_CM; import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_SLEEP_DURATION; import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_STEPS_GOAL; @@ -360,6 +362,64 @@ public class SettingsActivity extends AbstractSettingsActivity { } }); + final Preference setDateFormat = findPreference(PREF_MI2_DATEFORMAT); + setDateFormat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(PREF_MI2_DATEFORMAT); + } + }); + return true; + } + }); + + final Preference miBand2DisplayItems = findPreference(PREF_MI2_DISPLAY_ITEMS); + miBand2DisplayItems.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(PREF_MI2_DISPLAY_ITEMS); + } + }); + return true; + } + }); + + /* + final Preference miBand3DisplayItems = findPreference("miband3_display_items"); + miBand3DisplayItems.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(PREF_MI2_DISPLAY_ITEMS); + } + }); + return true; + } + }); + */ + + final Preference corDisplayItems = findPreference("cor_display_items"); + corDisplayItems.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + invokeLater(new Runnable() { + @Override + public void run() { + GBApplication.deviceService().onSendConfiguration(PREF_MI2_DISPLAY_ITEMS); + } + }); + return true; + } + }); + // Get all receivers of Media Buttons Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); @@ -488,6 +548,7 @@ public class SettingsActivity extends AbstractSettingsActivity { PREF_USER_WEIGHT_KG, PREF_USER_SLEEP_DURATION, PREF_USER_STEPS_GOAL, + PREF_MI2_ENABLE_TEXT_NOTIFICATIONS, "weather_city", }; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java similarity index 99% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java index 8fedb3d58..0a555b057 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java @@ -15,7 +15,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.devices.miband; +package nodomain.freeyourgadget.gadgetbridge.devices.huami; import java.util.HashMap; import java.util.Map; @@ -23,7 +23,7 @@ import java.util.UUID; import static nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport.BASE_UUID; -public class MiBand2Service { +public class HuamiService { public static final UUID UUID_SERVICE_MIBAND_SERVICE = UUID.fromString(String.format(BASE_UUID, "FEE0")); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipService.java index 36d0ce8ab..496956b41 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitbip/AmazfitBipService.java @@ -19,9 +19,9 @@ package nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip; import java.util.UUID; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service.DISPLAY_ITEM_BIT_CLOCK; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service.ENDPOINT_DISPLAY; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service.ENDPOINT_DISPLAY_ITEMS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.DISPLAY_ITEM_BIT_CLOCK; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY_ITEMS; public class AmazfitBipService { public static final UUID UUID_CHARACTERISTIC_WEATHER = UUID.fromString("0000000e-0000-3512-2118-0009af100700"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java index 3db34b267..dce25899b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java @@ -17,8 +17,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitcor; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service.DISPLAY_ITEM_BIT_CLOCK; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service.ENDPOINT_DISPLAY_ITEMS; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.DISPLAY_ITEM_BIT_CLOCK; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY_ITEMS; public class AmazfitCorService { public static final byte[] COMMAND_CHANGE_SCREENS = new byte[]{ENDPOINT_DISPLAY_ITEMS, DISPLAY_ITEM_BIT_CLOCK, 0x20, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java index 9fab9909f..c7dc78636 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband2/MiBand2Coordinator.java @@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; @@ -43,7 +43,7 @@ public class MiBand2Coordinator extends HuamiCoordinator { @NonNull @Override public DeviceType getSupportedType(GBDeviceCandidate candidate) { - if (candidate.supportsService(MiBand2Service.UUID_SERVICE_MIBAND2_SERVICE)) { + if (candidate.supportsService(HuamiService.UUID_SERVICE_MIBAND2_SERVICE)) { return DeviceType.MIBAND2; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Service.java new file mode 100644 index 000000000..7b8f1b69b --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband3/MiBand3Service.java @@ -0,0 +1,25 @@ +/* Copyright (C) 2015-2018 Andreas Shimokawa + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + +package nodomain.freeyourgadget.gadgetbridge.devices.huami.miband3; + +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.DISPLAY_ITEM_BIT_CLOCK; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY_ITEMS; + +public class MiBand3Service { + public static final byte[] COMMAND_CHANGE_SCREENS = new byte[]{ENDPOINT_DISPLAY_ITEMS, DISPLAY_ITEM_BIT_CLOCK, 0x30, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; +} 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 485dae7aa..888fc5b68 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 @@ -109,34 +109,6 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity { } }); - final Preference setDateFormat = findPreference(PREF_MI2_DATEFORMAT); - setDateFormat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - invokeLater(new Runnable() { - @Override - public void run() { - GBApplication.deviceService().onSendConfiguration(PREF_MI2_DATEFORMAT); - } - }); - return true; - } - }); - - final Preference displayPages = findPreference(PREF_MI2_DISPLAY_ITEMS); - displayPages.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - invokeLater(new Runnable() { - @Override - public void run() { - GBApplication.deviceService().onSendConfiguration(PREF_MI2_DISPLAY_ITEMS); - } - }); - return true; - } - }); - final Preference activateDisplayOnLift = findPreference(PREF_ACTIVATE_DISPLAY_ON_LIFT); activateDisplayOnLift.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override @@ -440,7 +412,6 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity { prefKeys.add(ActivityUser.PREF_USER_STEPS_GOAL); prefKeys.add(PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR); prefKeys.add(PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS); - prefKeys.add(PREF_MI2_ENABLE_TEXT_NOTIFICATIONS); prefKeys.add(PREF_MI2_INACTIVITY_WARNINGS_THRESHOLD); prefKeys.add(getNotificationPrefKey(VIBRATION_COUNT, ORIGIN_ALARM_CLOCK)); prefKeys.add(getNotificationPrefKey(VIBRATION_COUNT, ORIGIN_INCOMING_CALL)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 70d72a6f0..35ad56806 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -60,12 +60,12 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.ActivateDisplayOnLift; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService; import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2.MiBand2FWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.miband.DateTimeDisplay; import nodomain.freeyourgadget.gadgetbridge.devices.miband.DoNotDisturb; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2SampleProvider; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; @@ -185,7 +185,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { addSupportedService(MiBandService.UUID_SERVICE_MIBAND_SERVICE); addSupportedService(MiBandService.UUID_SERVICE_MIBAND2_SERVICE); - addSupportedService(MiBand2Service.UUID_SERVICE_FIRMWARE_SERVICE); + addSupportedService(HuamiService.UUID_SERVICE_FIRMWARE_SERVICE); deviceInfoProfile = new DeviceInfoProfile<>(this); addSupportedProfile(deviceInfoProfile); @@ -211,13 +211,13 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { try { boolean authenticate = needsAuth; needsAuth = false; - byte authFlags = MiBand2Service.AUTH_BYTE; + byte authFlags = HuamiService.AUTH_BYTE; if (gbDevice.getType() == DeviceType.MIBAND3) { authFlags = 0x00; } new InitOperation(authenticate, authFlags, this, builder).perform(); characteristicHRControlPoint = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT); - characteristicChunked = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_CHUNKEDTRANSFER); + characteristicChunked = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_CHUNKEDTRANSFER); } catch (IOException e) { GB.toast(getContext(), "Initializing Mi Band 2 failed", Toast.LENGTH_SHORT, GB.ERROR, e); } @@ -287,14 +287,14 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { builder.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_NOTIFICATION), enable); builder.notify(getCharacteristic(GattService.UUID_SERVICE_CURRENT_TIME), enable); // Notify CHARACTERISTIC9 to receive random auth code - builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_AUTH), enable); + builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUTH), enable); return this; } public HuamiSupport enableFurtherNotifications(TransactionBuilder builder, boolean enable) { - builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), enable); - builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_6_BATTERY_INFO), enable); - builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_DEVICEEVENT), enable); + builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), enable); + builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_6_BATTERY_INFO), enable); + builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_DEVICEEVENT), enable); return this; } @@ -357,7 +357,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { private HuamiSupport requestBatteryInfo(TransactionBuilder builder) { LOG.debug("Requesting Battery Info!"); - BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_6_BATTERY_INFO); + BluetoothGattCharacteristic characteristic = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_6_BATTERY_INFO); builder.read(characteristic); return this; } @@ -377,14 +377,14 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { private HuamiSupport setFitnessGoal(TransactionBuilder transaction) { LOG.info("Attempting to set Fitness Goal..."); - BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_8_USER_SETTINGS); + BluetoothGattCharacteristic characteristic = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_8_USER_SETTINGS); if (characteristic != null) { int fitnessGoal = GBApplication.getPrefs().getInt(ActivityUser.PREF_USER_STEPS_GOAL, 10000); byte[] bytes = ArrayUtils.addAll( - MiBand2Service.COMMAND_SET_FITNESS_GOAL_START, + HuamiService.COMMAND_SET_FITNESS_GOAL_START, BLETypeConversions.fromUint16(fitnessGoal)); bytes = ArrayUtils.addAll(bytes, - MiBand2Service.COMMAND_SET_FITNESS_GOAL_END); + HuamiService.COMMAND_SET_FITNESS_GOAL_END); transaction.write(characteristic, bytes); } else { LOG.info("Unable to set Fitness Goal"); @@ -400,7 +400,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { */ private HuamiSupport setUserInfo(TransactionBuilder transaction) { - BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_8_USER_SETTINGS); + BluetoothGattCharacteristic characteristic = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_8_USER_SETTINGS); if (characteristic == null) { return this; } @@ -432,7 +432,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { // FIXME: Do encoding like in PebbleProtocol, this is ugly byte bytes[] = new byte[]{ - MiBand2Service.COMMAND_SET_USERINFO, + HuamiService.COMMAND_SET_USERINFO, 0, 0, (byte) (birth_year & 0xff), @@ -462,16 +462,16 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { */ private HuamiSupport setWearLocation(TransactionBuilder builder) { LOG.info("Attempting to set wear location..."); - BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_8_USER_SETTINGS); + BluetoothGattCharacteristic characteristic = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_8_USER_SETTINGS); if (characteristic != null) { builder.notify(characteristic, true); int location = MiBandCoordinator.getWearLocation(getDevice().getAddress()); switch (location) { case 0: // left hand - builder.write(characteristic, MiBand2Service.WEAR_LOCATION_LEFT_WRIST); + builder.write(characteristic, HuamiService.WEAR_LOCATION_LEFT_WRIST); break; case 1: // right hand - builder.write(characteristic, MiBand2Service.WEAR_LOCATION_RIGHT_WRIST); + builder.write(characteristic, HuamiService.WEAR_LOCATION_RIGHT_WRIST); break; } builder.notify(characteristic, false); // TODO: this should actually be in some kind of finally-block in the queue. It should also be sent asynchronously after the notifications have completely arrived and processed. @@ -525,10 +525,10 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { builder.notify(characteristicHRControlPoint, true); if (enableHrSleepSupport) { LOG.info("Enabling heartrate sleep support..."); - builder.write(characteristicHRControlPoint, MiBand2Service.COMMAND_ENABLE_HR_SLEEP_MEASUREMENT); + builder.write(characteristicHRControlPoint, HuamiService.COMMAND_ENABLE_HR_SLEEP_MEASUREMENT); } else { LOG.info("Disabling heartrate sleep support..."); - builder.write(characteristicHRControlPoint, MiBand2Service.COMMAND_DISABLE_HR_SLEEP_MEASUREMENT); + builder.write(characteristicHRControlPoint, HuamiService.COMMAND_DISABLE_HR_SLEEP_MEASUREMENT); } builder.notify(characteristicHRControlPoint, false); // TODO: this should actually be in some kind of finally-block in the queue. It should also be sent asynchronously after the notifications have completely arrived and processed. } @@ -539,7 +539,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { if (characteristicHRControlPoint != null) { builder.notify(characteristicHRControlPoint, true); LOG.info("Setting heart rate measurement interval to " + minutes + " minutes"); - builder.write(characteristicHRControlPoint, new byte[]{MiBand2Service.COMMAND_SET_PERIODIC_HR_MEASUREMENT_INTERVAL, (byte) minutes}); + builder.write(characteristicHRControlPoint, new byte[]{HuamiService.COMMAND_SET_PERIODIC_HR_MEASUREMENT_INTERVAL, (byte) minutes}); builder.notify(characteristicHRControlPoint, false); // TODO: this should actually be in some kind of finally-block in the queue. It should also be sent asynchronously after the notifications have completely arrived and processed. } return this; @@ -615,7 +615,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { @Override public void onSetAlarms(ArrayList alarms) { try { - BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION); + BluetoothGattCharacteristic characteristic = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION); TransactionBuilder builder = performInitialized("Set alarm"); boolean anyAlarmEnabled = false; for (Alarm alarm : alarms) { @@ -639,9 +639,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { onAlarmClock(notificationSpec); return; } - int alertLevel = MiBand2Service.ALERT_LEVEL_MESSAGE; + int alertLevel = HuamiService.ALERT_LEVEL_MESSAGE; if (notificationSpec.type == NotificationType.UNKNOWN) { - alertLevel = MiBand2Service.ALERT_LEVEL_VIBRATE_ONLY; + alertLevel = HuamiService.ALERT_LEVEL_VIBRATE_ONLY; } String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext()).trim(); String origin = notificationSpec.type.getGenericType(); @@ -659,7 +659,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { }; 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, MiBand2Service.ALERT_LEVEL_VIBRATE_ONLY, abortAction); + performPreferredNotification("alarm clock ringing", MiBandConst.ORIGIN_ALARM_CLOCK, simpleNotification, HuamiService.ALERT_LEVEL_VIBRATE_ONLY, abortAction); } @Override @@ -692,7 +692,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { }; String message = NotificationUtils.getPreferredTextFor(callSpec); SimpleNotification simpleNotification = new SimpleNotification(message, AlertCategory.IncomingCall, null); - performPreferredNotification("incoming call", MiBandConst.ORIGIN_INCOMING_CALL, simpleNotification, MiBand2Service.ALERT_LEVEL_PHONE_CALL, abortAction); + performPreferredNotification("incoming call", MiBandConst.ORIGIN_INCOMING_CALL, simpleNotification, HuamiService.ALERT_LEVEL_PHONE_CALL, abortAction); } else if ((callSpec.command == CallSpec.CALL_START) || (callSpec.command == CallSpec.CALL_END)) { telephoneRinging = false; stopCurrentNotification(); @@ -745,7 +745,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } public HuamiSupport sendReboot(TransactionBuilder builder) { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_FIRMWARE), new byte[] { MiBand2Service.COMMAND_FIRMWARE_REBOOT}); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_FIRMWARE), new byte[] { HuamiService.COMMAND_FIRMWARE_REBOOT}); return this; } @@ -824,9 +824,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { try { TransactionBuilder builder = performInitialized(enable ? "Enabling realtime steps notifications" : "Disabling realtime steps notifications"); if (enable) { - builder.read(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS)); + builder.read(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_7_REALTIME_STEPS)); } - builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS), enable); + builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_7_REALTIME_STEPS), enable); builder.queue(getQueue()); enableRealtimeSamplesTimer(enable); } catch (IOException e) { @@ -927,7 +927,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { LOG.info("Sending " + requiredButtonPressMessage + " with button_id " + currentButtonActionId); this.getContext().getApplicationContext().sendBroadcast(in); if (prefs.getBoolean(MiBandConst.PREF_MIBAND_BUTTON_ACTION_VIBRATE, false)) { - performPreferredNotification(null, null, null, MiBand2Service.ALERT_LEVEL_VIBRATE_ONLY, null); + performPreferredNotification(null, null, null, HuamiService.ALERT_LEVEL_VIBRATE_ONLY, null); } currentButtonActionId = 0; @@ -997,7 +997,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { try { TransactionBuilder builder = performInitialized("acknowledge find phone"); - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), AmazfitBipService.COMMAND_ACK_FIND_PHONE_IN_PROGRESS); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), AmazfitBipService.COMMAND_ACK_FIND_PHONE_IN_PROGRESS); builder.queue(getQueue()); } catch (Exception ex) { LOG.error("Error sending current weather", ex); @@ -1058,7 +1058,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { super.onCharacteristicChanged(gatt, characteristic); UUID characteristicUUID = characteristic.getUuid(); - if (MiBand2Service.UUID_CHARACTERISTIC_6_BATTERY_INFO.equals(characteristicUUID)) { + if (HuamiService.UUID_CHARACTERISTIC_6_BATTERY_INFO.equals(characteristicUUID)) { handleBatteryInfo(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS); return true; } else if (MiBandService.UUID_CHARACTERISTIC_REALTIME_STEPS.equals(characteristicUUID)) { @@ -1067,14 +1067,14 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } else if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) { handleHeartrate(characteristic.getValue()); return true; - } else if (MiBand2Service.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) { + } else if (HuamiService.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) { LOG.info("AUTHENTICATION?? " + characteristicUUID); logMessageContent(characteristic.getValue()); return true; - } else if (MiBand2Service.UUID_CHARACTERISTIC_DEVICEEVENT.equals(characteristicUUID)) { + } else if (HuamiService.UUID_CHARACTERISTIC_DEVICEEVENT.equals(characteristicUUID)) { handleDeviceEvent(characteristic.getValue()); return true; - } else if (MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) { + } else if (HuamiService.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) { handleRealtimeSteps(characteristic.getValue()); return true; } else { @@ -1094,16 +1094,16 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { if (GattCharacteristic.UUID_CHARACTERISTIC_GAP_DEVICE_NAME.equals(characteristicUUID)) { handleDeviceName(characteristic.getValue(), status); return true; - } else if (MiBand2Service.UUID_CHARACTERISTIC_6_BATTERY_INFO.equals(characteristicUUID)) { + } else if (HuamiService.UUID_CHARACTERISTIC_6_BATTERY_INFO.equals(characteristicUUID)) { handleBatteryInfo(characteristic.getValue(), status); return true; } else if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) { logHeartrate(characteristic.getValue(), status); return true; - } else if (MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) { + } else if (HuamiService.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) { handleRealtimeSteps(characteristic.getValue()); return true; - } else if (MiBand2Service.UUID_CHARACTERISTIC_DEVICEEVENT.equals(characteristicUUID)) { + } else if (HuamiService.UUID_CHARACTERISTIC_DEVICEEVENT.equals(characteristicUUID)) { handleDeviceEvent(characteristic.getValue()); return true; } else { @@ -1118,7 +1118,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { public boolean onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { UUID characteristicUUID = characteristic.getUuid(); - if (MiBand2Service.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) { + if (HuamiService.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) { LOG.info("KEY AES SEND"); logMessageContent(characteristic.getValue()); return true; @@ -1313,7 +1313,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { * @param builder */ private HuamiSupport sendCalendarEvents(TransactionBuilder builder) { - BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION); + BluetoothGattCharacteristic characteristic = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION); Prefs prefs = GBApplication.getPrefs(); int availableSlots = prefs.getInt(MiBandConst.PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR, 0); @@ -1407,10 +1407,10 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { LOG.info("Setting date display to " + dateTimeDisplay); switch (dateTimeDisplay) { case TIME: - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.DATEFORMAT_TIME); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.DATEFORMAT_TIME); break; case DATE_TIME: - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.DATEFORMAT_DATE_TIME); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.DATEFORMAT_DATE_TIME); break; } return this; @@ -1420,9 +1420,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { boolean is24Format = DateFormat.is24HourFormat(getContext()); LOG.info("Setting 24h time format to " + is24Format); if (is24Format) { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.DATEFORMAT_TIME_24_HOURS); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.DATEFORMAT_TIME_24_HOURS); } else { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.DATEFORMAT_TIME_12_HOURS); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.DATEFORMAT_TIME_12_HOURS); } return this; } @@ -1431,9 +1431,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { boolean enable = HuamiCoordinator.getGoalNotification(); LOG.info("Setting goal notification to " + enable); if (enable) { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_ENABLE_GOAL_NOTIFICATION); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_ENABLE_GOAL_NOTIFICATION); } else { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_DISABLE_GOAL_NOTIFICATION); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_DISABLE_GOAL_NOTIFICATION); } return this; } @@ -1444,13 +1444,13 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { switch (displayOnLift) { case ON: - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_ENABLE_DISPLAY_ON_LIFT_WRIST); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_ENABLE_DISPLAY_ON_LIFT_WRIST); break; case OFF: - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_DISABLE_DISPLAY_ON_LIFT_WRIST); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_DISABLE_DISPLAY_ON_LIFT_WRIST); break; case SCHEDULED: - byte[] cmd = MiBand2Service.COMMAND_SCHEDULE_DISPLAY_ON_LIFT_WRIST.clone(); + byte[] cmd = HuamiService.COMMAND_SCHEDULE_DISPLAY_ON_LIFT_WRIST.clone(); Calendar calendar = GregorianCalendar.getInstance(); @@ -1464,7 +1464,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { cmd[6] = (byte) calendar.get(Calendar.HOUR_OF_DAY); cmd[7] = (byte) calendar.get(Calendar.MINUTE); - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), cmd); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), cmd); } return this; } @@ -1473,27 +1473,27 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { Set pages = HuamiCoordinator.getDisplayItems(); LOG.info("Setting display items to " + (pages == null ? "none" : pages)); - byte[] data = MiBand2Service.COMMAND_CHANGE_SCREENS.clone(); + byte[] data = HuamiService.COMMAND_CHANGE_SCREENS.clone(); if (pages != null) { if (pages.contains(MiBandConst.PREF_MI2_DISPLAY_ITEM_STEPS)) { - data[MiBand2Service.SCREEN_CHANGE_BYTE] |= MiBand2Service.DISPLAY_ITEM_BIT_STEPS; + data[HuamiService.SCREEN_CHANGE_BYTE] |= HuamiService.DISPLAY_ITEM_BIT_STEPS; } if (pages.contains(MiBandConst.PREF_MI2_DISPLAY_ITEM_DISTANCE)) { - data[MiBand2Service.SCREEN_CHANGE_BYTE] |= MiBand2Service.DISPLAY_ITEM_BIT_DISTANCE; + data[HuamiService.SCREEN_CHANGE_BYTE] |= HuamiService.DISPLAY_ITEM_BIT_DISTANCE; } if (pages.contains(MiBandConst.PREF_MI2_DISPLAY_ITEM_CALORIES)) { - data[MiBand2Service.SCREEN_CHANGE_BYTE] |= MiBand2Service.DISPLAY_ITEM_BIT_CALORIES; + data[HuamiService.SCREEN_CHANGE_BYTE] |= HuamiService.DISPLAY_ITEM_BIT_CALORIES; } if (pages.contains(MiBandConst.PREF_MI2_DISPLAY_ITEM_HEART_RATE)) { - data[MiBand2Service.SCREEN_CHANGE_BYTE] |= MiBand2Service.DISPLAY_ITEM_BIT_HEART_RATE; + data[HuamiService.SCREEN_CHANGE_BYTE] |= HuamiService.DISPLAY_ITEM_BIT_HEART_RATE; } if (pages.contains(MiBandConst.PREF_MI2_DISPLAY_ITEM_BATTERY)) { - data[MiBand2Service.SCREEN_CHANGE_BYTE] |= MiBand2Service.DISPLAY_ITEM_BIT_BATTERY; + data[HuamiService.SCREEN_CHANGE_BYTE] |= HuamiService.DISPLAY_ITEM_BIT_BATTERY; } } - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), data); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), data); return this; } @@ -1501,15 +1501,15 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { boolean enable = HuamiCoordinator.getRotateWristToSwitchInfo(); LOG.info("Setting rotate wrist to cycle info to " + enable); if (enable) { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_ENABLE_ROTATE_WRIST_TO_SWITCH_INFO); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_ENABLE_ROTATE_WRIST_TO_SWITCH_INFO); } else { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_DISABLE_ROTATE_WRIST_TO_SWITCH_INFO); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_DISABLE_ROTATE_WRIST_TO_SWITCH_INFO); } return this; } private HuamiSupport setDisplayCaller(TransactionBuilder builder) { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_ENABLE_DISPLAY_CALLER); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_ENABLE_DISPLAY_CALLER); return this; } @@ -1518,27 +1518,27 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { LOG.info("Setting do not disturb to " + doNotDisturb); switch (doNotDisturb) { case OFF: - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_DO_NOT_DISTURB_OFF); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_DO_NOT_DISTURB_OFF); break; case AUTOMATIC: - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_DO_NOT_DISTURB_AUTOMATIC); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_DO_NOT_DISTURB_AUTOMATIC); break; case SCHEDULED: - byte[] data = MiBand2Service.COMMAND_DO_NOT_DISTURB_SCHEDULED.clone(); + byte[] data = HuamiService.COMMAND_DO_NOT_DISTURB_SCHEDULED.clone(); Calendar calendar = GregorianCalendar.getInstance(); Date start = HuamiCoordinator.getDoNotDisturbStart(); calendar.setTime(start); - data[MiBand2Service.DND_BYTE_START_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); - data[MiBand2Service.DND_BYTE_START_MINUTES] = (byte) calendar.get(Calendar.MINUTE); + data[HuamiService.DND_BYTE_START_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); + data[HuamiService.DND_BYTE_START_MINUTES] = (byte) calendar.get(Calendar.MINUTE); Date end = HuamiCoordinator.getDoNotDisturbEnd(); calendar.setTime(end); - data[MiBand2Service.DND_BYTE_END_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); - data[MiBand2Service.DND_BYTE_END_MINUTES] = (byte) calendar.get(Calendar.MINUTE); + data[HuamiService.DND_BYTE_END_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); + data[HuamiService.DND_BYTE_END_MINUTES] = (byte) calendar.get(Calendar.MINUTE); - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), data); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), data); break; } @@ -1551,10 +1551,10 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { LOG.info("Setting inactivity warnings to " + enable); if (enable) { - byte[] data = MiBand2Service.COMMAND_ENABLE_INACTIVITY_WARNINGS.clone(); + byte[] data = HuamiService.COMMAND_ENABLE_INACTIVITY_WARNINGS.clone(); int threshold = HuamiCoordinator.getInactivityWarningsThreshold(); - data[MiBand2Service.INACTIVITY_WARNINGS_THRESHOLD] = (byte) threshold; + data[HuamiService.INACTIVITY_WARNINGS_THRESHOLD] = (byte) threshold; Calendar calendar = GregorianCalendar.getInstance(); @@ -1567,34 +1567,34 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { // The first interval always starts when the warnings interval starts calendar.setTime(intervalStart); - data[MiBand2Service.INACTIVITY_WARNINGS_INTERVAL_1_START_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); - data[MiBand2Service.INACTIVITY_WARNINGS_INTERVAL_1_START_MINUTES] = (byte) calendar.get(Calendar.MINUTE); + data[HuamiService.INACTIVITY_WARNINGS_INTERVAL_1_START_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); + data[HuamiService.INACTIVITY_WARNINGS_INTERVAL_1_START_MINUTES] = (byte) calendar.get(Calendar.MINUTE); if(enableDnd) { // The first interval ends when the dnd interval starts calendar.setTime(dndStart); - data[MiBand2Service.INACTIVITY_WARNINGS_INTERVAL_1_END_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); - data[MiBand2Service.INACTIVITY_WARNINGS_INTERVAL_1_END_MINUTES] = (byte) calendar.get(Calendar.MINUTE); + data[HuamiService.INACTIVITY_WARNINGS_INTERVAL_1_END_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); + data[HuamiService.INACTIVITY_WARNINGS_INTERVAL_1_END_MINUTES] = (byte) calendar.get(Calendar.MINUTE); // The second interval starts when the dnd interval ends calendar.setTime(dndEnd); - data[MiBand2Service.INACTIVITY_WARNINGS_INTERVAL_2_START_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); - data[MiBand2Service.INACTIVITY_WARNINGS_INTERVAL_2_START_MINUTES] = (byte) calendar.get(Calendar.MINUTE); + data[HuamiService.INACTIVITY_WARNINGS_INTERVAL_2_START_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); + data[HuamiService.INACTIVITY_WARNINGS_INTERVAL_2_START_MINUTES] = (byte) calendar.get(Calendar.MINUTE); // ... and it ends when the warnings interval ends calendar.setTime(intervalEnd); - data[MiBand2Service.INACTIVITY_WARNINGS_INTERVAL_2_END_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); - data[MiBand2Service.INACTIVITY_WARNINGS_INTERVAL_2_END_MINUTES] = (byte) calendar.get(Calendar.MINUTE); + data[HuamiService.INACTIVITY_WARNINGS_INTERVAL_2_END_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); + data[HuamiService.INACTIVITY_WARNINGS_INTERVAL_2_END_MINUTES] = (byte) calendar.get(Calendar.MINUTE); } else { // No Dnd, use the first interval calendar.setTime(intervalEnd); - data[MiBand2Service.INACTIVITY_WARNINGS_INTERVAL_1_END_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); - data[MiBand2Service.INACTIVITY_WARNINGS_INTERVAL_1_END_MINUTES] = (byte) calendar.get(Calendar.MINUTE); + data[HuamiService.INACTIVITY_WARNINGS_INTERVAL_1_END_HOURS] = (byte) calendar.get(Calendar.HOUR_OF_DAY); + data[HuamiService.INACTIVITY_WARNINGS_INTERVAL_1_END_MINUTES] = (byte) calendar.get(Calendar.MINUTE); } - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), data); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), data); } else { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_DISABLE_INACTIVITY_WARNINGS); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_DISABLE_INACTIVITY_WARNINGS); } return this; @@ -1604,9 +1604,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { MiBandConst.DistanceUnit unit = HuamiCoordinator.getDistanceUnit(); LOG.info("Setting distance unit to " + unit); if (unit == MiBandConst.DistanceUnit.METRIC) { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_DISTANCE_UNIT_METRIC); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_DISTANCE_UNIT_METRIC); } else { - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.COMMAND_DISTANCE_UNIT_IMPERIAL); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_DISTANCE_UNIT_IMPERIAL); } return this; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java index 702b212aa..7bcb4c38d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/actions/StopNotificationAction.java @@ -19,7 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.actions; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactionAction; public abstract class StopNotificationAction extends AbortTransactionAction { @@ -34,7 +34,7 @@ public abstract class StopNotificationAction extends AbortTransactionAction { public boolean run(BluetoothGatt gatt) { if (!super.run(gatt)) { // send a signal to stop the vibration - alertLevelCharacteristic.setValue(new byte[]{MiBand2Service.ALERT_LEVEL_NONE}); + alertLevelCharacteristic.setValue(new byte[]{HuamiService.ALERT_LEVEL_NONE}); gatt.writeCharacteristic(alertLevelCharacteristic); return false; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java index 482d00dcd..20376e138 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java @@ -37,7 +37,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiWeatherConditions; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; @@ -131,9 +131,6 @@ public class AmazfitBipSupport extends HuamiSupport { @Override protected AmazfitBipSupport setDisplayItems(TransactionBuilder builder) { - if (gbDevice.getType() != DeviceType.AMAZFITBIP) { - return this; // Disable for Cor for now - } if (gbDevice.getFirmwareVersion() == null) { LOG.warn("Device not initialized yet, won't set menu items"); return this; @@ -185,7 +182,7 @@ public class AmazfitBipSupport extends HuamiSupport { shortcut_alipay = true; } } - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), command); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), command); setShortcuts(builder, shortcut_weather, shortcut_alipay); return this; @@ -201,7 +198,7 @@ public class AmazfitBipSupport extends HuamiSupport { (byte) ((alipay && weather) ? 0x81 : 0x01), 0x01, }; - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), command); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), command); } @Override @@ -376,7 +373,7 @@ public class AmazfitBipSupport extends HuamiSupport { boolean handled = super.onCharacteristicChanged(gatt, characteristic); if (!handled) { UUID characteristicUUID = characteristic.getUuid(); - if (MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION.equals(characteristicUUID)) { + if (HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION.equals(characteristicUUID)) { return handleConfigurationInfo(characteristic.getValue()); } } @@ -399,7 +396,7 @@ public class AmazfitBipSupport extends HuamiSupport { // this probably does more than only getting the GPS version... private AmazfitBipSupport requestGPSVersion(TransactionBuilder builder) { LOG.info("Requesting GPS version"); - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), AmazfitBipService.COMMAND_REQUEST_GPS_VERSION); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), AmazfitBipService.COMMAND_REQUEST_GPS_VERSION); return this; } @@ -463,7 +460,7 @@ public class AmazfitBipSupport extends HuamiSupport { command_new = AmazfitBipService.COMMAND_SET_LANGUAGE_NEW_TEMPLATE; System.arraycopy(localeString.getBytes(), 0, command_new, 3, localeString.getBytes().length); - builder.add(new ConditionalWriteAction(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION)) { + builder.add(new ConditionalWriteAction(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION)) { @Override protected byte[] checkCondition() { if (gbDevice.getType() == DeviceType.MIBAND3 || diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/operations/AmazfitBipFetchLogsOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/operations/AmazfitBipFetchLogsOperation.java index 1386477fe..bbaeb2c85 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/operations/AmazfitBipFetchLogsOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/operations/AmazfitBipFetchLogsOperation.java @@ -33,7 +33,7 @@ import java.util.Locale; import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WaitAction; @@ -75,12 +75,12 @@ public class AmazfitBipFetchLogsOperation extends AbstractFetchOperation { GregorianCalendar sinceWhen = BLETypeConversions.createCalendar(); sinceWhen.add(Calendar.DAY_OF_MONTH, -10); builder.write(characteristicFetch, BLETypeConversions.join(new byte[]{ - MiBand2Service.COMMAND_ACTIVITY_DATA_START_DATE, + HuamiService.COMMAND_ACTIVITY_DATA_START_DATE, AmazfitBipService.COMMAND_ACTIVITY_DATA_TYPE_DEBUGLOGS}, getSupport().getTimeBytes(sinceWhen, TimeUnit.MINUTES))); builder.add(new WaitAction(1000)); // TODO: actually wait for the success-reply builder.notify(characteristicActivityData, true); - builder.write(characteristicFetch, new byte[]{MiBand2Service.COMMAND_FETCH_DATA}); + builder.write(characteristicFetch, new byte[]{HuamiService.COMMAND_FETCH_DATA}); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java index 1af80624f..7f8956759 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java @@ -27,9 +27,9 @@ import java.util.Set; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitcor.AmazfitCorFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitcor.AmazfitCorService; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSupport; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; @@ -72,7 +72,7 @@ public class AmazfitCorSupport extends AmazfitBipSupport { command[2] |= 0x01; } } - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), command); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), command); return this; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3Support.java index 930977c9f..b09eabc6d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband3/MiBand3Support.java @@ -19,14 +19,58 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband3; import android.content.Context; import android.net.Uri; -import java.io.IOException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.util.Set; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband3.MiBand3FWHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband3.MiBand3Service; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSupport; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class MiBand3Support extends AmazfitBipSupport { + private static final Logger LOG = LoggerFactory.getLogger(MiBand3Support.class); + + @Override + protected AmazfitBipSupport setDisplayItems(TransactionBuilder builder) { + if (true) { + return this; + } + + Prefs prefs = GBApplication.getPrefs(); + Set pages = prefs.getStringSet("miband3_display_items", null); + LOG.info("Setting display items to " + (pages == null ? "none" : pages)); + byte[] command = MiBand3Service.COMMAND_CHANGE_SCREENS.clone(); + + if (pages != null) { + if (pages.contains("notifications")) { + command[1] |= 0x02; + } + if (pages.contains("weather")) { + command[1] |= 0x04; + } + if (pages.contains("more")) { + command[1] |= 0x10; + } + if (pages.contains("status")) { + command[1] |= 0x20; + } + if (pages.contains("heart_rate")) { + command[1] |= 0x40; + } + } + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), command); + + return this; + } + @Override public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException { return new MiBand3FWHelper(uri, context); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java index 1909df9f5..ab3bab6b8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/AbstractFetchOperation.java @@ -36,7 +36,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceBusyAction; @@ -87,10 +87,10 @@ public abstract class AbstractFetchOperation extends AbstractHuamiOperation { } fetchCount++; - characteristicActivityData = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_5_ACTIVITY_DATA); + characteristicActivityData = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_5_ACTIVITY_DATA); builder.notify(characteristicActivityData, false); - characteristicFetch = getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC4); + characteristicFetch = getCharacteristic(HuamiService.UUID_UNKNOWN_CHARACTERISTIC4); builder.notify(characteristicFetch, true); startFetching(builder); @@ -105,10 +105,10 @@ public abstract class AbstractFetchOperation extends AbstractHuamiOperation { public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { UUID characteristicUUID = characteristic.getUuid(); - if (MiBand2Service.UUID_CHARACTERISTIC_5_ACTIVITY_DATA.equals(characteristicUUID)) { + if (HuamiService.UUID_CHARACTERISTIC_5_ACTIVITY_DATA.equals(characteristicUUID)) { handleActivityNotif(characteristic.getValue()); return true; - } else if (MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC4.equals(characteristicUUID)) { + } else if (HuamiService.UUID_UNKNOWN_CHARACTERISTIC4.equals(characteristicUUID)) { handleActivityMetadata(characteristic.getValue()); return true; } else { @@ -140,7 +140,7 @@ public abstract class AbstractFetchOperation extends AbstractHuamiOperation { protected void handleActivityMetadata(byte[] value) { if (value.length == 15) { // first two bytes are whether our request was accepted - if (ArrayUtils.equals(value, MiBand2Service.RESPONSE_ACTIVITY_DATA_START_DATE_SUCCESS, 0)) { + if (ArrayUtils.equals(value, HuamiService.RESPONSE_ACTIVITY_DATA_START_DATE_SUCCESS, 0)) { // the third byte (0x01 on success) = ? // the 4th - 7th bytes epresent the number of bytes/packets to expect, excluding the counter bytes expectedDataLength = BLETypeConversions.toUint32(Arrays.copyOfRange(value, 3, 7)); @@ -157,7 +157,7 @@ public abstract class AbstractFetchOperation extends AbstractHuamiOperation { handleActivityFetchFinish(false); } } else if (value.length == 3) { - if (Arrays.equals(MiBand2Service.RESPONSE_FINISH_SUCCESS, value)) { + if (Arrays.equals(HuamiService.RESPONSE_FINISH_SUCCESS, value)) { handleActivityFetchFinish(true); } else { LOG.warn("Unexpected activity metadata: " + Logging.formatBytes(value)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java index be8ab5309..650bc2406 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchActivityOperation.java @@ -33,7 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandSampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; @@ -69,10 +69,10 @@ public class FetchActivityOperation extends AbstractFetchOperation { @Override protected void startFetching(TransactionBuilder builder) { GregorianCalendar sinceWhen = getLastSuccessfulSyncTime(); - builder.write(characteristicFetch, BLETypeConversions.join(new byte[] { MiBand2Service.COMMAND_ACTIVITY_DATA_START_DATE, MiBand2Service.COMMAND_ACTIVITY_DATA_TYPE_ACTIVTY }, getSupport().getTimeBytes(sinceWhen, TimeUnit.MINUTES))); + builder.write(characteristicFetch, BLETypeConversions.join(new byte[] { HuamiService.COMMAND_ACTIVITY_DATA_START_DATE, HuamiService.COMMAND_ACTIVITY_DATA_TYPE_ACTIVTY }, getSupport().getTimeBytes(sinceWhen, TimeUnit.MINUTES))); builder.add(new WaitAction(1000)); // TODO: actually wait for the success-reply builder.notify(characteristicActivityData, true); - builder.write(characteristicFetch, new byte[] { MiBand2Service.COMMAND_FETCH_DATA}); + builder.write(characteristicFetch, new byte[] { HuamiService.COMMAND_FETCH_DATA}); } protected void handleActivityFetchFinish(boolean success) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java index 2a403c34d..6de70b5e6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java @@ -33,7 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary; import nodomain.freeyourgadget.gadgetbridge.export.ActivityTrackExporter; import nodomain.freeyourgadget.gadgetbridge.export.GPXExporter; @@ -73,12 +73,12 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { GregorianCalendar sinceWhen = getLastSuccessfulSyncTime(); builder.write(characteristicFetch, BLETypeConversions.join(new byte[] { - MiBand2Service.COMMAND_ACTIVITY_DATA_START_DATE, + HuamiService.COMMAND_ACTIVITY_DATA_START_DATE, AmazfitBipService.COMMAND_ACTIVITY_DATA_TYPE_SPORTS_DETAILS}, getSupport().getTimeBytes(sinceWhen, TimeUnit.MINUTES))); builder.add(new WaitAction(1000)); // TODO: actually wait for the success-reply builder.notify(characteristicActivityData, true); - builder.write(characteristicFetch, new byte[] { MiBand2Service.COMMAND_FETCH_DATA }); + builder.write(characteristicFetch, new byte[] { HuamiService.COMMAND_FETCH_DATA }); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java index b58726a2c..0d26eca17 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java @@ -35,8 +35,8 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; @@ -68,12 +68,12 @@ public class FetchSportsSummaryOperation extends AbstractFetchOperation { LOG.info("start" + getName()); GregorianCalendar sinceWhen = getLastSuccessfulSyncTime(); builder.write(characteristicFetch, BLETypeConversions.join(new byte[] { - MiBand2Service.COMMAND_ACTIVITY_DATA_START_DATE, + HuamiService.COMMAND_ACTIVITY_DATA_START_DATE, AmazfitBipService.COMMAND_ACTIVITY_DATA_TYPE_SPORTS_SUMMARIES}, getSupport().getTimeBytes(sinceWhen, TimeUnit.MINUTES))); builder.add(new WaitAction(1000)); // TODO: actually wait for the success-reply builder.notify(characteristicActivityData, true); - builder.write(characteristicFetch, new byte[] { MiBand2Service.COMMAND_FETCH_DATA }); + builder.write(characteristicFetch, new byte[] { HuamiService.COMMAND_FETCH_DATA }); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java index 977d9cfe9..a7d64a135 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java @@ -36,7 +36,7 @@ import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEOperation; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; @@ -65,17 +65,17 @@ public class InitOperation extends AbstractBTLEOperation { if (needsAuth) { builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.AUTHENTICATING, getContext())); // write key to miband2 - byte[] sendKey = org.apache.commons.lang3.ArrayUtils.addAll(new byte[]{MiBand2Service.AUTH_SEND_KEY, authFlags}, getSecretKey()); - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_AUTH), sendKey); + byte[] sendKey = org.apache.commons.lang3.ArrayUtils.addAll(new byte[]{HuamiService.AUTH_SEND_KEY, authFlags}, getSecretKey()); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUTH), sendKey); } else { builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); // get random auth number - builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_AUTH), requestAuthNumber()); + builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUTH), requestAuthNumber()); } } private byte[] requestAuthNumber() { - return new byte[]{MiBand2Service.AUTH_REQUEST_RANDOM_AUTH_NUMBER, authFlags}; + return new byte[]{HuamiService.AUTH_REQUEST_RANDOM_AUTH_NUMBER, authFlags}; } private byte[] getSecretKey() { @@ -91,31 +91,31 @@ public class InitOperation extends AbstractBTLEOperation { public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { UUID characteristicUUID = characteristic.getUuid(); - if (MiBand2Service.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) { + if (HuamiService.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) { try { byte[] value = characteristic.getValue(); getSupport().logMessageContent(value); - if (value[0] == MiBand2Service.AUTH_RESPONSE && - value[1] == MiBand2Service.AUTH_SEND_KEY && - value[2] == MiBand2Service.AUTH_SUCCESS) { + if (value[0] == HuamiService.AUTH_RESPONSE && + value[1] == HuamiService.AUTH_SEND_KEY && + value[2] == HuamiService.AUTH_SUCCESS) { TransactionBuilder builder = createTransactionBuilder("Sending the secret key to the band"); builder.write(characteristic, requestAuthNumber()); getSupport().performImmediately(builder); - } else if (value[0] == MiBand2Service.AUTH_RESPONSE && - value[1] == MiBand2Service.AUTH_REQUEST_RANDOM_AUTH_NUMBER && - value[2] == MiBand2Service.AUTH_SUCCESS) { + } else if (value[0] == HuamiService.AUTH_RESPONSE && + value[1] == HuamiService.AUTH_REQUEST_RANDOM_AUTH_NUMBER && + value[2] == HuamiService.AUTH_SUCCESS) { // md5?? byte[] eValue = handleAESAuth(value, getSecretKey()); byte[] responseValue = org.apache.commons.lang3.ArrayUtils.addAll( - new byte[]{MiBand2Service.AUTH_SEND_ENCRYPTED_AUTH_NUMBER, authFlags}, eValue); + new byte[]{HuamiService.AUTH_SEND_ENCRYPTED_AUTH_NUMBER, authFlags}, eValue); TransactionBuilder builder = createTransactionBuilder("Sending the encrypted random key to the band"); builder.write(characteristic, responseValue); getSupport().setCurrentTimeWithService(builder); getSupport().performImmediately(builder); - } else if (value[0] == MiBand2Service.AUTH_RESPONSE && - value[1] == MiBand2Service.AUTH_SEND_ENCRYPTED_AUTH_NUMBER && - value[2] == MiBand2Service.AUTH_SUCCESS) { + } else if (value[0] == HuamiService.AUTH_RESPONSE && + value[1] == HuamiService.AUTH_SEND_ENCRYPTED_AUTH_NUMBER && + value[2] == HuamiService.AUTH_SUCCESS) { TransactionBuilder builder = createTransactionBuilder("Authenticated, now initialize phase 2"); builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); getSupport().requestDeviceInfo(builder); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java index 08ba6a04a..08ffaff62 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation.java @@ -33,7 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventDisplayMessage; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceBusyAction; @@ -57,8 +57,8 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation { public UpdateFirmwareOperation(Uri uri, HuamiSupport support) { super(support); this.uri = uri; - fwCControlChar = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_FIRMWARE); - fwCDataChar = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_FIRMWARE_DATA); + fwCControlChar = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_FIRMWARE); + fwCDataChar = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_FIRMWARE_DATA); } @Override @@ -132,20 +132,20 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation { getSupport().logMessageContent(value); return; } - boolean success = value[2] == MiBand2Service.SUCCESS; + boolean success = value[2] == HuamiService.SUCCESS; - if (value[0] == MiBand2Service.RESPONSE && success) { + if (value[0] == HuamiService.RESPONSE && success) { try { switch (value[1]) { - case MiBand2Service.COMMAND_FIRMWARE_INIT: { + case HuamiService.COMMAND_FIRMWARE_INIT: { sendFirmwareData(getFirmwareInfo()); break; } - case MiBand2Service.COMMAND_FIRMWARE_START_DATA: { + case HuamiService.COMMAND_FIRMWARE_START_DATA: { sendChecksum(getFirmwareInfo()); break; } - case MiBand2Service.COMMAND_FIRMWARE_CHECKSUM: { + case HuamiService.COMMAND_FIRMWARE_CHECKSUM: { if (getFirmwareInfo().getFirmwareType() == HuamiFirmwareType.FIRMWARE) { TransactionBuilder builder = performInitialized("reboot"); getSupport().sendReboot(builder); @@ -156,7 +156,7 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation { } break; } - case MiBand2Service.COMMAND_FIRMWARE_REBOOT: { + case HuamiService.COMMAND_FIRMWARE_REBOOT: { LOG.info("Reboot command successfully sent."); GB.updateInstallNotification(getContext().getString(R.string.updatefirmwareoperation_update_complete), false, 100, getContext()); // getSupport().onReboot(); @@ -202,7 +202,7 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation { } byte[] bytes = new byte[arraySize]; int i = 0; - bytes[i++] = MiBand2Service.COMMAND_FIRMWARE_INIT; + bytes[i++] = HuamiService.COMMAND_FIRMWARE_INIT; bytes[i++] = sizeBytes[0]; bytes[i++] = sizeBytes[1]; bytes[i++] = sizeBytes[2]; @@ -243,7 +243,7 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation { if (prefs.getBoolean("mi_low_latency_fw_update", true)) { getSupport().setLowLatency(builder); } - builder.write(fwCControlChar, new byte[] { MiBand2Service.COMMAND_FIRMWARE_START_DATA }); + builder.write(fwCControlChar, new byte[] { HuamiService.COMMAND_FIRMWARE_START_DATA }); for (int i = 0; i < packets; i++) { byte[] fwChunk = Arrays.copyOfRange(fwbytes, i * packetLength, i * packetLength + packetLength); @@ -253,7 +253,7 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation { int progressPercent = (int) ((((float) firmwareProgress) / len) * 100); if ((i > 0) && (i % 100 == 0)) { - builder.write(fwCControlChar, new byte[]{MiBand2Service.COMMAND_FIRMWARE_UPDATE_SYNC}); + builder.write(fwCControlChar, new byte[]{HuamiService.COMMAND_FIRMWARE_UPDATE_SYNC}); builder.add(new SetProgressAction(getContext().getString(R.string.updatefirmwareoperation_update_in_progress), true, progressPercent, getContext())); } } @@ -264,7 +264,7 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation { firmwareProgress = len; } - builder.write(fwCControlChar, new byte[]{MiBand2Service.COMMAND_FIRMWARE_UPDATE_SYNC}); + builder.write(fwCControlChar, new byte[]{HuamiService.COMMAND_FIRMWARE_UPDATE_SYNC}); builder.queue(getQueue()); } catch (IOException ex) { @@ -281,7 +281,7 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation { int crc16 = firmwareInfo.getCrc16(); byte[] bytes = BLETypeConversions.fromUint16(crc16); builder.write(fwCControlChar, new byte[] { - MiBand2Service.COMMAND_FIRMWARE_CHECKSUM, + HuamiService.COMMAND_FIRMWARE_CHECKSUM, bytes[0], bytes[1], }); diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 955282199..128a49378 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -192,6 +192,30 @@ @string/p_battery + + @string/menuitem_notifications + @string/menuitem_weather + @string/menuitem_more + @string/menuitem_status + @string/heart_rate + + + + @string/p_menuitem_notifications + @string/p_menuitem_weather + @string/p_menuitem_more + @string/p_menuitem_status + @string/p_heart_rate + + + + @string/p_menuitem_notifications + @string/p_menuitem_weather + @string/p_menuitem_more + @string/p_menuitem_status + @string/p_heart_rate + + @string/menuitem_shortcut_alipay @string/menuitem_shortcut_weather diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6fc6c7f29..f3687c6ba 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -250,6 +250,8 @@ No MAC address passed, cannot pair. Device specific settings Mi Band / Amazfit settings + Mi Band 2 settings + Mi Band 3 settings Amazfit Bip settings Amazfit Cor settingss Male @@ -390,7 +392,7 @@ Alarms to reserve for upcoming events Use heart rate sensor to improve sleep detection Device time offset in hours (for detecting sleep of shift workers) - Mi2: Date format + Date format Time Button actions @@ -591,4 +593,5 @@ Compass Settings Alipay + More diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml index 90ebb612b..af094502c 100644 --- a/app/src/main/res/values/values.xml +++ b/app/src/main/res/values/values.xml @@ -30,6 +30,7 @@ settings alipay notifications + more off on diff --git a/app/src/main/res/xml/miband_preferences.xml b/app/src/main/res/xml/miband_preferences.xml index 9ebefb84e..5a8b262f1 100644 --- a/app/src/main/res/xml/miband_preferences.xml +++ b/app/src/main/res/xml/miband_preferences.xml @@ -113,15 +113,6 @@ android:maxLength="2" android:title="@string/miband_prefs_device_time_offset_hours" /> - - @@ -153,21 +144,6 @@ android:key="mi2_rotate_wrist_to_switch_info" android:title="@string/mi2_prefs_rotate_wrist_to_switch_info" /> - - - - + + + + + + From d9f990b3fa170d4cbbcd21847354bddebfb2b1f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 28 Jul 2018 16:49:29 +0200 Subject: [PATCH 060/211] Vertically align device icon (cherry picked from commit ca9229c) --- app/src/main/res/layout/device_itemv2.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/device_itemv2.xml b/app/src/main/res/layout/device_itemv2.xml index f046e571c..4ad19fb84 100644 --- a/app/src/main/res/layout/device_itemv2.xml +++ b/app/src/main/res/layout/device_itemv2.xml @@ -64,7 +64,7 @@ android:longClickable="true" android:background="?android:attr/selectableItemBackground" android:src="@drawable/ic_device_pebble" - android:layout_marginTop="8dp" + android:layout_marginTop="2dp" android:focusable="true" /> Date: Thu, 2 Aug 2018 22:02:22 +0200 Subject: [PATCH 061/211] Adjust testcases for samples with calculated timestamps --- .../gadgetbridge/test/ActivityDetailsParserTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/ActivityDetailsParserTest.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/ActivityDetailsParserTest.java index 61e34a58f..253347b7c 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/ActivityDetailsParserTest.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/ActivityDetailsParserTest.java @@ -47,7 +47,7 @@ public class ActivityDetailsParserTest extends TestBase { assertEquals("Elvis", track.getUser().getName()); List trackPoints = track.getTrackPoints(); - assertEquals(939, trackPoints.size()); + assertEquals(972, trackPoints.size()); } } @@ -86,7 +86,7 @@ public class ActivityDetailsParserTest extends TestBase { ActivityTrack track = parser.parse(FileUtils.readAll(in, MAX_DETAILS)); List trackPoints = track.getTrackPoints(); - assertEquals(939, trackPoints.size()); + assertEquals(972, trackPoints.size()); GPXExporter exporter = new GPXExporter(); From 66391e10c90bd06fc8a8103c935b39096a8a570c Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 2 Aug 2018 22:29:25 +0200 Subject: [PATCH 062/211] Amazfit Cor: Allow to enable music menu on device --- .../devices/huami/amazfitcor/AmazfitCorService.java | 2 +- .../service/devices/huami/amazfitcor/AmazfitCorSupport.java | 3 +++ app/src/main/res/values/arrays.xml | 3 +++ app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/values.xml | 1 + 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java index dce25899b..0f63c0b08 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitcor/AmazfitCorService.java @@ -21,5 +21,5 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.DI import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY_ITEMS; public class AmazfitCorService { - public static final byte[] COMMAND_CHANGE_SCREENS = new byte[]{ENDPOINT_DISPLAY_ITEMS, DISPLAY_ITEM_BIT_CLOCK, 0x20, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; + public static final byte[] COMMAND_CHANGE_SCREENS = new byte[]{ENDPOINT_DISPLAY_ITEMS, DISPLAY_ITEM_BIT_CLOCK, 0x20, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java index 7f8956759..a3d614624 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorSupport.java @@ -71,6 +71,9 @@ public class AmazfitCorSupport extends AmazfitBipSupport { if (pages.contains("alipay")) { command[2] |= 0x01; } + if (pages.contains("music")) { + command[2] |= 0x02; + } } builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), command); diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 128a49378..df4d09dcd 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -261,6 +261,7 @@ @string/menuitem_timer @string/menuitem_settings @string/menuitem_alipay + @string/menuitem_music @@ -272,6 +273,7 @@ @string/p_menuitem_timer @string/p_menuitem_settings @string/p_menuitem_alipay + @string/p_menuitem_music @@ -282,6 +284,7 @@ @string/p_menuitem_alarm @string/p_menuitem_timer @string/p_menuitem_settings + @string/p_menuitem_music diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f3687c6ba..29cab8301 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -593,5 +593,6 @@ Compass Settings Alipay + Music More diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml index af094502c..96d5d895c 100644 --- a/app/src/main/res/values/values.xml +++ b/app/src/main/res/values/values.xml @@ -30,6 +30,7 @@ settings alipay notifications + music more off From fe401bdcf5590b3230d354dded4c7658ef528bfe Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 2 Aug 2018 22:35:02 +0200 Subject: [PATCH 063/211] Amazfit Cor: allow music control --- .../devices/huami/HuamiDeviceEvent.java | 1 + .../service/devices/huami/HuamiSupport.java | 32 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java index 9f76582a9..a1d937a15 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiDeviceEvent.java @@ -30,4 +30,5 @@ public class HuamiDeviceEvent { public static final byte BUTTON_PRESSED_LONG = 0x0b; public static final byte TICK_30MIN = 0x0e; // unsure public static final byte FIND_PHONE_STOP = 0x0f; + public static final byte MUSIC_CONTROL = (byte) 0xfe; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 35ad56806..9448064f8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -54,6 +54,7 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.huami.ActivateDisplayOnLift; @@ -937,7 +938,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { } public void handleDeviceEvent(byte[] value) { - if (value == null || value.length != 1) { + if (value == null || value.length == 0) { return; } GBDeviceEventCallControl callCmd = new GBDeviceEventCallControl(); @@ -988,6 +989,35 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { findPhoneEvent.event = GBDeviceEventFindPhone.Event.STOP; evaluateGBDeviceEvent(findPhoneEvent); break; + case HuamiDeviceEvent.MUSIC_CONTROL: + LOG.info("got music control"); + GBDeviceEventMusicControl deviceEventMusicControl = new GBDeviceEventMusicControl(); + + switch (value[1]) { + case 0: + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PLAY; + break; + case 1: + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PAUSE; + break; + case 3: + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.NEXT; + break; + case 4: + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.PREVIOUS; + break; + case 5: + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.VOLUMEUP; + break; + case 6: + deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.VOLUMEDOWN; + break; + default: + LOG.info("unhandled music control event " + value[1]); + return; + } + evaluateGBDeviceEvent(deviceEventMusicControl); + break; default: LOG.warn("unhandled event " + value[0]); } From 5bca05caac80833a777f4e07c465fd115daf71a4 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sat, 4 Aug 2018 23:10:11 +0200 Subject: [PATCH 064/211] Fix loop condition! --- .../service/devices/huami/amazfitbip/ActivityDetailsParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java index 1b11daab5..6cec7e594 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/ActivityDetailsParser.java @@ -140,7 +140,7 @@ public class ActivityDetailsParser { List activityPointList = activityTrack.getTrackPoints(); Date gpsStartTime = null; List entriesToFixUp = new ArrayList<>(); - while (pointer < activityPointList.size() + 1) { + while (pointer < activityPointList.size() - 1) { ActivityPoint activityPoint = activityPointList.get(pointer); if (activityPoint.getLocation() == null) { pointer++; From 84f903cd8bc167e8eec33e4752e4f04bb5882900 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Tue, 31 Jul 2018 21:29:20 +0000 Subject: [PATCH 065/211] Translated using Weblate (Hebrew) Currently translated at 100.0% (507 of 507 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 95dc9117f..43c4de836 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -555,4 +555,11 @@ רוסית + הגדרות ID115 + כיוון המסך + + אופקי + אנכי + ID115 + From f9b9c3404262f308bdf1ae0f0d57715b684844f1 Mon Sep 17 00:00:00 2001 From: mesnevi Date: Wed, 1 Aug 2018 06:00:05 +0000 Subject: [PATCH 066/211] Translated using Weblate (Russian) Currently translated at 100.0% (507 of 507 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 28 ++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 6953ed01f..23279c657 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -273,7 +273,7 @@ Расстояние Жизненная активность Шагов сегодня, цель: %1$s - Не передавать данные об активности + Не подтверждать передачу данных об активности Если данные об активности не будут переданы на устройство, оно не будет очищено. Полезно, если GB используется с другими приложениями. Хранить данные о деятельности на Mi Band, даже после синхронизации. Полезно, если Mi Band используется совместно с другими приложениями. Использовать режим с низкими задержками для обновления прошивки @@ -496,7 +496,7 @@ Местоположение для погоды (CM/LOS) Подключаться только в режиме GATT-клиента - Экспериментальные настройки только для Pebble 2. Попробуйте, если есть проблемы с соединением. + Экспериментальные настройки только для Pebble 2. Попробуйте, если связь не очень Автоматический экспорт данных Включить автоматический экспорт Путь экспорта @@ -540,4 +540,28 @@ XWatch MyKronoz ZeTime + Настройки ID115 + Ориентация экрана + + Загружать данные об активности автоматически + Загрузка данных каждый раз, когда экран разблокируют. Это работает только если настроена блокировка экрана! + Минимальный интервал между загрузками + Загружать каждые %d минут(ы) + + Горизонтально + Вертикально + Отслеживание активности + Статистика активности + Сбросить дату загрузки + + Недопустимый формат данных + Данные GPS + Поправка ошибки GPS + No.1 F1 + ID115 + + Куда сохранять данные при экспорте + Уведомления Gadgetbridge + + Активность From 3a0bf06896ddb8d20d6597cdb83c40822645a769 Mon Sep 17 00:00:00 2001 From: mesnevi Date: Wed, 1 Aug 2018 10:03:42 +0000 Subject: [PATCH 067/211] Translated using Weblate (Russian) Currently translated at 100.0% (507 of 507 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 23279c657..62d4fd847 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -482,8 +482,8 @@ Погода Компас Настройки - Заблокировать все - Разблокировать все + Заблокировать все уведомления + Разблокировать все уведомления Вы собираетесь установить прошивку %s на ваш Mi Band 3. From 1ae1aaa90c612b39d5fc4cbcf790901f335a23cf Mon Sep 17 00:00:00 2001 From: mesnevi Date: Wed, 1 Aug 2018 21:58:35 +0000 Subject: [PATCH 068/211] Translated using Weblate (Russian) Currently translated at 100.0% (509 of 509 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 62d4fd847..c0eddc960 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -564,4 +564,6 @@ Уведомления Gadgetbridge Активность + Настройки Amazfit Cors + Уведомления From ee855af46f3db263dadadd1429b11c07c6c5086c Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Thu, 2 Aug 2018 09:13:32 +0000 Subject: [PATCH 069/211] Translated using Weblate (Hebrew) Currently translated at 100.0% (512 of 512 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 43c4de836..ac5134bf6 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -283,7 +283,7 @@ התראות לשמירה עבור אירועים עתידיים ניתן להשתמש בחיישן הדופק כדי לשפר את איתור השינה הפרש זמן בהתקן בשעות (לזיהוי שינה של עובדי משמרות) - Mi2: תבנית זמן + תבנית זמן זמן הפעלת התצוגה עם הנפת היד @@ -562,4 +562,9 @@ אנכי ID115 - + הגדרות Mi Band 2 + הגדרות Mi Band 3 + הגדרות Amazfit Cors + התראות + עוד + From 69c2c0c149965fed9a5564470baf54d42ca70652 Mon Sep 17 00:00:00 2001 From: mesnevi Date: Thu, 2 Aug 2018 09:24:19 +0000 Subject: [PATCH 070/211] Translated using Weblate (Russian) Currently translated at 100.0% (512 of 512 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index c0eddc960..0b93a80ab 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -295,7 +295,7 @@ Резервные сигналы для предстоящих событий Использовать датчик сердцебиения для улучшения мониторинга сна Смещение времени в часах (для тех, кто работает по ночам) - Mi2: Формат даты + Формат даты Время Время и дата Активировать экран при подъёме @@ -566,4 +566,7 @@ Активность Настройки Amazfit Cors Уведомления - + Настройки Mi Band 2 + Настройки Mi Band 3 + Ещё + From f474816e42dad4eec48573cc9caa3282d1aafff1 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Thu, 2 Aug 2018 09:14:24 +0000 Subject: [PATCH 071/211] Translated using Weblate (Hebrew) Currently translated at 100.0% (512 of 512 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/he/ --- app/src/main/res/values-he/strings.xml | 30 +++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index ac5134bf6..1cb63b5c0 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -33,7 +33,7 @@ הגדרה העברה למעלה - רשימת התרעות חסומות + רשימת התראות חסומות התקנת קושחה/יישומון @@ -57,7 +57,7 @@ בהירה כהה שפה - הסתרת ההתרעות של Gadgetbridge + הסתרת ההתראות של Gadgetbridge הסמל בשורת המצב והדיווח במסך הנעילה מופיעים הסמל בשורת המצב והדיווח במסך הנעילה מוסתרים דיווחים @@ -69,7 +69,7 @@ תמיכה בדיווחים גנריים …גם כאשר המסך פעיל לא להפריע - חסימת שליחה של התרעות בלתי רצויות בזמן שהמצב מכוון על לא להפריע + חסימת שליחה של התראות בלתי רצויות בזמן שהמצב מכוון על לא להפריע תעתיק תמיד כאשר המסך כבוי @@ -137,8 +137,8 @@ מצב לא ידוע (לא ידוע) בדיקה - התרעה לבדיקה - זוהי התרעה לבדיקה מ־Gadgetbridge + התראה לבדיקה + זוהי התראה לבדיקה מ־Gadgetbridge אין תמיכה ב־Bluetooth. ה־Bluetooth מנוטרל. נקישה על ההתקן המחובר למנהל היישומים @@ -200,11 +200,11 @@ שעון מעורר רטט בדיקה - התרעת מסרון + התראת מסרון הגדרות רטט - התרעות כלליות - התרעה על דוא״ל - התרעה על שיחה נכנסת + התראות כלליות + התראה על דוא״ל + התראה על שיחה נכנסת צ׳אט ניווט רשת חברתית @@ -299,7 +299,7 @@ חררר הוספת וידג׳ט משך השינה המועדף בשעות - הוגדרה התרעה לשעה %1$02d:%2$02d + הוגדרה התראה לשעה %1$02d:%2$02d מהדורת חומרה: %1$s מהדורת קושחה: %1$s אירעה שגיאה ביצירת תיקייה לקובצי הרישום: %1$s @@ -375,13 +375,13 @@ שעון דופק סוללה - התרעת יעד + התראת יעד הצמיד ירטוט כאשר הגעת ליעד הצעדים היומי הצגת פריטים בחירת הפריטים שיופיעו על מסך הצמיד הטיית היד כדי לעבור למצב נתונים אחר לא להפריע - הצמיד לא יקבל התרעות בזמן הפעילות + הצמיד לא יקבל התראות בזמן הפעילות אזהרות חוסר פעילות הצמיד ירטוט כשלא ביצעת פעילות במשך זמן מה סף חוסר פעילות (בדקות) @@ -401,7 +401,7 @@ שגיאה בייצוא ההעדפה: %1$s שגיאה בייבוא העדפה: %1$s עליך להתקין את הגרסה %1$s בטרם התקנת קושחה זו! - התרעות טקסט + התראות טקסט נדרשת קושחה >= 1.0.1.28 והקובץ Mili_pro.ft*‎ מותקן. כבוי כבוי @@ -540,8 +540,8 @@ \n \nהתהליך לא נבדק, ההתקן שלך עשוי להפסיק לפעול, המשך התהליך הוא על אחריותך! Mi Band 3 - הוספת כולם לרשימה השחורה של ההתרעות - הוספת כולם לרשימת ההיתר של ההתרעות + הוספת כולם לרשימה השחורה של ההתראות + הוספת כולם לרשימת ההיתר של ההתראות אחזור אוטומטי של נתוני פעילות From 810af68854be9dc24b3e23945b2de5435508433e Mon Sep 17 00:00:00 2001 From: mesnevi Date: Thu, 2 Aug 2018 21:29:32 +0000 Subject: [PATCH 072/211] Translated using Weblate (Russian) Currently translated at 100.0% (513 of 513 strings) Translation: Freeyourgadget/Gadgetbridge Translate-URL: https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/ru/ --- app/src/main/res/values-ru/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 0b93a80ab..e562b161a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -569,4 +569,5 @@ Настройки Mi Band 2 Настройки Mi Band 3 Ещё - +Музыка + From fe438f2354a982722a82eb495e20af97b7403533 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sun, 5 Aug 2018 00:00:52 +0200 Subject: [PATCH 073/211] More detailed changelog for ZeTime for 0.28 (taken from https://github.com/Lightwars/Gadgetbridge-1/commit/8af6515df886878a55be4d343e27b6e68a9ff32d) --- CHANGELOG.md | 2 +- app/src/main/res/xml/changelog_master.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d6210945..0843662ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ * Amazfit Bip: Fix weather on latest firmwares #### Version 0.28.0 -* Initial support for ZeTime +* Initial support for ZeTime: time, weather and activity data sync, notification support and music playback control is working * Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme * Amazfit Bip: Support setting language to Russian * Amazfit Cor: Support language switching on newer firmwares diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml index 65decd4ac..31edd1b28 100644 --- a/app/src/main/res/xml/changelog_master.xml +++ b/app/src/main/res/xml/changelog_master.xml @@ -8,7 +8,7 @@ Amazfit Bip: Fix weather on latest firmwares - Initial support for ZeTime + Initial support for ZeTime: time, weather and activity data sync, notification support and music playback control is working Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme Amazfit Bip: Support setting language to Russian Amazfit Cor: Support language switching on newer firmwares From 343239ff9e15abb214c15a5cc447b167ed2f3144 Mon Sep 17 00:00:00 2001 From: protomors Date: Thu, 2 Nov 2017 21:21:47 +0200 Subject: [PATCH 074/211] NO1 F1: Fixed typo. --- .../gadgetbridge/service/devices/no1f1/No1F1Support.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java index d09a2a3cd..396efde03 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java @@ -598,7 +598,7 @@ public class No1F1Support extends AbstractBTLEDeviceSupport { if (data[0] == No1F1Constants.CMD_FETCH_STEPS) { samples.get(i).setRawKind(ActivityKind.TYPE_ACTIVITY); samples.get(i).setRawIntensity(samples.get(i).getSteps()); - } else if (data[0] == No1F1Constants.CMD_FETCH_STEPS) { + } else if (data[0] == No1F1Constants.CMD_FETCH_SLEEP) { if (samples.get(i).getRawIntensity() < 7) samples.get(i).setRawKind(ActivityKind.TYPE_DEEP_SLEEP); else From fd68700b9a911d414e5b1b5df116049f0e05db50 Mon Sep 17 00:00:00 2001 From: protomors Date: Tue, 17 Jul 2018 11:56:36 +0300 Subject: [PATCH 075/211] NO1 F1: Set time during initialization. --- .../service/devices/no1f1/No1F1Support.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java index 396efde03..228bcd8b6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java @@ -89,6 +89,7 @@ public class No1F1Support extends AbstractBTLEDeviceSupport { builder.setGattCallback(this); builder.notify(measureCharacteristic, true); + setTime(builder); sendSettings(builder); builder.write(ctrlCharacteristic, new byte[]{No1F1Constants.CMD_FIRMWARE_VERSION}); @@ -173,18 +174,8 @@ public class No1F1Support extends AbstractBTLEDeviceSupport { public void onSetTime() { try { TransactionBuilder builder = performInitialized("setTime"); - Calendar c = GregorianCalendar.getInstance(); - byte[] datetimeBytes = new byte[]{ - No1F1Constants.CMD_DATETIME, - (byte) ((c.get(Calendar.YEAR) / 256) & 0xff), - (byte) (c.get(Calendar.YEAR) % 256), - (byte) (c.get(Calendar.MONTH) + 1), - (byte) c.get(Calendar.DAY_OF_MONTH), - (byte) c.get(Calendar.HOUR_OF_DAY), - (byte) c.get(Calendar.MINUTE), - (byte) c.get(Calendar.SECOND) - }; - builder.write(ctrlCharacteristic, datetimeBytes); + setTime(builder); + performConnected(builder.getTransaction()); } catch (IOException e) { GB.toast(getContext(), "Error setting time: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); } @@ -396,6 +387,21 @@ public class No1F1Support extends AbstractBTLEDeviceSupport { return true; } + private void setTime(TransactionBuilder transaction) { + Calendar c = GregorianCalendar.getInstance(); + byte[] datetimeBytes = new byte[]{ + No1F1Constants.CMD_DATETIME, + (byte) ((c.get(Calendar.YEAR) / 256) & 0xff), + (byte) (c.get(Calendar.YEAR) % 256), + (byte) (c.get(Calendar.MONTH) + 1), + (byte) c.get(Calendar.DAY_OF_MONTH), + (byte) c.get(Calendar.HOUR_OF_DAY), + (byte) c.get(Calendar.MINUTE), + (byte) c.get(Calendar.SECOND) + }; + transaction.write(ctrlCharacteristic, datetimeBytes); + } + /** * Set display settings (time format and measurement system) * From 88714ece4d61a1058e84c95324a8731bd97024d9 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 5 Aug 2018 15:26:12 +0200 Subject: [PATCH 076/211] Amazfit Bip: fix current weather not being displayed with latest firmware --- .../huami/amazfitbip/AmazfitBipSupport.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java index 20376e138..bf0da7393 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java @@ -34,10 +34,10 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiWeatherConditions; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService; -import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; @@ -238,7 +238,12 @@ public class AmazfitBipSupport extends HuamiSupport { buf.put((byte) 0); } - builder.write(getCharacteristic(AmazfitBipService.UUID_CHARACTERISTIC_WEATHER), buf.array()); + if (characteristicChunked != null) { + writeToChunked(builder, 1, buf.array()); + } else { + builder.write(getCharacteristic(AmazfitBipService.UUID_CHARACTERISTIC_WEATHER), buf.array()); + } + builder.queue(getQueue()); } catch (Exception ex) { LOG.error("Error sending current weather", ex); @@ -263,7 +268,13 @@ public class AmazfitBipSupport extends HuamiSupport { buf.put(aqiString.getBytes()); buf.put((byte) 0); } - builder.write(getCharacteristic(AmazfitBipService.UUID_CHARACTERISTIC_WEATHER), buf.array()); + + if (characteristicChunked != null) { + writeToChunked(builder, 1, buf.array()); + } else { + builder.write(getCharacteristic(AmazfitBipService.UUID_CHARACTERISTIC_WEATHER), buf.array()); + } + builder.queue(getQueue()); } catch (IOException ex) { LOG.error("Error sending air quality"); From 4ff04870caede5aa7963c6af745b70485bc7607c Mon Sep 17 00:00:00 2001 From: maxirnilian Date: Sun, 5 Aug 2018 18:52:44 +0200 Subject: [PATCH 077/211] Watch 9: Initial support --- app/src/main/AndroidManifest.xml | 6 + .../adapter/GBDeviceAdapterv2.java | 13 + .../watch9/Watch9CalibrationActivity.java | 107 ++++ .../devices/watch9/Watch9Constants.java | 76 +++ .../watch9/Watch9DeviceCoordinator.java | 147 +++++ .../devices/watch9/Watch9PairingActivity.java | 113 ++++ .../gadgetbridge/model/DeviceType.java | 1 + .../service/DeviceSupportFactory.java | 4 + .../devices/watch9/Watch9DeviceSupport.java | 605 ++++++++++++++++++ .../watch9/operations/InitOperation.java | 77 +++ .../gadgetbridge/util/DeviceHelper.java | 2 + .../layout/activity_watch9_calibration.xml | 124 ++++ .../res/layout/activity_watch9_pairing.xml | 33 + app/src/main/res/layout/device_itemv2.xml | 15 + app/src/main/res/values-de/strings.xml | 10 +- app/src/main/res/values/strings.xml | 11 + 16 files changed, 1343 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9CalibrationActivity.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9Constants.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9DeviceCoordinator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/watch9/Watch9PairingActivity.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/watch9/Watch9DeviceSupport.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/watch9/operations/InitOperation.java create mode 100644 app/src/main/res/layout/activity_watch9_calibration.xml create mode 100644 app/src/main/res/layout/activity_watch9_pairing.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bd42dd7d8..e9d2fc015 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -387,6 +387,12 @@ + +