mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-04 01:09:47 +01:00
Adding Mi Band 5 initial support (#1930)
Merge branch 'master' into master Merge branch 'master' into master Added available languages for Mi Band 5. This one's for fixing the step counter but the daily count is always a little bit different compared to what's shown on the smartband. Extending Mi Band 5 support! Every display item can be showed on the smartband now. Cleanup FW related test code FW related test code FW related test code FW related test code Adding Mi Band 5 test support Co-authored-by: cristian <c.alfano@outlook.it> Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/1930
This commit is contained in:
parent
e639744334
commit
d3a51a1078
@ -873,6 +873,9 @@ public class GBApplication extends Application {
|
|||||||
case MIBAND4:
|
case MIBAND4:
|
||||||
newWearside = prefs.getString("mi_wearside", "left");
|
newWearside = prefs.getString("mi_wearside", "left");
|
||||||
break;
|
break;
|
||||||
|
case MIBAND5:
|
||||||
|
newWearside = prefs.getString("mi_wearside", "left");
|
||||||
|
break;
|
||||||
case HPLUS:
|
case HPLUS:
|
||||||
newWearside = prefs.getString("hplus_wrist", "left");
|
newWearside = prefs.getString("hplus_wrist", "left");
|
||||||
newTimeformat = prefs.getString("hplus_timeformat", "24h");
|
newTimeformat = prefs.getString("hplus_timeformat", "24h");
|
||||||
|
@ -49,6 +49,7 @@ public class HuamiConst {
|
|||||||
public static final String MI_BAND3_NAME = "Mi Band 3";
|
public static final String MI_BAND3_NAME = "Mi Band 3";
|
||||||
public static final String MI_BAND3_NAME_2 = "Xiaomi Band 3";
|
public static final String MI_BAND3_NAME_2 = "Xiaomi Band 3";
|
||||||
public static final String MI_BAND4_NAME = "Mi Smart Band 4";
|
public static final String MI_BAND4_NAME = "Mi Smart Band 4";
|
||||||
|
public static final String MI_BAND5_NAME = "Mi Smart Band 5";
|
||||||
|
|
||||||
public static final String PREF_ACTIVATE_DISPLAY_ON_LIFT = "activate_display_on_lift_wrist";
|
public static final String PREF_ACTIVATE_DISPLAY_ON_LIFT = "activate_display_on_lift_wrist";
|
||||||
public static final String PREF_DISPLAY_ON_LIFT_START = "display_on_lift_start";
|
public static final String PREF_DISPLAY_ON_LIFT_START = "display_on_lift_start";
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||||
|
Gobbetti, HardLight, 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 <http://www.gnu.org/licenses/>. */
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.devices.huami.miband5;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
|
public class MiBand5Coordinator extends HuamiCoordinator {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(MiBand5Coordinator.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeviceType getDeviceType() {
|
||||||
|
return DeviceType.MIBAND5;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public DeviceType getSupportedType(GBDeviceCandidate candidate) {
|
||||||
|
try {
|
||||||
|
BluetoothDevice device = candidate.getDevice();
|
||||||
|
String name = device.getName();
|
||||||
|
if (name != null && name.equalsIgnoreCase(HuamiConst.MI_BAND5_NAME)) {
|
||||||
|
return DeviceType.MIBAND5;
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LOG.error("unable to check device support", ex);
|
||||||
|
}
|
||||||
|
return DeviceType.UNKNOWN;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InstallHandler findInstallHandler(Uri uri, Context context) {
|
||||||
|
MiBand5FWInstallHandler handler = new MiBand5FWInstallHandler(uri, context);
|
||||||
|
return handler.isValid() ? handler : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsHeartRateMeasurement(GBDevice device) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsWeather() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsActivityTracks() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsMusicInfo() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
|
||||||
|
return new int[]{
|
||||||
|
R.xml.devicesettings_miband5,
|
||||||
|
R.xml.devicesettings_wearlocation,
|
||||||
|
R.xml.devicesettings_custom_emoji_font,
|
||||||
|
R.xml.devicesettings_timeformat,
|
||||||
|
R.xml.devicesettings_dateformat,
|
||||||
|
R.xml.devicesettings_nightmode,
|
||||||
|
R.xml.devicesettings_liftwrist_display,
|
||||||
|
R.xml.devicesettings_swipeunlock,
|
||||||
|
R.xml.devicesettings_sync_calendar,
|
||||||
|
R.xml.devicesettings_expose_hr_thirdparty,
|
||||||
|
R.xml.devicesettings_pairingkey,
|
||||||
|
R.xml.devicesettings_high_mtu
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBondingStyle() {
|
||||||
|
return BONDING_STYLE_REQUIRE_KEY;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/* Copyright (C) 2017-2020 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 <http://www.gnu.org/licenses/>. */
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.devices.huami.miband5;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband5.MiBand5FirmwareInfo;
|
||||||
|
|
||||||
|
public class MiBand5FWHelper extends HuamiFWHelper {
|
||||||
|
|
||||||
|
public MiBand5FWHelper(Uri uri, Context context) throws IOException {
|
||||||
|
super(uri, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void determineFirmwareInfo(byte[] wholeFirmwareBytes) {
|
||||||
|
firmwareInfo = new MiBand5FirmwareInfo(wholeFirmwareBytes);
|
||||||
|
if (!firmwareInfo.isHeaderValid()) {
|
||||||
|
throw new IllegalArgumentException("Not a Mi Band 5 firmware");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/* Copyright (C) 2015-2020 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 <http://www.gnu.org/licenses/>. */
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.devices.huami.miband5;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband5.MiBand5FWHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
|
class MiBand5FWInstallHandler extends AbstractMiBandFWInstallHandler {
|
||||||
|
MiBand5FWInstallHandler(Uri uri, Context context) {
|
||||||
|
super(uri, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getFwUpgradeNotice() {
|
||||||
|
return mContext.getString(R.string.fw_upgrade_notice_miband5, helper.getHumanFirmwareVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AbstractMiBandFWHelper createHelper(Uri uri, Context context) throws IOException {
|
||||||
|
return new MiBand5FWHelper(uri, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isSupportedDeviceType(GBDevice device) {
|
||||||
|
return device.getType() == DeviceType.MIBAND5;
|
||||||
|
}
|
||||||
|
}
|
@ -46,6 +46,7 @@ public enum DeviceType {
|
|||||||
AMAZFITBIPS(20, R.drawable.ic_device_amazfit_bip, R.drawable.ic_device_amazfit_bip_disabled, R.string.devicetype_amazfit_bips),
|
AMAZFITBIPS(20, R.drawable.ic_device_amazfit_bip, R.drawable.ic_device_amazfit_bip_disabled, R.string.devicetype_amazfit_bips),
|
||||||
AMAZFITGTR_LITE(21, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_amazfit_gtr),
|
AMAZFITGTR_LITE(21, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_amazfit_gtr),
|
||||||
AMAZFITTREX(22, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_amazfit_trex),
|
AMAZFITTREX(22, R.drawable.ic_device_zetime, R.drawable.ic_device_zetime_disabled, R.string.devicetype_amazfit_trex),
|
||||||
|
MIBAND5(23, R.drawable.ic_device_miband2, R.drawable.ic_device_miband2_disabled, R.string.devicetype_miband5),
|
||||||
LIVEVIEW(30, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_liveview),
|
LIVEVIEW(30, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_liveview),
|
||||||
HPLUS(40, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_hplus),
|
HPLUS(40, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_hplus),
|
||||||
MAKIBESF68(41, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_makibes_f68),
|
MAKIBESF68(41, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_makibes_f68),
|
||||||
|
@ -46,6 +46,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitcor2.Am
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitgts.AmazfitGTSSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitgts.AmazfitGTSSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband3.MiBand3Support;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband3.MiBand3Support;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband4.MiBand4Support;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband4.MiBand4Support;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband5.MiBand5Support;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.id115.ID115Support;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.id115.ID115Support;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.itag.ITagSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.itag.ITagSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.BFH16DeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.jyou.BFH16DeviceSupport;
|
||||||
@ -146,6 +147,9 @@ public class DeviceSupportFactory {
|
|||||||
case MIBAND4:
|
case MIBAND4:
|
||||||
deviceSupport = new ServiceDeviceSupport(new MiBand4Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
deviceSupport = new ServiceDeviceSupport(new MiBand4Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||||
break;
|
break;
|
||||||
|
case MIBAND5:
|
||||||
|
deviceSupport = new ServiceDeviceSupport(new MiBand5Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||||
|
break;
|
||||||
case AMAZFITBIP:
|
case AMAZFITBIP:
|
||||||
deviceSupport = new ServiceDeviceSupport(new AmazfitBipSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
deviceSupport = new ServiceDeviceSupport(new AmazfitBipSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||||
break;
|
break;
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
/* Copyright (C) 2017-2020 Andreas Shimokawa, Daniele Gobbetti
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>. */
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband5;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareInfo;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
||||||
|
|
||||||
|
public class MiBand5FirmwareInfo extends HuamiFirmwareInfo {
|
||||||
|
|
||||||
|
public static final byte[] FW_HEADER = new byte[]{
|
||||||
|
0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x9c, (byte) 0xe3, 0x7d, 0x5c, 0x00, 0x04
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final int FW_HEADER_OFFSET = 16;
|
||||||
|
|
||||||
|
private static Map<Integer, String> crcToVersion = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
// firmware
|
||||||
|
crcToVersion.put(29062, "1.0.0.76");
|
||||||
|
crcToVersion.put(26302, "1.0.1.16");
|
||||||
|
|
||||||
|
// resources
|
||||||
|
crcToVersion.put(8009, "1.0.0.76");
|
||||||
|
crcToVersion.put(47040, "1.0.1.16");
|
||||||
|
|
||||||
|
// font
|
||||||
|
crcToVersion.put(31978, "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
public MiBand5FirmwareInfo(byte[] bytes) {
|
||||||
|
super(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HuamiFirmwareType determineFirmwareType(byte[] bytes) {
|
||||||
|
if (ArrayUtils.equals(bytes, RES_HEADER, COMPRESSED_RES_HEADER_OFFSET) || ArrayUtils.equals(bytes, NEWRES_HEADER, COMPRESSED_RES_HEADER_OFFSET_NEW) || ArrayUtils.equals(bytes, NEWRES_HEADER, COMPRESSED_RES_HEADER_OFFSET)) {
|
||||||
|
return HuamiFirmwareType.RES_COMPRESSED;
|
||||||
|
}
|
||||||
|
if (ArrayUtils.equals(bytes, FW_HEADER, FW_HEADER_OFFSET)) {
|
||||||
|
if (searchString32BitAligned(bytes, "Mi Smart Band 5")) {
|
||||||
|
return HuamiFirmwareType.FIRMWARE;
|
||||||
|
}
|
||||||
|
return HuamiFirmwareType.INVALID;
|
||||||
|
}
|
||||||
|
if (ArrayUtils.startsWith(bytes, WATCHFACE_HEADER)) {
|
||||||
|
return HuamiFirmwareType.WATCHFACE;
|
||||||
|
}
|
||||||
|
if (ArrayUtils.startsWith(bytes, NEWFT_HEADER)) {
|
||||||
|
if (bytes[10] == 0x03 || bytes[10] == 0x06) {
|
||||||
|
return HuamiFirmwareType.FONT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// somebody might have unpacked the compressed res
|
||||||
|
if (ArrayUtils.startsWith(bytes, RES_HEADER)) {
|
||||||
|
return HuamiFirmwareType.RES;
|
||||||
|
}
|
||||||
|
return HuamiFirmwareType.INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGenerallyCompatibleWith(GBDevice device) {
|
||||||
|
return isHeaderValid() && device.getType() == DeviceType.MIBAND5;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Map<Integer, String> getCrcMap() {
|
||||||
|
return crcToVersion;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
/* Copyright (C) 2017-2020 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 <http://www.gnu.org/licenses/>. */
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband5;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband5.MiBand5FWHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband4.MiBand4Support;
|
||||||
|
|
||||||
|
public class MiBand5Support extends MiBand4Support {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(MiBand5Support.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MiBand5Support setDisplayItems(TransactionBuilder builder) {
|
||||||
|
if (gbDevice.getFirmwareVersion() == null) {
|
||||||
|
LOG.warn("Device not initialized yet, won't set menu items");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress());
|
||||||
|
Set<String> pages = prefs.getStringSet(HuamiConst.PREF_DISPLAY_ITEMS, new HashSet<>(Arrays.asList(getContext().getResources().getStringArray(R.array.pref_miband5_display_items_default))));
|
||||||
|
LOG.info("Setting display items to " + (pages == null ? "none" : pages));
|
||||||
|
byte[] command = new byte[]{
|
||||||
|
0x1E,
|
||||||
|
0x00, 0x00, (byte) 0xFF, 0x12, // Display clock?
|
||||||
|
0x01, 0x00, (byte) 0xFF, 0x01, // Status
|
||||||
|
0x02, 0x00, (byte) 0xFF, 0x19, // PAI
|
||||||
|
0x03, 0x00, (byte) 0xFF, 0x02, // HR
|
||||||
|
0x04, 0x00, (byte) 0xFF, 0x06, // Notifications
|
||||||
|
0x05, 0x00, (byte) 0xFF, 0x33, // Breathing
|
||||||
|
0x06, 0x00, (byte) 0xFF, 0x15, // Events
|
||||||
|
0x07, 0x00, (byte) 0xFF, 0x04, // Weather
|
||||||
|
0x08, 0x00, (byte) 0xFF, 0x03, // Workout
|
||||||
|
0x09, 0x00, (byte) 0xFF, 0x07, // More
|
||||||
|
0x0A, 0x00, (byte) 0xFF, 0x1c, // Stress
|
||||||
|
0x0B, 0x00, (byte) 0xFF, 0x1d // Cycles
|
||||||
|
};
|
||||||
|
|
||||||
|
String[] keys = {"displayclock", "status", "pai", "hr", "notifications", "breathing", "eventreminder", "weather", "workout", "more", "stress", "cycles"};
|
||||||
|
byte[] ids = {0x12, 0x01, 0x19, 0x02, 0x06, 0x33, 0x15, 0x04, 0x03, 0x07, 0x1c, 0x1d};
|
||||||
|
|
||||||
|
if (pages != null) {
|
||||||
|
pages.add("displayclock");
|
||||||
|
// it seem that we first have to put all ENABLED items into the array
|
||||||
|
int pos = 1;
|
||||||
|
for (int i = 0; i < keys.length; i++) {
|
||||||
|
String key = keys[i];
|
||||||
|
byte id = ids[i];
|
||||||
|
if (pages.contains(key)) {
|
||||||
|
command[pos + 1] = 0x00;
|
||||||
|
command[pos + 3] = id;
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// And then all DISABLED ones
|
||||||
|
for (int i = 0; i < keys.length; i++) {
|
||||||
|
String key = keys[i];
|
||||||
|
byte id = ids[i];
|
||||||
|
if (!pages.contains(key)) {
|
||||||
|
command[pos + 1] = 0x01;
|
||||||
|
command[pos + 3] = id;
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeToChunked(builder, 2, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {
|
||||||
|
return new MiBand5FWHelper(uri, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getActivitySampleSize() {
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
}
|
@ -63,6 +63,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2.MiBand2Coordin
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2.MiBand2HRXCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2.MiBand2HRXCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband3.MiBand3Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband3.MiBand3Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband4.MiBand4Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband4.MiBand4Coordinator;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband5.MiBand5Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.id115.ID115Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.jyou.TeclastH30.TeclastH30Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.jyou.TeclastH30.TeclastH30Coordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.jyou.y5.Y5Coordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.jyou.y5.Y5Coordinator;
|
||||||
@ -213,6 +214,7 @@ public class DeviceHelper {
|
|||||||
|
|
||||||
private List<DeviceCoordinator> createCoordinators() {
|
private List<DeviceCoordinator> createCoordinators() {
|
||||||
List<DeviceCoordinator> result = new ArrayList<>();
|
List<DeviceCoordinator> result = new ArrayList<>();
|
||||||
|
result.add(new MiBand5Coordinator());
|
||||||
result.add(new MiScale2DeviceCoordinator());
|
result.add(new MiScale2DeviceCoordinator());
|
||||||
result.add(new AmazfitBipCoordinator());
|
result.add(new AmazfitBipCoordinator());
|
||||||
result.add(new AmazfitBipLiteCoordinator());
|
result.add(new AmazfitBipLiteCoordinator());
|
||||||
|
@ -313,6 +313,48 @@
|
|||||||
<item>@string/p_heart_rate</item>
|
<item>@string/p_heart_rate</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pref_miband5_display_items">
|
||||||
|
<item>@string/menuitem_status</item>
|
||||||
|
<item>@string/menuitem_pai</item>
|
||||||
|
<item>@string/menuitem_hr</item>
|
||||||
|
<item>@string/menuitem_notifications</item>
|
||||||
|
<item>@string/menuitem_breathing</item>
|
||||||
|
<item>@string/menuitem_eventreminder</item>
|
||||||
|
<item>@string/menuitem_weather</item>
|
||||||
|
<item>@string/menuitem_workout</item>
|
||||||
|
<item>@string/menuitem_more</item>
|
||||||
|
<item>@string/menuitem_stress</item>
|
||||||
|
<item>@string/menuitem_cycles</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pref_miband5_display_items_values">
|
||||||
|
<item>@string/p_menuitem_status</item>
|
||||||
|
<item>@string/p_menuitem_pai</item>
|
||||||
|
<item>@string/p_menuitem_hr</item>
|
||||||
|
<item>@string/p_menuitem_notifications</item>
|
||||||
|
<item>@string/p_menuitem_breathing</item>
|
||||||
|
<item>@string/p_menuitem_eventreminder</item>
|
||||||
|
<item>@string/p_menuitem_weather</item>
|
||||||
|
<item>@string/p_menuitem_workout</item>
|
||||||
|
<item>@string/p_menuitem_more</item>
|
||||||
|
<item>@string/p_menuitem_stress</item>
|
||||||
|
<item>@string/p_menuitem_cycles</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pref_miband5_display_items_default">
|
||||||
|
<item>@string/p_menuitem_status</item>
|
||||||
|
<item>@string/p_menuitem_pai</item>
|
||||||
|
<item>@string/p_menuitem_hr</item>
|
||||||
|
<item>@string/p_menuitem_notifications</item>
|
||||||
|
<item>@string/p_menuitem_breathing</item>
|
||||||
|
<item>@string/p_menuitem_eventreminder</item>
|
||||||
|
<item>@string/p_menuitem_weather</item>
|
||||||
|
<item>@string/p_menuitem_workout</item>
|
||||||
|
<item>@string/p_menuitem_more</item>
|
||||||
|
<item>@string/p_menuitem_stress</item>
|
||||||
|
<item>@string/p_menuitem_cycles</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="pref_bip_display_items">
|
<string-array name="pref_bip_display_items">
|
||||||
<item>@string/menuitem_shortcut_alipay</item>
|
<item>@string/menuitem_shortcut_alipay</item>
|
||||||
<item>@string/menuitem_shortcut_weather</item>
|
<item>@string/menuitem_shortcut_weather</item>
|
||||||
@ -632,6 +674,24 @@
|
|||||||
<item>ko_KO</item>
|
<item>ko_KO</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pref_miband5_language">
|
||||||
|
<item name="auto">@string/automatic</item>
|
||||||
|
<item name="zh_CN">@string/simplified_chinese</item>
|
||||||
|
<item name="zh_TW">@string/traditional_chinese</item>
|
||||||
|
<item name="en_US">@string/english</item>
|
||||||
|
<item name="ru_RU">@string/russian</item>
|
||||||
|
<item name="es_ES">@string/spanish</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pref_miband5_language_values">
|
||||||
|
<item>auto</item>
|
||||||
|
<item>zh_CN</item>
|
||||||
|
<item>zh_TW</item>
|
||||||
|
<item>en_US</item>
|
||||||
|
<item>ru_RU</item>
|
||||||
|
<item>es_ES</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="pref_zetime_language">
|
<string-array name="pref_zetime_language">
|
||||||
<item name="auto">@string/automatic</item>
|
<item name="auto">@string/automatic</item>
|
||||||
<item name="zh_CN">@string/simplified_chinese</item>
|
<item name="zh_CN">@string/simplified_chinese</item>
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
<string name="fw_upgrade_notice_amazfit_trex">You are about to install the %s firmware on your Amazfit T-Rex.\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!</string>
|
<string name="fw_upgrade_notice_amazfit_trex">You are about to install the %s firmware on your Amazfit T-Rex.\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!</string>
|
||||||
<string name="fw_upgrade_notice_miband3">You are about to install the %s firmware on your Mi Band 3.\n\nPlease make sure to install the .fw file, and after that the .res file. Your band 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\nPROCEED AT YOUR OWN RISK!</string>
|
<string name="fw_upgrade_notice_miband3">You are about to install the %s firmware on your Mi Band 3.\n\nPlease make sure to install the .fw file, and after that the .res file. Your band 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\nPROCEED AT YOUR OWN RISK!</string>
|
||||||
<string name="fw_upgrade_notice_miband4">You are about to install the %s firmware on your Mi Band 4.\n\nPlease make sure to install the .fw file, and after that the .res file. Your band 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\nPROCEED AT YOUR OWN RISK!</string>
|
<string name="fw_upgrade_notice_miband4">You are about to install the %s firmware on your Mi Band 4.\n\nPlease make sure to install the .fw file, and after that the .res file. Your band 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\nPROCEED AT YOUR OWN RISK!</string>
|
||||||
|
<string name="fw_upgrade_notice_miband5">You are about to install the %s firmware on your Mi Band 5.\n\nPlease make sure to install the .fw file, and after that the .res file. Your band 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\nPROCEED AT YOUR OWN RISK!</string>
|
||||||
<string name="fw_multi_upgrade_notice">You are about to install the %1$s and %2$s firmware, instead of the ones currently on your Mi Band.</string>
|
<string name="fw_multi_upgrade_notice">You are about to install the %1$s and %2$s firmware, instead of the ones currently on your Mi Band.</string>
|
||||||
<string name="miband_firmware_known">This firmware has been tested and is known to be compatible with Gadgetbridge.</string>
|
<string name="miband_firmware_known">This firmware has been tested and is known to be compatible with Gadgetbridge.</string>
|
||||||
<string name="miband_firmware_unknown_warning">"This firmware is untested and may not be compatible with Gadgetbridge.\n\nYou are DISCOURAGED from flashing it!"</string>
|
<string name="miband_firmware_unknown_warning">"This firmware is untested and may not be compatible with Gadgetbridge.\n\nYou are DISCOURAGED from flashing it!"</string>
|
||||||
@ -721,6 +722,7 @@
|
|||||||
<string name="devicetype_miband2">Mi Band 2</string>
|
<string name="devicetype_miband2">Mi Band 2</string>
|
||||||
<string name="devicetype_miband3">Mi Band 3</string>
|
<string name="devicetype_miband3">Mi Band 3</string>
|
||||||
<string name="devicetype_miband4">Mi Band 4</string>
|
<string name="devicetype_miband4">Mi Band 4</string>
|
||||||
|
<string name="devicetype_miband5">Mi Band 5</string>
|
||||||
<string name="devicetype_amazfit_bip">Amazfit Bip</string>
|
<string name="devicetype_amazfit_bip">Amazfit Bip</string>
|
||||||
<string name="devicetype_amazfit_bip_lite">Amazfit Bip Lite</string>
|
<string name="devicetype_amazfit_bip_lite">Amazfit Bip Lite</string>
|
||||||
<string name="devicetype_amazfit_cor">Amazfit Cor</string>
|
<string name="devicetype_amazfit_cor">Amazfit Cor</string>
|
||||||
@ -764,6 +766,8 @@
|
|||||||
<string name="menuitem_notifications">Notifications</string>
|
<string name="menuitem_notifications">Notifications</string>
|
||||||
<string name="menuitem_activity">Activity</string>
|
<string name="menuitem_activity">Activity</string>
|
||||||
<string name="menuitem_weather">Weather</string>
|
<string name="menuitem_weather">Weather</string>
|
||||||
|
<string name="menuitem_breathing">Breathing</string>
|
||||||
|
<string name="menuitem_cycles">Cycles</string>
|
||||||
<string name="menuitem_alarm">Alarm</string>
|
<string name="menuitem_alarm">Alarm</string>
|
||||||
<string name="menuitem_timer">Timer</string>
|
<string name="menuitem_timer">Timer</string>
|
||||||
<string name="menuitem_compass">Compass</string>
|
<string name="menuitem_compass">Compass</string>
|
||||||
@ -773,6 +777,7 @@
|
|||||||
<string name="menuitem_music">Music</string>
|
<string name="menuitem_music">Music</string>
|
||||||
<string name="menuitem_more">More</string>
|
<string name="menuitem_more">More</string>
|
||||||
<string name="menuitem_nfc">NFC</string>
|
<string name="menuitem_nfc">NFC</string>
|
||||||
|
<string name="menuitem_stress">Stress</string>
|
||||||
<string name="menuitem_pai">PAI</string>
|
<string name="menuitem_pai">PAI</string>
|
||||||
<string name="menuitem_hr">Heart Rate</string>
|
<string name="menuitem_hr">Heart Rate</string>
|
||||||
<string name="menuitem_eventreminder">Event Reminder</string>
|
<string name="menuitem_eventreminder">Event Reminder</string>
|
||||||
|
@ -30,11 +30,14 @@
|
|||||||
<item name="p_menuitem_settings" type="string">settings</item>
|
<item name="p_menuitem_settings" type="string">settings</item>
|
||||||
<item name="p_menuitem_alipay" type="string">alipay</item>
|
<item name="p_menuitem_alipay" type="string">alipay</item>
|
||||||
<item name="p_menuitem_notifications" type="string">notifications</item>
|
<item name="p_menuitem_notifications" type="string">notifications</item>
|
||||||
|
<item name="p_menuitem_breathing" type="string">breathing</item>
|
||||||
<item name="p_menuitem_music" type="string">music</item>
|
<item name="p_menuitem_music" type="string">music</item>
|
||||||
<item name="p_menuitem_more" type="string">more</item>
|
<item name="p_menuitem_more" type="string">more</item>
|
||||||
<item name="p_menuitem_nfc" type="string">nfc</item>
|
<item name="p_menuitem_nfc" type="string">nfc</item>
|
||||||
<item name="p_menuitem_hr" type="string">hr</item>
|
<item name="p_menuitem_hr" type="string">hr</item>
|
||||||
<item name="p_menuitem_pai" type="string">pai</item>
|
<item name="p_menuitem_pai" type="string">pai</item>
|
||||||
|
<item name="p_menuitem_stress" type="string">stress</item>
|
||||||
|
<item name="p_menuitem_cycles" type="string">cycles</item>
|
||||||
<item name="p_menuitem_eventreminder" type="string">eventreminder</item>
|
<item name="p_menuitem_eventreminder" type="string">eventreminder</item>
|
||||||
<item name="p_menuitem_workout" type="string">workout</item>
|
<item name="p_menuitem_workout" type="string">workout</item>
|
||||||
<item name="p_menuitem_worldclock" type="string">worldclock</item>
|
<item name="p_menuitem_worldclock" type="string">worldclock</item>
|
||||||
|
20
app/src/main/res/xml/devicesettings_miband5.xml
Normal file
20
app/src/main/res/xml/devicesettings_miband5.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<MultiSelectListPreference
|
||||||
|
android:icon="@drawable/ic_widgets"
|
||||||
|
android:defaultValue="@array/pref_miband5_display_items_default"
|
||||||
|
android:dialogTitle="@string/mi2_prefs_display_items"
|
||||||
|
android:entries="@array/pref_miband5_display_items"
|
||||||
|
android:entryValues="@array/pref_miband5_display_items_values"
|
||||||
|
android:key="display_items"
|
||||||
|
android:summary="@string/mi2_prefs_display_items_summary"
|
||||||
|
android:title="@string/mi2_prefs_display_items" />
|
||||||
|
<ListPreference
|
||||||
|
android:icon="@drawable/ic_language"
|
||||||
|
android:defaultValue="auto"
|
||||||
|
android:entries="@array/pref_miband5_language"
|
||||||
|
android:entryValues="@array/pref_miband5_language_values"
|
||||||
|
android:key="language"
|
||||||
|
android:summary="%s"
|
||||||
|
android:title="@string/pref_title_language" />
|
||||||
|
</androidx.preference.PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user