diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lenovo/watchxplus/WatchXPlusConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lenovo/watchxplus/WatchXPlusConstants.java
index 2ac346f40..dfe3a641e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lenovo/watchxplus/WatchXPlusConstants.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lenovo/watchxplus/WatchXPlusConstants.java
@@ -36,6 +36,7 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
public static final String PREF_FIND_PHONE_DURATION = "prefs_find_phone_duration";
public static final String PREF_ALTITUDE = "watchxplus_altitude";
public static final String PREF_REPEAT = "watchxplus_repeat";
+ public static final String PREF_IS_BP_CALIBRATED = "watchxplus_is_bp_calibrated";
// time format constants
public static final byte ARG_SET_TIMEMODE_24H = 0x00;
@@ -50,7 +51,9 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
public static final byte[] CMD_RETRIEVE_DATA_CONTENT = new byte[]{(byte)0xF0, 0x12};
public static final byte[] CMD_REMOVE_DATA_CONTENT = new byte[]{(byte)0xF0, 0x32};
public static final byte[] CMD_BLOOD_PRESSURE_MEASURE = new byte[]{0x05, 0x0D};
-
+ public static final byte[] CMD_HEART_RATE_MEASURE = new byte[]{0x03, 0x23};
+ public static final byte[] CMD_IS_BP_CALIBRATED = new byte[]{0x05, 0x0B};
+ public static final byte[] CMD_BP_CALIBRATION = new byte[]{0x05, 0x0C};
public static final byte[] CMD_NOTIFICATION_TEXT_TASK = new byte[]{0x03, 0x06};
public static final byte[] CMD_NOTIFICATION_CANCEL = new byte[]{0x03, 0x04};
@@ -67,6 +70,7 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
public static final byte[] RESP_SHAKE_SWITCH = new byte[]{0x08, 0x03, -0x6E};
public static final byte[] RESP_DISCONNECT_REMIND = new byte[]{0x08, 0x00, 0x11};
+ public static final byte[] RESP_IS_BP_CALIBRATED = new byte[]{0x08, 0x05, 0x0B};
public static final byte[] RESP_AUTHORIZATION_TASK = new byte[]{0x01, 0x01, 0x05};
public static final byte[] RESP_DAY_STEPS_INDICATOR = new byte[]{0x08, 0x10, 0x03};
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lenovo/watchxplus/WatchXPlusDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lenovo/watchxplus/WatchXPlusDeviceCoordinator.java
index 2fb9a6179..71863c7e8 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lenovo/watchxplus/WatchXPlusDeviceCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lenovo/watchxplus/WatchXPlusDeviceCoordinator.java
@@ -37,6 +37,8 @@ public class WatchXPlusDeviceCoordinator extends AbstractDeviceCoordinator {
public static final int FindPhone_ON = -1;
public static final int FindPhone_OFF = 0;
+ public static boolean isBPCalibrated = false;
+
protected static Prefs prefs = GBApplication.getPrefs();
@NonNull
@@ -164,6 +166,10 @@ public class WatchXPlusDeviceCoordinator extends AbstractDeviceCoordinator {
};
}
+/*
+Prefs from device settings on main page
+ */
+// return saved time format
public static byte getTimeMode(SharedPreferences sharedPrefs) {
String timeMode = sharedPrefs.getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, getContext().getString(R.string.p_timeformat_24h));
if (timeMode.equals(getContext().getString(R.string.p_timeformat_24h))) {
@@ -172,6 +178,7 @@ public class WatchXPlusDeviceCoordinator extends AbstractDeviceCoordinator {
return WatchXPlusConstants.ARG_SET_TIMEMODE_12H;
}
}
+
// check if it is needed to toggle Lift Wrist to Sreen on
public static boolean shouldEnableHeadsUpScreen(SharedPreferences sharedPrefs) {
String liftMode = sharedPrefs.getString(WatchXPlusConstants.PREF_ACTIVATE_DISPLAY, getContext().getString(R.string.p_on));
@@ -185,19 +192,8 @@ public class WatchXPlusDeviceCoordinator extends AbstractDeviceCoordinator {
// WatchXPlus doesn't support scheduled intervals. Treat it as "on".
return !lostReminder.equals(getContext().getString(R.string.p_off));
}
-// read altitude from preferences
- public static int getAltitude(String address) {
- return (int) prefs.getInt(WatchXPlusConstants.PREF_ALTITUDE, 200);
- }
-
-// read repeat call notification
- public static int getRepeatOnCall(String address) {
- return (int) prefs.getInt(WatchXPlusConstants.PREF_REPEAT, 1);
- }
-
-// read repeat call preferences
- public static int getRepeat = 0;
+// find phone settings
/**
* @return {@link #FindPhone_OFF}, {@link #FindPhone_ON}, or the duration
*/
@@ -226,4 +222,31 @@ public class WatchXPlusDeviceCoordinator extends AbstractDeviceCoordinator {
}
}
}
+
+/*
+Values from device specific settings page
+ */
+// read altitude from preferences
+ public static int getAltitude(String address) {
+ return (int) prefs.getInt(WatchXPlusConstants.PREF_ALTITUDE, 200);
+ }
+
+// read repeat call notification
+ public static int getRepeatOnCall(String address) {
+ return (int) prefs.getInt(WatchXPlusConstants.PREF_REPEAT, 1);
+ }
+
+/*
+Other saved preferences
+ */
+ public static byte getBPCalibrationStatus(SharedPreferences sharedPrefs) {
+ String timeMode = sharedPrefs.getString(DeviceSettingsPreferenceConst.PREF_TIMEFORMAT, getContext().getString(R.string.p_timeformat_24h));
+ if (timeMode.equals(getContext().getString(R.string.p_timeformat_24h))) {
+ return WatchXPlusConstants.ARG_SET_TIMEMODE_24H;
+ } else {
+ return WatchXPlusConstants.ARG_SET_TIMEMODE_12H;
+ }
+ }
+
+
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java
index d61b8bb0f..331f7bc99 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java
@@ -247,9 +247,12 @@ public class NotificationListener extends NotificationListenerService {
return;
}
}
+
if (shouldIgnore(sbn)) {
- LOG.info("Ignore notification");
- return;
+ if (!"com.sec.android.app.clockpackage".equals(sbn.getPackageName())) { // allow phone alarm notification
+ LOG.info("Ignore notification: " + sbn.getPackageName());
+ return;
+ }
}
switch (GBApplication.getGrantedInterruptionFilter()) {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lenovo/watchxplus/WatchXPlusDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lenovo/watchxplus/WatchXPlusDeviceSupport.java
index 4e320c8ad..a0bdf88fb 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lenovo/watchxplus/WatchXPlusDeviceSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lenovo/watchxplus/WatchXPlusDeviceSupport.java
@@ -74,12 +74,14 @@ import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
+import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
+import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WaitAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lenovo.operations.InitOperation;
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
@@ -167,7 +169,6 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
@Override
public void onNotification(NotificationSpec notificationSpec) {
-
String senderOrTitle = StringUtils.getFirstOf(notificationSpec.sender, notificationSpec.title);
String message = StringUtils.truncate(senderOrTitle, 14) + "\0";
@@ -178,23 +179,37 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
message += StringUtils.truncate(notificationSpec.body, 64);
}
- sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_DEFAULT, message, false);
+ sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_DEFAULT, message);
}
- private void sendNotification(int notificationChannel, String notificationText, boolean repeat) {
+// cancel notification
+// cancel watch notification - stop vibration and turn off screen
+ private void cancelNotification() {
+ try {
+ getQueue().clear();
+ TransactionBuilder builder = performInitialized("cancelNotification");
+ byte[] bArr;
+ int mPosition = 1024;
+ int mMessageId = 0xFF;
+ bArr = new byte[6];
+ bArr[0] = (byte) ((int) (mPosition >> 24));
+ bArr[1] = (byte) ((int) (mPosition >> 16));
+ bArr[2] = (byte) ((int) (mPosition >> 8));
+ bArr[3] = (byte) ((int) mPosition);
+ bArr[4] = (byte) (mMessageId >> 8);
+ bArr[5] = (byte) mMessageId;
+ builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
+ buildCommand(WatchXPlusConstants.CMD_NOTIFICATION_CANCEL,
+ WatchXPlusConstants.WRITE_VALUE,
+ bArr));
+ builder.queue(getQueue());
+ } catch (IOException e) {
+ LOG.warn("Unable to cancel notification", e);
+ }
+ }
+
+ private void sendNotification(int notificationChannel, String notificationText) {
try {
- int on = 5000; // repeat delay ms
- int test = 1; // repeat once
- if (repeat) {
- test = WatchXPlusDeviceCoordinator.getRepeatOnCall(getDevice().getAddress());
- if (test < 1) {
- test = 1;
- }
- WatchXPlusDeviceCoordinator.getRepeat = 1;
- } else {
- test = 1;
- WatchXPlusDeviceCoordinator.getRepeat = 0;
- }
TransactionBuilder builder = performInitialized("showNotification");
byte[] command = WatchXPlusConstants.CMD_NOTIFICATION_TEXT_TASK;
byte[] text = notificationText.getBytes("UTF-8");
@@ -222,33 +237,10 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
}
messagePart[0] = (byte) notificationChannel;
messagePart[1] = (byte) messageIndex;
- for (int i = 0; i < test; i++) { // repeat call notification
- if (notificationText != "stop") {
- builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
- buildCommand(command,
- WatchXPlusConstants.KEEP_ALIVE,
- messagePart));
- if (WatchXPlusDeviceCoordinator.getRepeat == 1) {
- builder.wait(on);
- } else {
- i = test;
- break;
- }
- } else { //cancel text notification
- i = test;
- byte[] bArr;
- int mPosition = 1024;
- bArr = new byte[4];
- bArr[0] = (byte) ((int) (mPosition >> 24));
- bArr[1] = (byte) ((int) (mPosition >> 16));
- bArr[2] = (byte) ((int) (mPosition >> 8));
- bArr[3] = (byte) ((int) mPosition);
- builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
- buildCommand(WatchXPlusConstants.CMD_NOTIFICATION_CANCEL,
- WatchXPlusConstants.WRITE_VALUE,
- bArr));
- }
- }
+ builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
+ buildCommand(command,
+ WatchXPlusConstants.KEEP_ALIVE,
+ messagePart));
}
builder.queue(getQueue());
} catch (IOException e) {
@@ -256,6 +248,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
}
}
+
private WatchXPlusDeviceSupport enableNotificationChannels(TransactionBuilder builder) {
builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(WatchXPlusConstants.CMD_NOTIFICATION_SETTINGS,
@@ -413,9 +406,8 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
.enableNotificationChannels(builder)
.enableDoNotDisturb(builder, false)
.setFitnessGoal(builder)
+ .getBloodPressureCalibrationStatus(builder)
.syncPreferences(builder);
- //.setHeadsUpScreen(builder, true);
- //.getSwitchStatus(builder);
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext()));
builder.setGattCallback(this);
@@ -424,7 +416,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
@Override
public void onDeleteNotification(int id) {
-
+ cancelNotification();
}
@Override
@@ -475,21 +467,105 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
}
}
int repeat = 0;
+ boolean isRinging = false;
@Override
- public void onSetCallState(CallSpec callSpec) {
- SharedPreferences.Editor prefs = GBApplication.getPrefs().getPreferences().edit();
+ public void onSetCallState(final CallSpec callSpec) {
+ int repeatDelay = 5000;
+ int repeatCount = WatchXPlusDeviceCoordinator.getRepeatOnCall(getDevice().getAddress());
+ if (repeatCount < 0) {
+ repeatCount = 0;
+ }
+ if (repeatCount > 5) {
+ repeatCount = 5;
+ }
+
+ if("Phone".equals(callSpec.name)) { // ignore notification if caller name is Phone
+ return;
+ }
+
switch (callSpec.command) {
case CallSpec.CALL_INCOMING:
- WatchXPlusDeviceCoordinator.getRepeat = 1;
- sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name, true);
+ isRinging = true;
+ sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
+// TODO dirty code, need to fix
+// repeat call notification up to 5 times
+ Handler handler = new Handler();
+ if (repeatCount > 0) {
+ handler.postDelayed(new Runnable() {
+ public void run() {
+ // Actions to do after 5 seconds
+ if (isRinging) {
+ sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
+ }
+ }
+ }, repeatDelay);
+ }
+ if (repeatCount > 1) {
+ handler.postDelayed(new Runnable() {
+ public void run() {
+ // Actions to do after 5 seconds
+ if (isRinging) {
+ sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
+ }
+ }
+ }, repeatDelay * 2);
+ }
+ if (repeatCount > 2) {
+ handler.postDelayed(new Runnable() {
+ public void run() {
+ // Actions to do after 5 seconds
+ if (isRinging) {
+ sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
+ }
+ }
+ }, repeatDelay * 3);
+ }
+ if (repeatCount > 3) {
+ handler.postDelayed(new Runnable() {
+ public void run() {
+ // Actions to do after 5 seconds
+ if (isRinging) {
+ sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
+ }
+ }
+ }, repeatDelay * 4);
+ }
+ if (repeatCount > 4) {
+ handler.postDelayed(new Runnable() {
+ public void run() {
+ // Actions to do after 5 seconds
+ if (isRinging) {
+ sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, callSpec.name);
+ }
+ }
+ }, repeatDelay * 5);
+ }
break;
case CallSpec.CALL_START:
- WatchXPlusDeviceCoordinator.getRepeat = 1;
- sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, "stop", false);
+ isRinging = false;
+ cancelNotification();
+ break;
+ case CallSpec.CALL_REJECT:
+ isRinging = false;
+ cancelNotification();
+ break;
+ case CallSpec.CALL_ACCEPT:
+ isRinging = false;
+ cancelNotification();
+ break;
+ case CallSpec.CALL_OUTGOING:
+ isRinging = false;
+ cancelNotification();
break;
case CallSpec.CALL_END:
- WatchXPlusDeviceCoordinator.getRepeat = 0;
- sendNotification(WatchXPlusConstants.NOTIFICATION_CHANNEL_PHONE_CALL, "stop", false);
+ if (isRinging) {
+ // it's a missed call
+ // don't clear notification to preserve small icon near bluetooth
+ isRinging = false;
+ } else {
+ isRinging = false;
+ cancelNotification();
+ }
break;
default:
break;
@@ -573,7 +649,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
@Override
public void onHeartRateTest() {
-
+ //requestHeartRateMeasurement();
}
@Override
@@ -658,7 +734,29 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
requestBloodPressureMeasurement();
}
+// check status of blood pressure calibration
+ private WatchXPlusDeviceSupport getBloodPressureCalibrationStatus(TransactionBuilder builder) {
+ builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
+ buildCommand(WatchXPlusConstants.CMD_IS_BP_CALIBRATED,
+ WatchXPlusConstants.READ_VALUE));
+
+ return this;
+ }
+
+ private void handleBloodPressureCalibrationStatus(byte[] value) {
+ if (Conversion.calculateHigh(value[8]) != 0) {
+ WatchXPlusDeviceCoordinator.isBPCalibrated = false;
+ } else {
+ WatchXPlusDeviceCoordinator.isBPCalibrated = true;
+ }
+ }
+// end check status of blood pressure calibration
+
private void requestBloodPressureMeasurement() {
+ if (!WatchXPlusDeviceCoordinator.isBPCalibrated) {
+ LOG.warn("BP is NOT calibrated");
+ return;
+ }
try {
TransactionBuilder builder = performInitialized("bpMeasure");
@@ -673,6 +771,29 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
}
}
+
+ /*
+ // not working!!!
+ private void requestHeartRateMeasurement() {
+ try {
+ TransactionBuilder builder = performInitialized("hrMeasure");
+
+ byte[] command = new byte[]{0x05, 0x0B};
+
+ builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
+ buildCommand(command,
+ WatchXPlusConstants.READ_VALUE));
+
+ // builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
+ // buildCommand(command,
+ // WatchXPlusConstants.TASK, new byte[]{0x01}));
+ builder.queue(getQueue());
+ } catch (IOException e) {
+ LOG.warn("Unable to request HR Measure", e);
+ }
+ }
+*/
+
@Override
public void onSendWeather(WeatherSpec weatherSpec) {
try {
@@ -708,18 +829,19 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_FIRMWARE_INFO, 5)) {
handleFirmwareInfo(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_SHAKE_SWITCH, 5)) {
- LOG.info(" RESP LIGHT SCREEN ");
handleShakeState(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_DISCONNECT_REMIND, 5)) {
- LOG.info(" RESP DISCONNECT REMINDER ");
handleDisconnectReminderState(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_BATTERY_INFO, 5)) {
handleBatteryState(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_TIME_SETTINGS, 5)) {
handleTime(value);
+ } else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_IS_BP_CALIBRATED, 5)) {
+ handleBloodPressureCalibrationStatus(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_BUTTON_INDICATOR, 5)) {
this.onReverseFindDevice(true);
// It looks like WatchXPlus doesn't send this action
+// WRONG: WatchXPlus send this on find phone
LOG.info(" Unhandled action: Button pressed");
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_ALARM_INDICATOR, 5)) {
LOG.info(" Alarm active: id=" + value[8]);
@@ -1409,5 +1531,25 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
(byte) (value >> 8),
(byte) value};
}
+
+ static int calculateLow(byte... bArr) {
+ int i = 0;
+ int i2 = 0;
+ while (i < bArr.length) {
+ i2 += (bArr[i] & 255) << (i * 8);
+ i++;
+ }
+ return i2;
+ }
+
+ static int calculateHigh(byte... bArr) {
+ int i = 0;
+ int i2 = 0;
+ while (i < bArr.length) {
+ i2 += (bArr[i] & 255) << (((bArr.length - 1) - i) * 8);
+ i++;
+ }
+ return i2;
+ }
}
}
diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml
index e3aab489e..10ac20d9b 100644
--- a/app/src/main/res/values-bg/strings.xml
+++ b/app/src/main/res/values-bg/strings.xml
@@ -284,6 +284,13 @@
Watch 9 свързване
Watch 9 сверяване
WatchX Plus сверяване
+ Edinici
+ Формат на часа
+ Калибриране на височина
+ Повтори известия за звънене
+ Възможни стойности min=0, max=5
+ WatchXPlus настройки
+ WatchXPlus калибриране
Наблюдение/анализ на съня
Съхраняване на log файлове
Инициализиране
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ea014997e..e3409ae9d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -190,8 +190,10 @@
Units
Time format
Altitude calibration
- Repeat vibration on call
+ Repeat call notification
+ Possible values min=0, max=5
WatchXPlus settings
+ WatchXPlus calibration
Makibes HR3 settings
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 5d1cd46e9..3bf87b1a8 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -583,19 +583,24 @@
android:key="pref_category_watchxplus_general"
android:title="@string/pref_header_general">
+
+
+
+
-
-
-
+