Huawei: Real-time heart rate mode and low/high alerts

This commit is contained in:
Me7c7 2025-02-25 09:44:15 +02:00 committed by José Rebelo
parent cbe82a482d
commit b164397467
15 changed files with 411 additions and 11 deletions

View File

@ -94,6 +94,10 @@ public final class HuaweiConstants {
public static final String PREF_HUAWEI_DND_LIFT_WRIST_TYPE = "dnd_lift_wrist_type"; // SharedPref for 0x01 0x1D
public static final String PREF_HUAWEI_DEBUG_REQUEST = "debug_huawei_request";
public static final String PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT = "continuous_skin_temperature_measurement";
public static final String PREF_HUAWEI_HEART_RATE_REALTIME_MODE = "pref_huawei_heart_rate_realtime_mode";
public static final String PREF_HUAWEI_HEART_RATE_LOW_ALERT = "pref_huawei_heart_rate_low_alert";
public static final String PREF_HUAWEI_HEART_RATE_HIGH_ALERT= "pref_huawei_heart_rate_high_alert";
public static final String PREF_HUAWEI_SPO_LOW_ALERT= "pref_huawei_spo_low_alert";
public static final String PKG_NAME = "com.huawei.devicegroupmanage";
}

View File

@ -281,10 +281,22 @@ public class HuaweiCoordinator {
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_inactivity_sheduled);
if (supportsTruSleep())
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_trusleep);
if (supportsHeartRate())
if (supportsHeartRate()) {
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_heartrate_automatic_enable);
if (supportsSPo2())
if (supportsRealtimeHeartRate())
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_huawei_heart_rate_realtime);
if(supportsHighHeartRateAlert())
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_huawei_heart_rate_huawei_high_alert);
if(supportsLowHeartRateAlert())
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_huawei_heart_rate_huawei_low_alert);
}
if (supportsSPo2()) {
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_spo_automatic_enable);
if(supportsLowSPo2Alert())
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_huawei_spo_low_alert);
}
if(supportsTemperature()) {
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_temperature_automatic_enable);
}
@ -470,6 +482,18 @@ public class HuaweiCoordinator {
return supportsHeartRate() || getForceOption(gbDevice, PREF_FORCE_ENABLE_HEARTRATE_SUPPORT);
}
public boolean supportsRealtimeHeartRate() {
return supportsCommandForService(0x07, 0x1c);
}
public boolean supportsHighHeartRateAlert() {
return supportsCommandForService(0x07, 0x1d);
}
public boolean supportsLowHeartRateAlert() {
return supportsCommandForService(0x07, 0x22);
}
public boolean supportsHeartRateZones() {
return supportsCommandForService(0x07, 0x13);
}
@ -490,6 +514,10 @@ public class HuaweiCoordinator {
return supportsSPo2() || getForceOption(gbDevice, PREF_FORCE_ENABLE_SPO2_SUPPORT);
}
public boolean supportsLowSPo2Alert() {
return supportsCommandForService(0x07, 0x25);
}
public boolean supportsRunPaceConfig() {
return supportsCommandForService(0x07, 0x28);
}

View File

@ -39,6 +39,10 @@ import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.*;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_DEBUG_REQUEST;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_HIGH_ALERT;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_LOW_ALERT;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_REALTIME_MODE;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_SPO_LOW_ALERT;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_TRUSLEEP;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_WORKMODE;
@ -106,6 +110,10 @@ public class HuaweiSettingsCustomizer implements DeviceSpecificSettingsCustomize
handler.addPreferenceHandlerFor(PREF_HUAWEI_TRUSLEEP);
handler.addPreferenceHandlerFor(PREF_HUAWEI_DEBUG_REQUEST);
handler.addPreferenceHandlerFor(PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT);
handler.addPreferenceHandlerFor(PREF_HUAWEI_HEART_RATE_REALTIME_MODE);
handler.addPreferenceHandlerFor(PREF_HUAWEI_HEART_RATE_LOW_ALERT);
handler.addPreferenceHandlerFor(PREF_HUAWEI_HEART_RATE_HIGH_ALERT);
handler.addPreferenceHandlerFor(PREF_HUAWEI_SPO_LOW_ALERT);
final Preference forceOptions = handler.findPreference(PREF_FORCE_OPTIONS);
if (forceOptions != null) {

View File

@ -701,6 +701,67 @@ public class FitnessData {
}
}
public static class EnableRealtimeHeartRate {
public static final byte id = 0x1c;
public static class Request extends HuaweiPacket {
public Request(ParamsProvider paramsProvider, boolean enableRealtimeHeartRate) {
super(paramsProvider);
this.serviceId = FitnessData.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x01, enableRealtimeHeartRate);
this.isEncrypted = true;
this.complete = true;
}
}
}
public static class HighHeartRateAlert {
public static final byte id = 0x1d;
public static class Request extends HuaweiPacket {
public Request(ParamsProvider paramsProvider, boolean enabled, byte highHeartRateAlert) {
super(paramsProvider);
this.serviceId = FitnessData.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x01, enabled);
if(enabled)
this.tlv.put(0x02, highHeartRateAlert);
this.isEncrypted = true;
this.complete = true;
}
}
}
public static class LowHeartRateAlert {
public static final byte id = 0x22;
public static class Request extends HuaweiPacket {
public Request(ParamsProvider paramsProvider, boolean enabled, byte lowHeartRateAlert) {
super(paramsProvider);
this.serviceId = FitnessData.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x01, enabled);
if(enabled)
this.tlv.put(0x02, lowHeartRateAlert);
this.isEncrypted = true;
this.complete = true;
}
}
}
public static class NotifyRestHeartRate {
public static final byte id = 0x23;
@ -738,6 +799,27 @@ public class FitnessData {
}
}
public static class LowSpoAlert {
public static final byte id = 0x25;
public static class Request extends HuaweiPacket {
public Request(ParamsProvider paramsProvider, boolean enabled, byte lowHeartRateAlert) {
super(paramsProvider);
this.serviceId = FitnessData.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x01, enabled);
if(enabled)
this.tlv.put(0x02, lowHeartRateAlert);
this.isEncrypted = true;
this.complete = true;
}
}
}
public static class RunPaceConfig {
public static final byte id = 0x28;

View File

@ -16,6 +16,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_HIGH_ALERT;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_LOW_ALERT;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_GOAL_STANDING_TIME_HOURS;
import android.bluetooth.BluetoothGattCharacteristic;
@ -147,8 +149,11 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Send
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetAutomaticHeartrateRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetAutomaticSpoRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetDisconnectNotification;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetHeartRateHighAlert;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetHeartRateLowAlert;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetMediumToStrengthThresholdRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetSkinTemperatureMeasurement;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetSpO2LowAlert;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetTemperatureUnitSetting;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.StopFindPhoneRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.StopNotificationRequest;
@ -1119,11 +1124,21 @@ public class HuaweiSupportProvider {
setDisconnectNotification();
break;
case DeviceSettingsPreferenceConst.PREF_HEARTRATE_AUTOMATIC_ENABLE:
case HuaweiConstants.PREF_HUAWEI_HEART_RATE_REALTIME_MODE:
setHeartrateAutomatic();
break;
case HuaweiConstants.PREF_HUAWEI_HEART_RATE_LOW_ALERT:
setHeartRateLowAlert();
break;
case HuaweiConstants.PREF_HUAWEI_HEART_RATE_HIGH_ALERT:
setHeartRateHighAlert();
break;
case DeviceSettingsPreferenceConst.PREF_SPO_AUTOMATIC_ENABLE:
setSpoAutomatic();
break;
case HuaweiConstants.PREF_HUAWEI_SPO_LOW_ALERT:
setSpoLowAlert();
break;
case DeviceSettingsPreferenceConst.PREF_FORCE_ENABLE_SMART_ALARM:
getAlarms();
break;
@ -2220,6 +2235,26 @@ public class HuaweiSupportProvider {
}
}
private void setHeartRateLowAlert() {
try {
SetHeartRateLowAlert req = new SetHeartRateLowAlert(this);
req.doPerform();
} catch (IOException e) {
GB.toast(context, "Failed to set heart rate low alert", Toast.LENGTH_SHORT, GB.ERROR, e);
LOG.error("Failed to set heart rate low alert", e);
}
}
private void setHeartRateHighAlert() {
try {
SetHeartRateHighAlert req = new SetHeartRateHighAlert(this);
req.doPerform();
} catch (IOException e) {
GB.toast(context, "Failed to set heart rate high alert", Toast.LENGTH_SHORT, GB.ERROR, e);
LOG.error("Failed to set heart rate high alert", e);
}
}
private void setSpoAutomatic() {
try {
SetAutomaticSpoRequest req = new SetAutomaticSpoRequest(this);
@ -2230,6 +2265,16 @@ public class HuaweiSupportProvider {
}
}
private void setSpoLowAlert() {
try {
SetSpO2LowAlert req = new SetSpO2LowAlert(this);
req.doPerform();
} catch (IOException e) {
GB.toast(context, "Failed to set spo low alert", Toast.LENGTH_SHORT, GB.ERROR, e);
LOG.error("Failed to set spo low alert", e);
}
}
public void sendDebugRequest() {
try {
LOG.debug("Send debug request");

View File

@ -23,6 +23,7 @@ import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FitnessData;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
@ -39,17 +40,28 @@ public class SetAutomaticHeartrateRequest extends Request {
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
boolean automaticHeartrateEnabled = GBApplication
boolean automaticHeartRateEnabled = GBApplication
.getDeviceSpecificSharedPrefs(supportProvider.getDevice().getAddress())
.getBoolean(DeviceSettingsPreferenceConst.PREF_HEARTRATE_AUTOMATIC_ENABLE, false);
if (automaticHeartrateEnabled)
LOG.info("Attempting to enable automatic heartrate");
boolean realtimeHeartRateEnabled = GBApplication
.getDeviceSpecificSharedPrefs(supportProvider.getDevice().getAddress())
.getBoolean(HuaweiConstants.PREF_HUAWEI_HEART_RATE_REALTIME_MODE, false);
if (automaticHeartRateEnabled)
LOG.info("Attempting to enable automatic heart rate");
else
LOG.info("Attempting to disable automatic heartrate");
try {
return new FitnessData.EnableAutomaticHeartrate.Request(paramsProvider, automaticHeartrateEnabled).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
LOG.info("Attempting to disable automatic heart rate");
if(realtimeHeartRateEnabled && this.supportProvider.getHuaweiCoordinator().supportsRealtimeHeartRate()) {
try {
return new FitnessData.EnableRealtimeHeartRate.Request(paramsProvider, automaticHeartRateEnabled).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
} else {
try {
return new FitnessData.EnableAutomaticHeartrate.Request(paramsProvider, automaticHeartRateEnabled).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
}
}
}

View File

@ -0,0 +1,37 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FitnessData;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class SetHeartRateHighAlert extends Request {
private static final Logger LOG = LoggerFactory.getLogger(SetHeartRateHighAlert.class);
public SetHeartRateHighAlert(HuaweiSupportProvider support) {
super(support);
this.serviceId = FitnessData.id;
this.commandId = FitnessData.HighHeartRateAlert.id;
this.addToResponse = false;
}
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
int highHeartRateAlert = Integer.parseInt(GBApplication
.getDeviceSpecificSharedPrefs(supportProvider.getDevice().getAddress())
.getString(HuaweiConstants.PREF_HUAWEI_HEART_RATE_HIGH_ALERT, "0"));
LOG.info("Attempting to sel high heart rate alert: {}", highHeartRateAlert);
try {
return new FitnessData.HighHeartRateAlert.Request(paramsProvider, highHeartRateAlert > 0, (byte) highHeartRateAlert).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
}
}

View File

@ -0,0 +1,37 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FitnessData;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class SetHeartRateLowAlert extends Request {
private static final Logger LOG = LoggerFactory.getLogger(SetHeartRateLowAlert.class);
public SetHeartRateLowAlert(HuaweiSupportProvider support) {
super(support);
this.serviceId = FitnessData.id;
this.commandId = FitnessData.LowHeartRateAlert.id;
this.addToResponse = false;
}
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
int lowHeartRateAlert = Integer.parseInt(GBApplication
.getDeviceSpecificSharedPrefs(supportProvider.getDevice().getAddress())
.getString(HuaweiConstants.PREF_HUAWEI_HEART_RATE_LOW_ALERT, "0"));
LOG.info("Attempting to set low heart rate alert: {}", lowHeartRateAlert);
try {
return new FitnessData.LowHeartRateAlert.Request(paramsProvider, lowHeartRateAlert > 0, (byte) lowHeartRateAlert).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
}
}

View File

@ -0,0 +1,37 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FitnessData;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class SetSpO2LowAlert extends Request {
private static final Logger LOG = LoggerFactory.getLogger(SetSpO2LowAlert.class);
public SetSpO2LowAlert(HuaweiSupportProvider support) {
super(support);
this.serviceId = FitnessData.id;
this.commandId = FitnessData.LowSpoAlert.id;
this.addToResponse = false;
}
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
int lowSpOAlert = Integer.parseInt(GBApplication
.getDeviceSpecificSharedPrefs(supportProvider.getDevice().getAddress())
.getString(HuaweiConstants.PREF_HUAWEI_SPO_LOW_ALERT, "0"));
LOG.info("Attempting to sel high spo alert: {}", lowSpOAlert);
try {
return new FitnessData.LowSpoAlert.Request(paramsProvider, lowSpOAlert > 0, (byte) lowSpOAlert).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
}
}

View File

@ -4509,4 +4509,57 @@
<item>transparency</item>
<item>off</item>
</string-array>
<string-array name="prefs_huawei_heart_rate_high_alert_names">
<item name="0">@string/off</item>
<item name="100">@string/heartrate_bpm_100</item>
<item name="110">@string/heartrate_bpm_110</item>
<item name="120">@string/heartrate_bpm_120</item>
<item name="130">@string/heartrate_bpm_130</item>
<item name="140">@string/heartrate_bpm_140</item>
<item name="150">@string/heartrate_bpm_150</item>
</string-array>
<string-array name="prefs_huawei_heart_rate_high_alert_values">
<item>0</item>
<item>100</item>
<item>110</item>
<item>120</item>
<item>130</item>
<item>140</item>
<item>150</item>
</string-array>
<string-array name="prefs_huawei_heart_rate_low_alert_names">
<item name="0">@string/off</item>
<item name="40">@string/heartrate_bpm_40</item>
<item name="45">@string/heartrate_bpm_45</item>
<item name="50">@string/heartrate_bpm_50</item>
</string-array>
<string-array name="prefs_huawei_heart_rate_low_alert_values">
<item>0</item>
<item>40</item>
<item>45</item>
<item>50</item>
</string-array>
<string-array name="prefs_huawei_spo_low_alert_names">
<item name="0">@string/spo2_off</item>
<item name="75">@string/spo2_perc_75</item>
<item name="80">@string/spo2_perc_80</item>
<item name="85">@string/spo2_perc_85</item>
<item name="90">@string/spo2_perc_90</item>
</string-array>
<string-array name="prefs_huawei_spo_low_alert_values">
<item>0</item>
<item>75</item>
<item>80</item>
<item>85</item>
<item>90</item>
</string-array>
</resources>

View File

@ -774,6 +774,7 @@
<string name="heartrate_bpm_185">185 bpm</string>
<string name="heartrate_bpm_195">195 bpm</string>
<string name="heartrate_bpm_205">205 bpm</string>
<string name="spo2_perc_75">75%</string>
<string name="spo2_perc_80">80%</string>
<string name="spo2_perc_85">85%</string>
<string name="spo2_perc_90">90%</string>
@ -3033,9 +3034,17 @@
<string name="pref_disable_find_phone_with_dnd">Disable find my phone when do not disturb is active</string>
<string name="pref_heartrate_automatic_enable">Enable automatic heartrate measuring</string>
<string name="pref_heartrate_automatic_enable">Enable automatic heart rate measuring</string>
<string name="pref_spo_automatic_enable">Enable automatic SpO2 measuring</string>
<string name="pref_heart_rate_realtime_mode">Real-time automatic heart rate measuring mode</string>
<string name="pref_heart_rate_realtime_mode_summary">If enabled, uses real-time mode, otherwise uses smart mode. This mode consume more power.</string>
<string name="pref_heart_rate_high_alert">High heart rate alert</string>
<string name="pref_heart_rate_low_alert">Low heart rate alert</string>
<string name="pref_spo_low_alert">Low SpO2 alert</string>
<string name="pref_force_options">Force options</string>
<string name="pref_force_options_summary">Some devices falsely claim not to have support for some options. This settings can be used to enable them anyway.\nUSE AT YOUR OWN RISK\nRead the wiki</string>
<string name="pref_force_smart_alarm">Force smart alarm</string>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:dependency="heartrate_automatic_enable"
android:entries="@array/prefs_huawei_heart_rate_high_alert_names"
android:entryValues="@array/prefs_huawei_heart_rate_high_alert_values"
android:icon="@drawable/ic_heartrate"
android:defaultValue="0"
android:key="pref_huawei_heart_rate_high_alert"
android:summary="%s"
android:title="@string/pref_heart_rate_high_alert" />
</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:dependency="heartrate_automatic_enable"
android:entries="@array/prefs_huawei_heart_rate_low_alert_names"
android:entryValues="@array/prefs_huawei_heart_rate_low_alert_values"
android:icon="@drawable/ic_heartrate"
android:defaultValue="0"
android:key="pref_huawei_heart_rate_low_alert"
android:summary="%s"
android:title="@string/pref_heart_rate_low_alert" />
</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreferenceCompat
android:defaultValue="false"
android:icon="@drawable/ic_heartrate"
android:dependency="heartrate_automatic_enable"
android:key="pref_huawei_heart_rate_realtime_mode"
android:layout="@layout/preference_checkbox"
android:title="@string/pref_heart_rate_realtime_mode"
android:summary="@string/pref_heart_rate_realtime_mode_summary"/>
</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:dependency="spo_automatic_enable"
android:entries="@array/prefs_huawei_spo_low_alert_names"
android:entryValues="@array/prefs_huawei_spo_low_alert_values"
android:icon="@drawable/ic_heart"
android:defaultValue="0"
android:key="pref_huawei_spo_low_alert"
android:summary="%s"
android:title="@string/pref_spo_low_alert" />
</androidx.preference.PreferenceScreen>