diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9264f7164..25521912f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
### Changelog
-#### Version 0.40.0 (WIP)
+#### Version 0.40.1
+* Mi Band/Amazfit: Recogize changes when toggling alarm on device (immediately when connected, else when connecting)
+* Mi Band/Amazfit: Fix some bugs with stuck connection when re-connecting
+* Mi Band 4: Support higher MTU for multiple times faster firmware transfer (probably also Amazfit GTR/GTS)
+* Amazfit Cor: Fix setting language to Chinese manually
+
+#### Version 0.40.0
* Fossil Q Hybrid: Initial support
* Bangle.js: Initial support
* Reserve Alarm for Calendar feature restricted to Mi Band 1/2 and moved to per-device settings
diff --git a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java
index 13868d787..f9a0a697e 100644
--- a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java
+++ b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java
@@ -15,8 +15,6 @@
*/
package nodomain.freeyourgadget.gadgetbridge.daogen;
-import java.util.Date;
-
import de.greenrobot.daogenerator.DaoGenerator;
import de.greenrobot.daogenerator.Entity;
import de.greenrobot.daogenerator.Index;
@@ -45,7 +43,7 @@ public class GBDaoGenerator {
public static void main(String[] args) throws Exception {
- Schema schema = new Schema(21, MAIN_PACKAGE + ".entities");
+ Schema schema = new Schema(22, MAIN_PACKAGE + ".entities");
Entity userAttributes = addUserAttributes(schema);
Entity user = addUserInfo(schema, userAttributes);
@@ -378,6 +376,7 @@ public class GBDaoGenerator {
);
alarm.addIntProperty("hour").notNull();
alarm.addIntProperty("minute").notNull();
+ alarm.addBooleanProperty("unused").notNull();
alarm.addToOne(user, userId);
alarm.addToOne(device, deviceId);
}
diff --git a/README.md b/README.md
index da40517f6..972d1338a 100644
--- a/README.md
+++ b/README.md
@@ -80,6 +80,7 @@ Please see [FEATURES.md](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/ma
* Johannes Schmitt (BFH-16)
* Lukas Schwichtenberg (Makibes HR3)
* Daniel Dakhno (Fossil Q Hybrid)
+* Gordon Williams (Bangle.js)
## Contribute
diff --git a/app/build.gradle b/app/build.gradle
index 893e36c2a..67f484af5 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.40.0"
- versionCode 163
+ versionName "0.40.1"
+ versionCode 164
vectorDrawables.useSupportLibrary = true
}
buildTypes {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java
index 6293cb03c..fd427af72 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java
@@ -17,18 +17,23 @@
along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.activities;
+import android.content.BroadcastReceiver;
+import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Bundle;
import android.view.MenuItem;
+import androidx.annotation.NonNull;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.GBAlarmListAdapter;
@@ -40,6 +45,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
+import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
@@ -59,6 +65,10 @@ public class ConfigureAlarms extends AbstractGBActivity {
setContentView(R.layout.activity_configure_alarms);
+ IntentFilter filterLocal = new IntentFilter();
+ filterLocal.addAction(DeviceService.ACTION_SAVE_ALARMS);
+ LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
+
gbDevice = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
mGBAlarmListAdapter = new GBAlarmListAdapter(this);
@@ -136,7 +146,7 @@ public class ConfigureAlarms extends AbstractGBActivity {
}
private Alarm createDefaultAlarm(@NonNull Device device, @NonNull User user, int position) {
- return new Alarm(device.getId(), user.getId(), position, false, false,0, 6, 30);
+ return new Alarm(device.getId(), user.getId(), position, false, false, 0, 6, 30, false);
}
@Override
@@ -165,4 +175,25 @@ public class ConfigureAlarms extends AbstractGBActivity {
private void sendAlarmsToDevice() {
GBApplication.deviceService().onSetAlarms(mGBAlarmListAdapter.getAlarmList());
}
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ switch (action) {
+ case DeviceService.ACTION_SAVE_ALARMS: {
+ updateAlarmsFromDB();
+ break;
+ }
+ }
+ }
+ };
+
+ @Override
+ protected void onDestroy() {
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
+ super.onDestroy();
+ }
+
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java
index 07500a8b4..7725d1bf2 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java
@@ -27,12 +27,13 @@ import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
-import java.util.ArrayList;
-import java.util.List;
-
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.ArrayList;
+import java.util.List;
+
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
@@ -71,7 +72,7 @@ public class GBAlarmListAdapter extends RecyclerView.Adapter. */
+package nodomain.freeyourgadget.gadgetbridge.database.schema;
+
+import android.database.sqlite.SQLiteDatabase;
+
+import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
+import nodomain.freeyourgadget.gadgetbridge.database.DBUpdateScript;
+import nodomain.freeyourgadget.gadgetbridge.entities.AlarmDao;
+import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySampleDao;
+
+public class GadgetbridgeUpdate_22 implements DBUpdateScript {
+ @Override
+ public void upgradeSchema(SQLiteDatabase db) {
+ if (!DBHelper.existsColumn(AlarmDao.TABLENAME, AlarmDao.Properties.Unused.columnName, db)) {
+ String ADD_COLUMN_UNUSED = "ALTER TABLE " + AlarmDao.TABLENAME + " ADD COLUMN "
+ + AlarmDao.Properties.Unused.columnName + " INTEGER NOT NULL DEFAULT 0;";
+ db.execSQL(ADD_COLUMN_UNUSED);
+ }
+ }
+
+ @Override
+ public void downgradeSchema(SQLiteDatabase db) {
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSConstants.java
index cb1c47165..dfcb8470b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSConstants.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSConstants.java
@@ -1,3 +1,19 @@
+/* Copyright (C) 2019 Gordon Williams
+
+ 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.banglejs;
import java.util.UUID;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java
index b6bcd466c..b6a29e229 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java
@@ -1,3 +1,20 @@
+/* Copyright (C) 2016-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniele
+ Gobbetti, Gordon Williams, José Rebelo
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.devices.banglejs;
import android.annotation.TargetApi;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java
index b18466afc..d40e35120 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java
@@ -59,6 +59,7 @@ public class HuamiService {
public static final int ALERT_LEVEL_PHONE_CALL = 2;
public static final int ALERT_LEVEL_VIBRATE_ONLY = 3;
+
// set metric distance
// set 12 hour time mode
@@ -158,6 +159,9 @@ public class HuamiService {
public static final byte[] COMMAND_ENABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x01, 0, 0, 0, 0};
public static final byte[] COMMAND_DISABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x00, 0, 0, 0, 0};
+ public static final byte[] COMMAND_REQUEST_ALARMS = new byte[]{0x0d};
+ public static final byte[] COMMAND_REQUEST_GPS_VERSION = new byte[]{0x0e};
+
// The third byte controls the threshold, in minutes
// The last 8 bytes represent 2 separate time intervals for the inactivity warnings
// If there is no do not disturb interval, the last 4 bytes (the second interval) are 0
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 f6e4b1e82..8debbcdce 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
@@ -26,9 +26,6 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.EN
public class AmazfitBipService {
public static final UUID UUID_CHARACTERISTIC_WEATHER = UUID.fromString("0000000e-0000-3512-2118-0009af100700");
- // goes to UUID_CHARACTERISTIC_3_CONFIGURATION, TODO: validate this for Mi Band 2, it maybe triggers more than only GPS version...
- public static final byte[] COMMAND_REQUEST_GPS_VERSION = new byte[]{0x0e};
-
public static final byte COMMAND_ACTIVITY_DATA_TYPE_DEBUGLOGS = 0x07;
public static final byte[] COMMAND_SET_LANGUAGE_SIMPLIFIED_CHINESE = new byte[]{ENDPOINT_DISPLAY, 0x13, 0x00, 0x00};
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Alarm.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Alarm.java
index 5a4c22d3d..5805d3072 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Alarm.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Alarm.java
@@ -37,6 +37,8 @@ public interface Alarm extends Serializable {
boolean getEnabled();
+ boolean getUnused();
+
boolean getSmartWakeup();
int getRepetition();
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 fb48ccf8b..d0e7c0241 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java
@@ -53,6 +53,7 @@ public interface DeviceService extends EventHandler {
String ACTION_FIND_DEVICE = PREFIX + ".action.find_device";
String ACTION_SET_CONSTANT_VIBRATION = PREFIX + ".action.set_constant_vibration";
String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms";
+ String ACTION_SAVE_ALARMS = PREFIX + ".action.save_alarms";
String ACTION_ENABLE_REALTIME_STEPS = PREFIX + ".action.enable_realtime_steps";
String ACTION_REALTIME_SAMPLES = PREFIX + ".action.realtime_samples";
String ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT = PREFIX + ".action.realtime_hr_measurement";
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 f02b327bc..9625f0db8 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java
@@ -1,8 +1,8 @@
/* Copyright (C) 2015-2019 Andreas Böhler, Andreas Shimokawa, Carsten
- Pfeiffer, Cre3per, Daniel Dakhno, Daniele Gobbetti, Jean-François Greffier,
- João Paulo Barraca, José Rebelo, Kranz, ladbsoft, Manuel Ruß, maxirnilian,
- protomors, Quallenauge, Sami Alaoui, Sebastian Kranz, Sophanimus, tiparega,
- Vadim Kaushan
+ Pfeiffer, Cre3per, Daniel Dakhno, Daniele Gobbetti, Gordon Williams,
+ Jean-François Greffier, João Paulo Barraca, José Rebelo, Kranz, ladbsoft,
+ Manuel Ruß, maxirnilian, protomors, Quallenauge, Sami Alaoui, Sebastian
+ Kranz, Sophanimus, tiparega, Vadim Kaushan
This file is part of Gadgetbridge.
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 5066df6fc..3697e9d5a 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java
@@ -287,7 +287,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
return START_NOT_STICKY;
}
- if (mDeviceSupport == null || (!isInitialized() && !mDeviceSupport.useAutoConnect())) {
+ if (mDeviceSupport == null || (!isInitialized() && !action.equals(ACTION_DISCONNECT) && (!mDeviceSupport.useAutoConnect() || isConnected()))) {
// trying to send notification without valid Bluetooth connection
if (mGBDevice != null) {
// at least send back the current device state
@@ -814,6 +814,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
}
if (mAutoConnectInvervalReceiver != null) {
unregisterReceiver(mAutoConnectInvervalReceiver);
+ mAutoConnectInvervalReceiver.destroy();
mAutoConnectInvervalReceiver = null;
}
}
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 d0519fdcd..b30bf3db8 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java
@@ -1,8 +1,8 @@
/* Copyright (C) 2015-2019 0nse, Andreas Böhler, Andreas Shimokawa, Carsten
- Pfeiffer, Cre3per, criogenic, Daniel Dakhno, Daniele Gobbetti, Jean-François
- Greffier, João Paulo Barraca, José Rebelo, Kranz, ladbsoft, Manuel Ruß,
- maxirnilian, protomors, Quallenauge, Sami Alaoui, Sergey Trofimov, Sophanimus,
- tiparega, Vadim Kaushan
+ Pfeiffer, Cre3per, criogenic, Daniel Dakhno, Daniele Gobbetti, Gordon Williams,
+ Jean-François Greffier, João Paulo Barraca, José Rebelo, Kranz, ladbsoft,
+ Manuel Ruß, maxirnilian, protomors, Quallenauge, Sami Alaoui, Sergey Trofimov,
+ Sophanimus, tiparega, Vadim Kaushan
This file is part of Gadgetbridge.
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java
index 1546b8302..36b6d2a80 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BtLEQueue.java
@@ -265,9 +265,6 @@ public final class BtLEQueue {
mGbDevice.setState(newState);
mGbDevice.sendDeviceUpdateIntent(mContext);
- if (mConnectionLatch != null && newState == State.CONNECTED) {
- mConnectionLatch.countDown();
- }
}
public void disconnect() {
@@ -516,6 +513,9 @@ public final class BtLEQueue {
// only propagate the successful event
getCallbackToUse().onServicesDiscovered(gatt);
}
+ if (mConnectionLatch != null) {
+ mConnectionLatch.countDown();
+ }
} else {
LOG.warn("onServicesDiscovered received: " + status);
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCallback.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCallback.java
index 16ec0f4f8..a15f24076 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCallback.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCallback.java
@@ -1,3 +1,19 @@
+/* Copyright (C) 2015-2019 Andreas Shimokawa, Carsten Pfeiffer, Daniel Dakhno
+
+ 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 . */
/*
* Copyright (C) 2013 The Android Open Source Project
*
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java
index 638ffae11..ccb2ce3ae 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java
@@ -1,3 +1,19 @@
+/* Copyright (C) 2019 Andreas Shimokawa, Gordon Williams
+
+ 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.service.devices.banglejs;
import android.bluetooth.BluetoothGatt;
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 415d45ff9..291cb9367 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,5 +30,6 @@ 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 MTU_REQUEST = 0x16;
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 ef827101e..b664d11bc 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
@@ -143,6 +143,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ge
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.getNotificationPrefStringValue;
import static nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL;
+
public class HuamiSupport extends AbstractBTLEDeviceSupport {
// We introduce key press counter for notification purposes
@@ -164,7 +165,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
};
private BluetoothGattCharacteristic characteristicHRControlPoint;
- protected BluetoothGattCharacteristic characteristicChunked;
+ private BluetoothGattCharacteristic characteristicChunked;
private boolean needsAuth;
private volatile boolean telephoneRinging;
@@ -181,6 +182,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
private MusicSpec bufferMusicSpec = null;
private MusicStateSpec bufferMusicStateSpec = null;
private boolean heartRateNotifyEnabled;
+ private int mMTU = 23;
public HuamiSupport() {
this(LOG);
@@ -293,15 +295,16 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
builder.notify(getCharacteristic(GattService.UUID_SERVICE_CURRENT_TIME), enable);
// Notify CHARACTERISTIC9 to receive random auth code
builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUTH), enable);
+
return this;
}
public HuamiSupport enableFurtherNotifications(TransactionBuilder builder, boolean 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);
builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUDIO), enable);
builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_AUDIODATA), enable);
+ builder.notify(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_DEVICEEVENT), enable);
return this;
}
@@ -1150,6 +1153,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
break;
case HuamiDeviceEvent.ALARM_TOGGLED:
LOG.info("An alarm was toggled");
+ TransactionBuilder builder = new TransactionBuilder("requestAlarms");
+ requestAlarms(builder);
+ builder.queue(getQueue());
break;
case HuamiDeviceEvent.FELL_ASLEEP:
LOG.info("Fell asleep");
@@ -1212,11 +1218,34 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}
evaluateGBDeviceEvent(deviceEventMusicControl);
break;
+ case HuamiDeviceEvent.MTU_REQUEST:
+ int mtu = (value[2] & 0xff) << 8 | value[1] & 0xff;
+ LOG.info("device announced MTU of " + mtu);
+ mMTU = mtu;
+ /*
+ * not really sure if this would make sense, is this event already a proof of a successful MTU
+ * negotiation initiated by the Huami device, and acknowledged by the phone? do we really have to
+ * requestMTU() from our side after receiving this?
+ * /
+ if (mMTU != mtu) {
+ requestMTU(mtu);
+ }
+ */
+ break;
default:
LOG.warn("unhandled event " + value[0]);
}
}
+ private void requestMTU(int mtu) {
+ if (GBApplication.isRunningLollipopOrLater()) {
+ new TransactionBuilder("requestMtu")
+ .requestMtu(mtu)
+ .queue(getQueue());
+ mMTU = mtu;
+ }
+ }
+
private void acknowledgeFindPhone() {
try {
TransactionBuilder builder = performInitialized("acknowledge find phone");
@@ -1300,6 +1329,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
} else if (HuamiService.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) {
handleRealtimeSteps(characteristic.getValue());
return true;
+ } else if (HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION.equals(characteristicUUID)) {
+ handleConfigurationInfo(characteristic.getValue());
+ return true;
} else {
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
logMessageContent(characteristic.getValue());
@@ -1394,6 +1426,53 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}
}
+ private void handleConfigurationInfo(byte[] value) {
+ if (value == null || value.length < 4) {
+ return;
+ }
+ if (value[0] == 0x10 && value[2] == 0x01) {
+ if (value[1] == 0x0e) {
+ String gpsVersion = new String(value, 3, value.length - 3);
+ LOG.info("got gps version = " + gpsVersion);
+ gbDevice.setFirmwareVersion2(gpsVersion);
+ } else if (value[1] == 0x0d) {
+ LOG.info("got alarms from watch");
+ decodeAndUpdateAlarmStatus(value);
+ } else {
+ LOG.warn("got configuration info we do not handle yet " + GB.hexdump(value, 3, -1));
+ }
+ } else {
+ LOG.warn("error received from configuration request " + GB.hexdump(value, 0, -1));
+ }
+ }
+
+ private void decodeAndUpdateAlarmStatus(byte[] response) {
+ List alarms = DBHelper.getAlarms(gbDevice);
+ boolean[] alarmsInUse = new boolean[10];
+ boolean[] alarmsEnabled = new boolean[10];
+ int nr_alarms = response[8];
+ for (int i = 0; i < nr_alarms; i++) {
+ byte alarm_data = response[9 + i];
+ int index = alarm_data & 0xf;
+ alarmsInUse[index] = true;
+ boolean enabled = (alarm_data & 0x10) == 0x10;
+ alarmsEnabled[index] = enabled;
+ LOG.info("alarm " + index + " is enabled:" + enabled);
+ }
+ for (nodomain.freeyourgadget.gadgetbridge.entities.Alarm alarm : alarms) {
+ boolean enabled = alarmsEnabled[alarm.getPosition()];
+ boolean unused = !alarmsInUse[alarm.getPosition()];
+ if (alarm.getEnabled() != enabled || alarm.getUnused() != unused) {
+ LOG.info("updating alarm index " + alarm.getPosition() + " unused=" + unused + ", enabled=" + enabled);
+ alarm.setEnabled(enabled);
+ alarm.setUnused(unused);
+ DBHelper.store(alarm);
+ Intent intent = new Intent(DeviceService.ACTION_SAVE_ALARMS);
+ LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
+ }
+ }
+ }
+
private void enableRealtimeSamplesTimer(boolean enable) {
if (enable) {
getRealtimeSamplesSupport().start();
@@ -1487,13 +1566,17 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}
int base = 0;
- if (alarm.getEnabled()) {
+ int daysMask = 0;
+ if (alarm.getEnabled() && !alarm.getUnused()) {
base = 128;
}
- int daysMask = alarm.getRepetition();
- if (!alarm.isRepetitive()) {
- daysMask = 128;
+ if (!alarm.getUnused()) {
+ daysMask = alarm.getRepetition();
+ if (!alarm.isRepetitive()) {
+ daysMask = 128;
+ }
}
+
byte[] alarmMessage = new byte[] {
(byte) 0x2, // TODO what is this?
(byte) (base + alarm.getPosition()), // 128 is the base, alarm slot is added
@@ -2170,8 +2253,8 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
return this;
}
- protected void writeToChunked(TransactionBuilder builder, int type, byte[] data) {
- final int MAX_CHUNKLENGTH = 17;
+ private void writeToChunked(TransactionBuilder builder, int type, byte[] data) {
+ final int MAX_CHUNKLENGTH = mMTU - 6;
int remaining = data.length;
byte count = 0;
while (remaining > 0) {
@@ -2198,6 +2281,19 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}
}
+
+ protected HuamiSupport requestGPSVersion(TransactionBuilder builder) {
+ LOG.info("Requesting GPS version");
+ builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_REQUEST_GPS_VERSION);
+ return this;
+ }
+
+ private HuamiSupport requestAlarms(TransactionBuilder builder) {
+ LOG.info("Requesting alarms");
+ builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_REQUEST_ALARMS);
+ return this;
+ }
+
@Override
public String customStringFilter(String inputString) {
if (HuamiCoordinator.getUseCustomFont(gbDevice.getAddress())) {
@@ -2258,6 +2354,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
setDisconnectNotification(builder);
setExposeHRThridParty(builder);
setHeartrateMeasurementInterval(builder, getHeartRateMeasurementInterval());
+ requestAlarms(builder);
}
private int getHeartRateMeasurementInterval() {
@@ -2271,4 +2368,8 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
public UpdateFirmwareOperation createUpdateFirmwareOperation(Uri uri) {
return new UpdateFirmwareOperation(uri, this);
}
+
+ public int getMTU() {
+ return mMTU;
+ }
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java
index e5936c52f..699f4feef 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipFirmwareInfo.java
@@ -159,9 +159,11 @@ public class AmazfitBipFirmwareInfo extends HuamiFirmwareInfo {
// BipOS FW
crcToVersion.put(28373, "1.1.2.05 (BipOS 0.5)");
+ crcToVersion.put(62977, "1.1.2.05 (BipOS 0.5.1)");
// BipOS RES
crcToVersion.put(16303, "1.1.2.05 (BipOS 0.5)");
+ crcToVersion.put(61135, "1.1.2.05 (BipOS 0.5.1)");
}
public AmazfitBipFirmwareInfo(byte[] bytes) {
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 1e1b81d15..99861ce8e 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
@@ -17,11 +17,7 @@
along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip;
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
import android.net.Uri;
import org.slf4j.Logger;
@@ -29,7 +25,6 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Set;
-import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
@@ -37,21 +32,14 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipFWHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
-import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
-import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
-import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
-import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile;
-import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert;
-import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiIcon;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
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.HuamiFetchDebugLogsOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy;
-import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
public class AmazfitBipSupport extends HuamiSupport {
@@ -162,39 +150,6 @@ public class AmazfitBipSupport extends HuamiSupport {
}
}
- @Override
- public boolean onCharacteristicChanged(BluetoothGatt gatt,
- BluetoothGattCharacteristic characteristic) {
- boolean handled = super.onCharacteristicChanged(gatt, characteristic);
- if (!handled) {
- UUID characteristicUUID = characteristic.getUuid();
- if (HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION.equals(characteristicUUID)) {
- return handleConfigurationInfo(characteristic.getValue());
- }
- }
- return false;
- }
-
- private boolean handleConfigurationInfo(byte[] value) {
- if (value == null || value.length < 4) {
- return false;
- }
- if (value[0] == 0x10 && value[1] == 0x0e && value[2] == 0x01) {
- String gpsVersion = new String(value, 3, value.length - 3);
- LOG.info("got gps version = " + gpsVersion);
- gbDevice.setFirmwareVersion2(gpsVersion);
- return true;
- }
- return false;
- }
-
- // this probably does more than only getting the GPS version...
- private AmazfitBipSupport requestGPSVersion(TransactionBuilder builder) {
- LOG.info("Requesting GPS version");
- builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), AmazfitBipService.COMMAND_REQUEST_GPS_VERSION);
- return this;
- }
-
@Override
public void phase2Initialize(TransactionBuilder builder) {
super.phase2Initialize(builder);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorFirmwareInfo.java
index f681678c6..0a14d1bbc 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorFirmwareInfo.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitcor/AmazfitCorFirmwareInfo.java
@@ -44,6 +44,7 @@ public class AmazfitCorFirmwareInfo extends HuamiFirmwareInfo {
crcToVersion.put(51575, "1.0.7.88");
crcToVersion.put(6346, "1.2.5.00");
crcToVersion.put(24277, "1.2.7.20");
+ crcToVersion.put(10078, "1.2.7.32");
// resources
crcToVersion.put(46341, "RES 1.0.5.60");
@@ -53,6 +54,7 @@ public class AmazfitCorFirmwareInfo extends HuamiFirmwareInfo {
crcToVersion.put(31263, "RES 1.0.7.77-91");
crcToVersion.put(20920, "RES 1.2.5.00-69");
crcToVersion.put(25397, "RES 1.2.7.20");
+ crcToVersion.put(54167, "RES 1.2.7.32");
// font
crcToVersion.put(61054, "8");
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 4102c7fbd..32612aea2 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
@@ -61,6 +61,7 @@ public class MiBand3FirmwareInfo extends HuamiFirmwareInfo {
crcToVersion.put(40949, "2.3.0.28");
crcToVersion.put(59213, "2.4.0.12");
crcToVersion.put(10810, "2.4.0.20");
+ crcToVersion.put(18271, "2.4.0.32");
// firmware (Mi Band 3 NFC)
crcToVersion.put(46724, "1.7.0.4");
@@ -74,7 +75,7 @@ public class MiBand3FirmwareInfo extends HuamiFirmwareInfo {
crcToVersion.put(1815, "2.0.0.4");
crcToVersion.put(7225, "2.2.0.12-2.3.0.6");
crcToVersion.put(52754, "2.3.0.28");
- crcToVersion.put(17930, "2.4.0.12-20");
+ crcToVersion.put(17930, "2.4.0.12-32");
// font
crcToVersion.put(19775, "1");
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4FirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4FirmwareInfo.java
index 0a3dd9022..238630890 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4FirmwareInfo.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband4/MiBand4FirmwareInfo.java
@@ -41,12 +41,14 @@ public class MiBand4FirmwareInfo extends HuamiFirmwareInfo {
crcToVersion.put(43437, "1.0.5.66");
crcToVersion.put(31632, "1.0.6.00");
crcToVersion.put(6856, "1.0.7.14");
+ crcToVersion.put(50145, "1.0.7.60");
// resources
crcToVersion.put(27412, "1.0.5.22");
crcToVersion.put(5466, "1.0.5.66");
crcToVersion.put(20047, "1.0.6.00");
crcToVersion.put(62914, "1.0.7.14");
+ crcToVersion.put(17303, "1.0.7.60");
// font
crcToVersion.put(31978, "1");
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 974b72128..2e1d12768 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
@@ -139,8 +139,8 @@ public class InitOperation extends AbstractBTLEOperation {
value[2] == HuamiService.AUTH_SUCCESS) {
TransactionBuilder builder = createTransactionBuilder("Authenticated, now initialize phase 2");
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext()));
- huamiSupport.requestDeviceInfo(builder);
huamiSupport.enableFurtherNotifications(builder, true);
+ huamiSupport.requestDeviceInfo(builder);
huamiSupport.phase2Initialize(builder);
huamiSupport.phase3Initialize(builder);
huamiSupport.setInitialized(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 07ca209cd..5b9179101 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
@@ -232,7 +232,7 @@ public class UpdateFirmwareOperation extends AbstractHuamiOperation {
private boolean sendFirmwareData(HuamiFirmwareInfo info) {
byte[] fwbytes = info.getBytes();
int len = fwbytes.length;
- final int packetLength = 20;
+ final int packetLength = getSupport().getMTU() - 3;
int packets = len / packetLength;
try {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/AutoConnectIntervalReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/AutoConnectIntervalReceiver.java
index dad443888..b8540347c 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/AutoConnectIntervalReceiver.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/receivers/AutoConnectIntervalReceiver.java
@@ -103,4 +103,8 @@ public class AutoConnectIntervalReceiver extends BroadcastReceiver {
}
}
+ public void destroy() {
+ LocalBroadcastManager.getInstance(service).unregisterReceiver(this);
+ }
+
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java
index 22b9e9e8c..47a6bc46a 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java
@@ -48,7 +48,7 @@ public class AlarmUtils {
* @return
*/
public static nodomain.freeyourgadget.gadgetbridge.model.Alarm createSingleShot(int index, boolean smartWakeup, Calendar calendar) {
- return new Alarm(-1, -1, index, true, smartWakeup, Alarm.ALARM_ONCE, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE));
+ return new Alarm(-1, -1, index, true, smartWakeup, Alarm.ALARM_ONCE, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), false);
}
/**
@@ -127,7 +127,7 @@ public class AlarmUtils {
int hour = Integer.parseInt(tokens[4]);
int minute = Integer.parseInt(tokens[5]);
- return new Alarm(device.getId(), user.getId(), index, enabled, smartWakeup, repetition, hour, minute);
+ return new Alarm(device.getId(), user.getId(), index, enabled, smartWakeup, repetition, hour, minute, false);
}
private static Comparator createComparator() {
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 ff91bdf73..4ac3037d4 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java
@@ -1,7 +1,8 @@
-/* Copyright (C) 2015-2019 0nse, Andreas Böhler, Andreas Shimokawa, Carsten
- Pfeiffer, Cre3per, Daniel Dakhno, Daniele Gobbetti, Jean-François Greffier,
- João Paulo Barraca, José Rebelo, Kranz, ladbsoft, Manuel Ruß, maxirnilian,
- protomors, Quallenauge, Sami Alaoui, Sophanimus, tiparega, Vadim Kaushan
+/* Copyright (C) 2015-2019 0nse, Andreas Böhler, Andreas Shimokawa,
+ Carsten Pfeiffer, Cre3per, Daniel Dakhno, Daniele Gobbetti, Gordon Williams,
+ Jean-François Greffier, João Paulo Barraca, José Rebelo, Kranz, ladbsoft,
+ Manuel Ruß, maxirnilian, protomors, Quallenauge, Sami Alaoui, Sophanimus,
+ tiparega, Vadim Kaushan
This file is part of Gadgetbridge.
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 4b2c92b2e..d4138695f 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -307,7 +307,7 @@
Váha v kg
Ověřování
Ověřování vyžadováno
- Spí…
+ Spí
Přidat widget
Preferovaná doba spánku v hodinách
Budík nastaven na %1$02d:%2$02d
@@ -356,7 +356,7 @@
Metrické
Imperiální
24h
- dop./odp.
+ Dop./Odp.
Budík
(%1$s)
Nalezeno!
@@ -576,7 +576,7 @@
Ok
Při západu slunce
Záznamy aktivit
- Běh na pásu
+ Běžecký pás
Mi Band 3
Q8
MyKronoz ZeTime
@@ -725,7 +725,7 @@
Využít vlastní font
Vaše zařízení má vlastní font s podporou emoji
Cesta autoexportu databáze je nastaveno na:
- AutoExport
+ Automatický export
Exportovat Databázi
Importovat Databázi
Spustit AutoExport Teď
@@ -792,4 +792,22 @@
\n
\nPOKRAČUJTE NA VLASTNÍ NEBEZPEČÍ!
nodomain.freeyourgadget.gadgetbridge.ButtonPressed
+ Fossil Q Hybrid
+ Q hybrid nastavení
+ Hodinky nejsou připojeny
+ síla vibrace:
+ Cíl v krocích
+ časový posun
+ posun dalšího časového pásma vzhledem k UTC
+ přepsat tlačítka
+ použít čítač aktivity jako čítač oznámení
+ Chcete-li aktivovat počítadlo, nastavte počet kroků na milion.
+ Tlačítka přepsána
+ Chyba při přepisování tlačítek
+ posun časového pásma podle
+ změna může trvat několik sekund…
+ posun času o
+ Zakázat nové BLE skenování
+ Tuto možnost zaškrtněte pokud Vaše zařízení nelze najít během vyhledávání
+ Bangle.js
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index ffd6bbe92..a01672a6f 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -44,7 +44,7 @@
Kalender auf Blacklist
FW/App-Installer
- Du installierst jetzt %s.
+ Du bist dabei, die %s zu installieren.
Du bist dabei, die %1$s und %2$s Firmware zu installieren, anstatt die, die sich derzeit auf deinem Mi Band befinden.
Diese Firmware wurde getestet und ist bekanntlich mit Gadgetbridge kompatibel.
Diese Firmware ist nicht getestet und ist möglicherweise nicht mit Gadgetbridge kompatibel.
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index adc4e2580..0d92f12cf 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -795,4 +795,9 @@
Klokke ikke tilkoblet
vibrasjonsstyrke:
Bangle.js
+ Fossil Q Hybrid
+ Q Hybrid-innstillinger
+ overskriv taster
+ Knapper overskrevet
+ Kunne ikke overskrive knapper
\ No newline at end of file
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 1e58a478b..57a48ce12 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -346,7 +346,7 @@
Bieganie
Pływanie
Bieżnia
- Połącz
+ Połącz…
Otwórz okno nawigacji
Zamknij okno nawigacji
Kalibracja urządzenia
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index ec1c1e8e5..da3c030ba 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -26,4 +26,19 @@
刪除並清除緩存
重新安裝
nodomain.freeyourgadget.gadgetbridge.ButtonPressed
+ Gadgetbridge
+ Gadgetbridge
+ 連接中…
+ 截取設備的屏幕截圖
+ 校正設備
+ 應用管理器
+ 緩存的應用程式
+ 已安裝的錶盤
+ 在Pebble應用商店中搜索
+ 啟動
+ 停用
+ 激活HRM
+ 停用HRM
+ 啟動系統天氣應用
+ 停用系统天气应用
\ No newline at end of file
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index a779f45fa..386325036 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -390,7 +390,7 @@
- @string/automatic
- - @string/simplified_chinese
+ - @string/simplified_chinese
- @string/traditional_chinese
- @string/english
- @string/spanish
@@ -404,7 +404,7 @@
- auto
- - zh_CH
+ - zh_CN
- zh_TW
- en_US
- es_ES
@@ -418,7 +418,7 @@
- @string/automatic
- - @string/simplified_chinese
+ - @string/simplified_chinese
- @string/traditional_chinese
- @string/english
- @string/spanish
@@ -427,7 +427,7 @@
- auto
- - zh_CH
+ - zh_CN
- zh_TW
- en_US
- es_ES
@@ -436,7 +436,7 @@
- @string/automatic
- - @string/simplified_chinese
+ - @string/simplified_chinese
- @string/traditional_chinese
- @string/english
- @string/spanish
@@ -459,7 +459,7 @@
- auto
- - zh_CH
+ - zh_CN
- zh_TW
- en_US
- es_ES
diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml
index 238225a81..354521c4e 100644
--- a/app/src/main/res/xml/changelog_master.xml
+++ b/app/src/main/res/xml/changelog_master.xml
@@ -1,5 +1,17 @@
+
+ Mi Band/Amazfit: Recogize changes when toggling alarm on device (immediately when connected, else when connecting)
+ Mi Band/Amazfit: Fix some bugs with stuck connection when re-connecting
+ Mi Band 4: Support higher MTU for multiple times faster firmware transfer (probably also Amazfit GTR/GTS)
+ Amazfit Cor: Fix setting language to Chinese manually
+
+
+ Fossil Q Hybrid: Initial support
+ Bangle.js: Initial support
+ Reserve Alarm for Calendar feature restricted to Mi Band 1/2 and moved to per-device settings
+ New icon for App Manager
+
Try to actively re-connect when a connection gets interrupted (interval grows up to 64 seconds)
Mi Band2/Amazfip Bip: Make button action settings per-device and enable for Amazfit Bip
diff --git a/fastlane/metadata/android/en-US/changelogs/163.txt b/fastlane/metadata/android/en-US/changelogs/163.txt
new file mode 100644
index 000000000..cbf180728
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/163.txt
@@ -0,0 +1,4 @@
+* Fossil Q Hybrid: Initial support
+* Bangle.js: Initial support
+* Reserve Alarm for Calendar feature restricted to Mi Band 1/2 and moved to per-device settings
+* New icon for App Manager
diff --git a/fastlane/metadata/android/en-US/changelogs/164.txt b/fastlane/metadata/android/en-US/changelogs/164.txt
new file mode 100644
index 000000000..5055314aa
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/164.txt
@@ -0,0 +1,4 @@
+* Mi Band/Amazfit: Recogize changes when toggling alarm on device (immediately when connected, else when connecting)
+* Mi Band/Amazfit: Fix some bugs with stuck connection when re-connecting
+* Mi Band 4: Support higher MTU for multiple times faster firmware transfer (probably also Amazfit GTR/GTS)
+* Amazfit Cor: Fix setting language to Chinese manually