mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-10 17:11:56 +01:00
Colmi R0x: Add support for HRV
This commit is contained in:
parent
0a9da03618
commit
4939de47c1
@ -135,6 +135,7 @@ public class GBDaoGenerator {
|
||||
addColmiStressSample(schema, user, device);
|
||||
addColmiSleepSessionSample(schema, user, device);
|
||||
addColmiSleepStageSample(schema, user, device);
|
||||
addColmiHrvValueSample(schema, user, device);
|
||||
|
||||
addHuaweiActivitySample(schema, user, device);
|
||||
|
||||
@ -546,6 +547,13 @@ public class GBDaoGenerator {
|
||||
return sleepStageSample;
|
||||
}
|
||||
|
||||
private static Entity addColmiHrvValueSample(Schema schema, Entity user, Entity device) {
|
||||
Entity hrvValueSample = addEntity(schema, "ColmiHrvValueSample");
|
||||
addCommonTimeSampleProperties("AbstractHrvValueSample", hrvValueSample, user, device);
|
||||
hrvValueSample.addIntProperty("value").notNull().codeBeforeGetter(OVERRIDE);
|
||||
return hrvValueSample;
|
||||
}
|
||||
|
||||
private static void addHeartRateProperties(Entity activitySample) {
|
||||
activitySample.addIntProperty(SAMPLE_HEART_RATE).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
}
|
||||
|
@ -199,6 +199,7 @@ public class DeviceSettingsPreferenceConst {
|
||||
public static final String PREF_HEARTRATE_SLEEP_BREATHING_QUALITY_MONITORING = "heartrate_sleep_breathing_quality_monitoring";
|
||||
public static final String PREF_SPO2_ALL_DAY_MONITORING = "spo2_all_day_monitoring_enabled";
|
||||
public static final String PREF_SPO2_LOW_ALERT_THRESHOLD = "spo2_low_alert_threshold";
|
||||
public static final String PREF_HRV_ALL_DAY_MONITORING = "hrv_all_day_monitoring_enabled";
|
||||
|
||||
public static final String PREF_AUTOHEARTRATE_SWITCH = "pref_autoheartrate_switch";
|
||||
public static final String PREF_AUTOHEARTRATE_SLEEP = "pref_autoheartrate_sleep";
|
||||
|
@ -552,6 +552,7 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i
|
||||
addPreferenceHandlerFor(PREF_HEARTRATE_SLEEP_BREATHING_QUALITY_MONITORING);
|
||||
addPreferenceHandlerFor(PREF_SPO2_ALL_DAY_MONITORING);
|
||||
addPreferenceHandlerFor(PREF_SPO2_LOW_ALERT_THRESHOLD);
|
||||
addPreferenceHandlerFor(PREF_HRV_ALL_DAY_MONITORING);
|
||||
addPreferenceHandlerFor(PREF_DO_NOT_DISTURB_NOAUTO);
|
||||
addPreferenceHandlerFor(PREF_DO_NOT_DISTURB_NOAUTO_START);
|
||||
addPreferenceHandlerFor(PREF_DO_NOT_DISTURB_NOAUTO_END);
|
||||
|
@ -22,9 +22,12 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import de.greenrobot.dao.query.QueryBuilder;
|
||||
import de.greenrobot.dao.AbstractDao;
|
||||
import de.greenrobot.dao.Property;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings;
|
||||
@ -34,10 +37,12 @@ import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.colmi.samples.ColmiActivitySampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.colmi.samples.ColmiHrvValueSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.colmi.samples.ColmiSpo2SampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.colmi.samples.ColmiStressSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.ColmiActivitySampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.ColmiHeartRateSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.ColmiHrvValueSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.ColmiSleepSessionSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.ColmiSleepStageSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.ColmiSpo2SampleDao;
|
||||
@ -46,6 +51,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HrvValueSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Spo2Sample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.StressSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||
@ -56,21 +62,23 @@ public abstract class AbstractColmiR0xCoordinator extends AbstractBLEDeviceCoord
|
||||
|
||||
@Override
|
||||
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
|
||||
Long deviceId = device.getId();
|
||||
QueryBuilder<?> qb;
|
||||
final Long deviceId = device.getId();
|
||||
|
||||
qb = session.getColmiActivitySampleDao().queryBuilder();
|
||||
qb.where(ColmiActivitySampleDao.Properties.DeviceId.eq(deviceId)).buildDelete().executeDeleteWithoutDetachingEntities();
|
||||
qb = session.getColmiHeartRateSampleDao().queryBuilder();
|
||||
qb.where(ColmiHeartRateSampleDao.Properties.DeviceId.eq(deviceId)).buildDelete().executeDeleteWithoutDetachingEntities();
|
||||
qb = session.getColmiSpo2SampleDao().queryBuilder();
|
||||
qb.where(ColmiSpo2SampleDao.Properties.DeviceId.eq(deviceId)).buildDelete().executeDeleteWithoutDetachingEntities();
|
||||
qb = session.getColmiStressSampleDao().queryBuilder();
|
||||
qb.where(ColmiStressSampleDao.Properties.DeviceId.eq(deviceId)).buildDelete().executeDeleteWithoutDetachingEntities();
|
||||
qb = session.getColmiSleepSessionSampleDao().queryBuilder();
|
||||
qb.where(ColmiSleepSessionSampleDao.Properties.DeviceId.eq(deviceId)).buildDelete().executeDeleteWithoutDetachingEntities();
|
||||
qb = session.getColmiSleepStageSampleDao().queryBuilder();
|
||||
qb.where(ColmiSleepStageSampleDao.Properties.DeviceId.eq(deviceId)).buildDelete().executeDeleteWithoutDetachingEntities();
|
||||
final Map<AbstractDao<?, ?>, Property> daoMap = new HashMap<AbstractDao<?, ?>, Property>() {{
|
||||
put(session.getColmiActivitySampleDao(), ColmiActivitySampleDao.Properties.DeviceId);
|
||||
put(session.getColmiHeartRateSampleDao(), ColmiHeartRateSampleDao.Properties.DeviceId);
|
||||
put(session.getColmiSpo2SampleDao(), ColmiSpo2SampleDao.Properties.DeviceId);
|
||||
put(session.getColmiStressSampleDao(), ColmiStressSampleDao.Properties.DeviceId);
|
||||
put(session.getColmiSleepSessionSampleDao(), ColmiSleepSessionSampleDao.Properties.DeviceId);
|
||||
put(session.getColmiSleepStageSampleDao(), ColmiSleepStageSampleDao.Properties.DeviceId);
|
||||
put(session.getColmiHrvValueSampleDao(), ColmiHrvValueSampleDao.Properties.DeviceId);
|
||||
}};
|
||||
|
||||
for (final Map.Entry<AbstractDao<?, ?>, Property> e : daoMap.entrySet()) {
|
||||
e.getKey().queryBuilder()
|
||||
.where(e.getValue().eq(deviceId))
|
||||
.buildDelete().executeDeleteWithoutDetachingEntities();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -159,6 +167,11 @@ public abstract class AbstractColmiR0xCoordinator extends AbstractBLEDeviceCoord
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsHrvMeasurement() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleProvider<? extends ActivitySample> getSampleProvider(GBDevice device, DaoSession session) {
|
||||
return new ColmiActivitySampleProvider(device, session);
|
||||
@ -174,6 +187,11 @@ public abstract class AbstractColmiR0xCoordinator extends AbstractBLEDeviceCoord
|
||||
return new ColmiStressSampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends HrvValueSample> getHrvValueSampleProvider(final GBDevice device, final DaoSession session) {
|
||||
return new ColmiHrvValueSampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeartRateCapability.MeasurementInterval> getHeartRateMeasurementIntervals() {
|
||||
return Arrays.asList(
|
||||
|
@ -38,6 +38,8 @@ public class ColmiR0xConstants {
|
||||
public static final byte CMD_PACKET_SIZE = 0x2f;
|
||||
public static final byte CMD_AUTO_STRESS_PREF = 0x36;
|
||||
public static final byte CMD_SYNC_STRESS = 0x37;
|
||||
public static final byte CMD_AUTO_HRV_PREF = 0x38;
|
||||
public static final byte CMD_SYNC_HRV = 0x39;
|
||||
public static final byte CMD_SYNC_ACTIVITY = 0x43;
|
||||
public static final byte CMD_FIND_DEVICE = 0x50;
|
||||
public static final byte CMD_MANUAL_HEART_RATE = 0x69;
|
||||
|
@ -96,6 +96,17 @@ public class ColmiR0xPacketHandler {
|
||||
support.evaluateGBDeviceEvent(eventUpdatePreferences);
|
||||
}
|
||||
|
||||
public static void hrvSettings(ColmiR0xDeviceSupport support, byte[] value) {
|
||||
boolean enabled = value[2] == 0x01;
|
||||
LOG.info("Received HRV preference: {}", enabled ? "enabled" : "disabled");
|
||||
GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences();
|
||||
eventUpdatePreferences.withPreference(
|
||||
DeviceSettingsPreferenceConst.PREF_HRV_ALL_DAY_MONITORING,
|
||||
enabled
|
||||
);
|
||||
support.evaluateGBDeviceEvent(eventUpdatePreferences);
|
||||
}
|
||||
|
||||
public static void goalsSettings(byte[] value) {
|
||||
int steps = BLETypeConversions.toUint32(value[2], value[3], value[4], (byte) 0);
|
||||
int calories = BLETypeConversions.toUint32(value[5], value[6], value[7], (byte) 0);
|
||||
@ -410,4 +421,8 @@ public class ColmiR0xPacketHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void historicalHRV(GBDevice device, Context context, byte[] value) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,56 @@
|
||||
/* Copyright (C) 2024 Arjan Schrijver
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.colmi.samples;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import de.greenrobot.dao.AbstractDao;
|
||||
import de.greenrobot.dao.Property;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractTimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.ColmiHrvValueSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.ColmiHrvValueSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
|
||||
public class ColmiHrvValueSampleProvider extends AbstractTimeSampleProvider<ColmiHrvValueSample> {
|
||||
public ColmiHrvValueSampleProvider(final GBDevice device, final DaoSession session) {
|
||||
super(device, session);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AbstractDao<ColmiHrvValueSample, ?> getSampleDao() {
|
||||
return getSession().getColmiHrvValueSampleDao();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Property getTimestampSampleProperty() {
|
||||
return ColmiHrvValueSampleDao.Properties.Timestamp;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Property getDeviceIdentifierSampleProperty() {
|
||||
return ColmiHrvValueSampleDao.Properties.DeviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColmiHrvValueSample createSample() {
|
||||
return new ColmiHrvValueSample();
|
||||
}
|
||||
}
|
@ -91,15 +91,6 @@ public class ColmiR0xDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
deviceInfoProfile = new DeviceInfoProfile<>(this);
|
||||
deviceInfoProfile.addListener(mListener);
|
||||
addSupportedProfile(deviceInfoProfile);
|
||||
|
||||
// try (DBHandler db = GBApplication.acquireDB()) {
|
||||
// db.getDatabase().execSQL("DROP TABLE IF EXISTS 'COLMI_ACTIVITY_SAMPLE'");
|
||||
// db.getDatabase().execSQL("DROP TABLE IF EXISTS 'COLMI_HEART_RATE_SAMPLE'");
|
||||
// db.getDatabase().execSQL("DROP TABLE IF EXISTS 'COLMI_SPO2_SAMPLE'");
|
||||
// db.getDatabase().execSQL("DROP TABLE IF EXISTS 'COLMI_STRESS_SAMPLE'");
|
||||
// } catch (Exception e) {
|
||||
// LOG.error("Error acquiring database", e);
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -277,6 +268,9 @@ public class ColmiR0xDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
case ColmiR0xConstants.CMD_AUTO_STRESS_PREF:
|
||||
ColmiR0xPacketHandler.stressSettings(this, value);
|
||||
break;
|
||||
case ColmiR0xConstants.CMD_AUTO_HRV_PREF:
|
||||
ColmiR0xPacketHandler.hrvSettings(this, value);
|
||||
break;
|
||||
case ColmiR0xConstants.CMD_SYNC_STRESS:
|
||||
ColmiR0xPacketHandler.historicalStress(getDevice(), getContext(), value);
|
||||
if (!getDevice().isBusy()) {
|
||||
@ -295,6 +289,9 @@ public class ColmiR0xDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ColmiR0xConstants.CMD_SYNC_HRV:
|
||||
ColmiR0xPacketHandler.historicalHRV(getDevice(), getContext(), value);
|
||||
break;
|
||||
case ColmiR0xConstants.CMD_FIND_DEVICE:
|
||||
LOG.info("Received find device response: {}", StringUtils.bytesToHex(value));
|
||||
break;
|
||||
@ -367,6 +364,9 @@ public class ColmiR0xDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
switch (value[1]) {
|
||||
case ColmiR0xConstants.BIG_DATA_TYPE_SLEEP:
|
||||
ColmiR0xPacketHandler.historicalSleep(getDevice(), getContext(), value);
|
||||
fetchHistoryHRV();
|
||||
// Signal history sync finished at this point, since older firmwares
|
||||
// will not send anything back after requesting HRV history
|
||||
fetchRecordedDataFinished();
|
||||
break;
|
||||
case ColmiR0xConstants.BIG_DATA_TYPE_SPO2:
|
||||
@ -478,6 +478,12 @@ public class ColmiR0xDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
LOG.info("Stress preference request sent: {}", StringUtils.bytesToHex(stressPrefsPacket));
|
||||
sendWrite("stressPreferenceRequest", stressPrefsPacket);
|
||||
break;
|
||||
case DeviceSettingsPreferenceConst.PREF_HRV_ALL_DAY_MONITORING:
|
||||
final boolean hrvEnabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_HRV_ALL_DAY_MONITORING, false);
|
||||
byte[] hrvPrefsPacket = buildPacket(new byte[]{ColmiR0xConstants.CMD_AUTO_HRV_PREF, ColmiR0xConstants.PREF_WRITE, (byte) (hrvEnabled ? 0x01 : 0x00)});
|
||||
LOG.info("HRV preference request sent: {}", StringUtils.bytesToHex(hrvPrefsPacket));
|
||||
sendWrite("hrvPreferenceRequest", hrvPrefsPacket);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -538,6 +544,9 @@ public class ColmiR0xDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
request = buildPacket(new byte[]{ColmiR0xConstants.CMD_AUTO_SPO2_PREF, ColmiR0xConstants.PREF_READ});
|
||||
LOG.info("Request SpO2 measurement setting from ring: {}", StringUtils.bytesToHex(request));
|
||||
sendWrite("spo2SettingRequest", request);
|
||||
request = buildPacket(new byte[]{ColmiR0xConstants.CMD_AUTO_HRV_PREF, ColmiR0xConstants.PREF_READ});
|
||||
LOG.info("Request HRV measurement setting from ring: {}", StringUtils.bytesToHex(request));
|
||||
sendWrite("hrvSettingRequest", request);
|
||||
request = buildPacket(new byte[]{ColmiR0xConstants.CMD_GOALS, ColmiR0xConstants.PREF_READ});
|
||||
LOG.info("Request goals from ring: {}", StringUtils.bytesToHex(request));
|
||||
sendWrite("goalsSettingRequest", request);
|
||||
@ -664,4 +673,13 @@ public class ColmiR0xDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
LOG.info("Fetch historical sleep data request sent: {}", StringUtils.bytesToHex(sleepHistoryRequest));
|
||||
sendCommand("sleepHistoryRequest", sleepHistoryRequest);
|
||||
}
|
||||
|
||||
private void fetchHistoryHRV() {
|
||||
getDevice().setBusyTask(getContext().getString(R.string.busy_task_fetch_hrv_data));
|
||||
getDevice().sendDeviceUpdateIntent(getContext());
|
||||
syncingDay = Calendar.getInstance();
|
||||
byte[] hrvHistoryRequest = buildPacket(new byte[]{ColmiR0xConstants.CMD_SYNC_HRV});
|
||||
LOG.info("Fetch historical HRV data request sent: {}", StringUtils.bytesToHex(hrvHistoryRequest));
|
||||
sendWrite("hrvHistoryRequest", hrvHistoryRequest);
|
||||
}
|
||||
}
|
||||
|
9
app/src/main/res/drawable/baseline_bloodtype_24.xml
Normal file
9
app/src/main/res/drawable/baseline_bloodtype_24.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#7E7E7E"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
|
||||
<path android:fillColor="#000000" android:pathData="M12,2c-5.33,4.55 -8,8.48 -8,11.8c0,4.98 3.8,8.2 8,8.2s8,-3.22 8,-8.2C20,10.48 17.33,6.55 12,2zM15,18H9v-2h6V18zM15,13h-2v2h-2v-2H9v-2h2V9h2v2h2V13z"/>
|
||||
</vector>
|
@ -693,6 +693,7 @@
|
||||
<string name="busy_task_fetch_stress_data">Fetching stress data</string>
|
||||
<string name="busy_task_fetch_pai_data">Fetching PAI data</string>
|
||||
<string name="busy_task_fetch_spo2_data">Fetching SpO2 data</string>
|
||||
<string name="busy_task_fetch_hrv_data">Fetching HRV data</string>
|
||||
<string name="busy_task_fetch_hr_data">Fetching heart rate data</string>
|
||||
<string name="busy_task_fetch_sleep_data">Fetching sleep data</string>
|
||||
<string name="busy_task_fetch_sleep_respiratory_rate_data">Fetching sleep respiratory rate data</string>
|
||||
@ -3355,4 +3356,10 @@
|
||||
<string name="pref_dashboard_widget_today_yesterday_data_summary">Show data from yesterday dimmed between the current time and midnight</string>
|
||||
<string name="pref_dashboard_widget_today_time_indicator_title">Current time indicator</string>
|
||||
<string name="pref_dashboard_widget_today_time_indicator_summary">Show an indicator at the current time, to visually separate data from yesterday and today</string>
|
||||
<string name="pref_dnd_follow_phone_title">Follow phone DND setting</string>
|
||||
<string name="pref_dnd_follow_phone_summary">When DND is enabled or disabled on the phone, automatically toggle it on the device too</string>
|
||||
<string name="inactivity_warnings_minimum_steps_title">Minimum amount of steps</string>
|
||||
<string name="inactivity_warnings_minimum_steps_summary">Minimum amount of steps that need to be taken during the threshold minutes</string>
|
||||
<string name="prefs_hrv_monitoring_title">HRV monitoring</string>
|
||||
<string name="prefs_hrv_monitoring_description">Automatically monitor heart rate variability throughout the day</string>
|
||||
</resources>
|
||||
|
@ -1,24 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<ListPreference
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/prefs_heartrate_measurement_interval"
|
||||
android:entryValues="@array/prefs_heartrate_measurement_interval_values"
|
||||
android:icon="@drawable/ic_heartrate"
|
||||
android:key="heartrate_measurement_interval"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_title_heartrate_measurement_interval" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_mood_bad"
|
||||
android:key="heartrate_stress_monitoring"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/prefs_stress_monitoring_description"
|
||||
android:title="@string/prefs_stress_monitoring_title" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="spo2_all_day_monitoring_enabled"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/prefs_spo2_monitoring_description"
|
||||
android:title="@string/prefs_spo2_monitoring_title" />
|
||||
<ListPreference
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/prefs_heartrate_measurement_interval"
|
||||
android:entryValues="@array/prefs_heartrate_measurement_interval_values"
|
||||
android:icon="@drawable/ic_heartrate"
|
||||
android:key="heartrate_measurement_interval"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_title_heartrate_measurement_interval" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_mood_bad"
|
||||
android:key="heartrate_stress_monitoring"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/prefs_stress_monitoring_description"
|
||||
android:title="@string/prefs_stress_monitoring_title" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/baseline_bloodtype_24"
|
||||
android:key="spo2_all_day_monitoring_enabled"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/prefs_spo2_monitoring_description"
|
||||
android:title="@string/prefs_spo2_monitoring_title" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_show_chart"
|
||||
android:key="hrv_all_day_monitoring_enabled"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/prefs_hrv_monitoring_description"
|
||||
android:title="@string/prefs_hrv_monitoring_title" />
|
||||
</androidx.preference.PreferenceScreen>
|
||||
|
Loading…
Reference in New Issue
Block a user