diff --git a/README.md b/README.md index 072392f2b..ffc878842 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ vendor's servers. * Mi Band 3 [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-3) * Mi Band 4 (WARNING: NEEDS VENDOR APP WITH ACCOUNT ONCE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-4) * Mi/Amazfit Band 5 (WARNING: NEEDS VENDOR APP WITH ACCOUNT ONCE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-5) +* Amazfit X (WARNING: NEEDS VENDOR APP WITH ACCOUNT ONCE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-5) * Mi Scale 2 (Currently only displays a toast after stepping on the scale) * NO.1 F1 * Pebble, Pebble Steel, Pebble Time, Pebble Time Steel, Pebble Time Round [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Pebble) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java index cd3f75f0b..c48663e2c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java @@ -53,6 +53,7 @@ public class HuamiConst { public static final String MI_BAND5_NAME = "Mi Smart Band 5"; public static final String AMAZFIT_BAND5_NAME = "Amazfit Band 5"; public static final String AMAZFIT_NEO_NAME = "Amazfit Neo"; + public static final String AMAZFIT_X = "Amazfit X"; public static final String PREF_ACTIVATE_DISPLAY_ON_LIFT = "activate_display_on_lift_wrist"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java new file mode 100644 index 000000000..dfc450a7f --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXCoordinator.java @@ -0,0 +1,115 @@ +/* Copyright (C) 2016-2021 Andreas Shimokawa, Carsten Pfeiffer, Daniele + Gobbetti, HardLight, José Rebelo, odavo32nof + + 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.amazfitx; + +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.devices.huami.amazfitx.AmazfitXFWInstallHandler; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; + +public class AmazfitXCoordinator extends HuamiCoordinator { + private static final Logger LOG = LoggerFactory.getLogger(AmazfitXCoordinator.class); + + @Override + public DeviceType getDeviceType() { + return DeviceType.AMAZFITX; + } + + @NonNull + @Override + public DeviceType getSupportedType(GBDeviceCandidate candidate) { + try { + BluetoothDevice device = candidate.getDevice(); + String name = device.getName(); + if (name != null && name.equalsIgnoreCase(HuamiConst.AMAZFIT_X)) { + return DeviceType.AMAZFITX; + } + } catch (Exception ex) { + LOG.error("unable to check device support", ex); + } + return DeviceType.UNKNOWN; + + } + + + @Override + public InstallHandler findInstallHandler(Uri uri, Context context) { + // TOOD Need to be checked first + AmazfitXFWInstallHandler handler = new AmazfitXFWInstallHandler(uri, context); + return handler.isValid() ? handler : null; +// return 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_amazfitx, + 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_bt_connected_advertisement, + R.xml.devicesettings_device_actions, + R.xml.devicesettings_pairingkey, + R.xml.devicesettings_high_mtu + }; + } + + @Override + public int getBondingStyle() { + return BONDING_STYLE_REQUIRE_KEY; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXFWHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXFWHelper.java new file mode 100644 index 000000000..4addb2122 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXFWHelper.java @@ -0,0 +1,40 @@ +/* Copyright (C) 2017-2021 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.amazfitx; + +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.amazfitx.AmazfitXFirmwareInfo; + +public class AmazfitXFWHelper extends HuamiFWHelper { + + public AmazfitXFWHelper(Uri uri, Context context) throws IOException { + super(uri, context); + } + + @Override + protected void determineFirmwareInfo(byte[] wholeFirmwareBytes) { + firmwareInfo = new AmazfitXFirmwareInfo(wholeFirmwareBytes); + if (!firmwareInfo.isHeaderValid()) { + throw new IllegalArgumentException("Not an Amazfit X firmware"); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXFWInstallHandler.java new file mode 100644 index 000000000..dad7a4842 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/amazfitx/AmazfitXFWInstallHandler.java @@ -0,0 +1,50 @@ +/* Copyright (C) 2015-2021 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.amazfitx; + +import android.content.Context; +import android.net.Uri; + +import java.io.IOException; + +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitx.AmazfitXFWHelper; +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 AmazfitXFWInstallHandler extends AbstractMiBandFWInstallHandler { + AmazfitXFWInstallHandler(Uri uri, Context context) { + super(uri, context); + } + + @Override + protected String getFwUpgradeNotice() { + return mContext.getString(R.string.fw_upgrade_notice_amazfitx, helper.getHumanFirmwareVersion()); + } + + @Override + protected AbstractMiBandFWHelper createHelper(Uri uri, Context context) throws IOException { + return new AmazfitXFWHelper(uri, context); + } + + @Override + protected boolean isSupportedDeviceType(GBDevice device) { + return device.getType() == DeviceType.AMAZFITX; + } +} 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 f885d5345..17e85bae5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceType.java @@ -93,6 +93,7 @@ public enum DeviceType { SONY_SWR12(310, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_sonyswr12), LIVEVIEW(320, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_liveview), WASPOS(330, R.drawable.ic_device_pebble, R.drawable.ic_device_pebble_disabled, R.string.devicetype_waspos), + AMAZFITX(340, R.drawable.ic_device_miband2, R.drawable.ic_device_miband2_disabled, R.string.devicetype_amazfit_x), 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/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java index 0e18231e5..3f94fc00f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java @@ -58,6 +58,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitgts2.Am import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitneo.AmazfitNeoSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfittrex.AmazfitTRexSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitvergel.AmazfitVergeLSupport; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitx.AmazfitXSupport; 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.miband5.MiBand5Support; @@ -231,6 +232,9 @@ public class DeviceSupportFactory { case AMAZFITBAND5: deviceSupport = new ServiceDeviceSupport(new AmazfitBand5Support(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; + case AMAZFITX: + deviceSupport = new ServiceDeviceSupport(new AmazfitXSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); + break; case AMAZFITNEO: deviceSupport = new ServiceDeviceSupport(new AmazfitNeoSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); break; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitx/AmazfitXFirmwareInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitx/AmazfitXFirmwareInfo.java new file mode 100644 index 000000000..cc7061905 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitx/AmazfitXFirmwareInfo.java @@ -0,0 +1,86 @@ +/* Copyright (C) 2017-2021 Andreas Shimokawa, Cristian Alfano, Daniele + Gobbetti, odavo32nof + + 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.huami.amazfitx; + +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 AmazfitXFirmwareInfo 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 crcToVersion = new HashMap<>(); + + static { + // no known fw so far + } + + public AmazfitXFirmwareInfo(byte[] bytes) { + super(bytes); + } + + @Override + protected HuamiFirmwareType determineFirmwareType(byte[] bytes) { + // Currently always return INVALID because it's untested + /* + 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, "Amazfit X")) { + return HuamiFirmwareType.FIRMWARE; + } + return HuamiFirmwareType.INVALID; + } + if (ArrayUtils.startsWith(bytes, WATCHFACE_HEADER_UIHH)) { + 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.AMAZFITX; + } + + @Override + protected Map getCrcMap() { + return crcToVersion; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitx/AmazfitXSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitx/AmazfitXSupport.java new file mode 100644 index 000000000..50a069a96 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitx/AmazfitXSupport.java @@ -0,0 +1,52 @@ +/* Copyright (C) 2017-2021 Andreas Shimokawa, Carsten Pfeiffer, Dmytro Bielik + + 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.huami.amazfitx; + +import android.content.Context; +import android.net.Uri; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitband5.AmazfitBand5FWHelper; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband5.MiBand5Support; + +public class AmazfitXSupport extends MiBand5Support { + private static final Logger LOG = LoggerFactory.getLogger(AmazfitXSupport.class); + + @Override + protected AmazfitXSupport setDisplayItems(TransactionBuilder builder) { + setDisplayItemsNew(builder, false, R.array.pref_amazfitband5_display_items_default); + return this; + } + + @Override + protected AmazfitXSupport setShortcuts(TransactionBuilder builder) { + setDisplayItemsNew(builder, true, R.array.pref_amazfitband5_shortcuts_default); + return this; + } + + @Override + public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException { + return new AmazfitBand5FWHelper(uri, context); + } +} 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 ca2e5a2bb..fd88f69fd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java @@ -65,6 +65,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitcor2.AmazfitCor import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgtr.AmazfitGTRCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgtr.AmazfitGTRLiteCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgtr2.AmazfitGTR2Coordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitx.AmazfitXCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppe.ZeppECoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgtr2.AmazfitGTR2eCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgts.AmazfitGTSCoordinator; @@ -231,6 +232,7 @@ public class DeviceHelper { private List createCoordinators() { List result = new ArrayList<>(); result.add(new MiScale2DeviceCoordinator()); + result.add(new AmazfitXCoordinator()); result.add(new AmazfitBipCoordinator()); result.add(new AmazfitBipLiteCoordinator()); result.add(new AmazfitCorCoordinator()); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 756a1be5b..d0447e2b2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -76,6 +76,7 @@ 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! 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! 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! + You are about to install the %s firmware on your Amazfit X.\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! 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!" @@ -809,6 +810,7 @@ Amazfit GTS 2 Amazfit GTS 2 Mini Amazfit GTS 2e + Amazfit Band 5 Zepp E Vibratissimo LiveView diff --git a/app/src/main/res/xml/devicesettings_amazfitx.xml b/app/src/main/res/xml/devicesettings_amazfitx.xml new file mode 100644 index 000000000..7a2dd852e --- /dev/null +++ b/app/src/main/res/xml/devicesettings_amazfitx.xml @@ -0,0 +1,30 @@ + + + + + +