mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-27 12:26:48 +01:00
Zepp OS: Add support for morning updates
This commit is contained in:
parent
4713c6511e
commit
f1dd4019bf
@ -2,19 +2,20 @@
|
||||
|
||||
#### Next Version
|
||||
|
||||
* Add Croatian transliterator
|
||||
* Amazfit Bip U: Remove alarm snooze option
|
||||
* Amazfit GTR 4 / GTS 4: Add watch Wi-Fi Hotspot and FTP Server
|
||||
* Amazfit GTR 4: Whitelist fw 3.18.1.1 diff from 3.17.0.2
|
||||
* Amazfit GTS 2 Mini: Add missing alexa menu item
|
||||
* Bangle.js: Fix updating timezone in settings.json if the timezone is zero
|
||||
* Fix restoring app notification/pebble blacklist preferences on import
|
||||
* Huami: Implement repeated activity fetching
|
||||
* Sony WH-1000XM4: Add speak-to-chat
|
||||
* Zepp OS: Add config to keep screen on during workout
|
||||
* Zepp OS: Add support for morning updates
|
||||
* Zepp OS: Add preference to keep screen on during workout
|
||||
* Zepp OS: Add preference for camera remote
|
||||
* Zepp OS: Fix activate display upon lift wrist smart mode
|
||||
* Zepp OS: Fix setting of unknown configuration values
|
||||
* Add Croatian transliterator
|
||||
* Fix restoring app notification/pebble blacklist preferences on import
|
||||
|
||||
#### 0.73.0
|
||||
* Initial support for Amazfit T-Rex 2
|
||||
|
@ -41,6 +41,7 @@ public class DeviceSettingsPreferenceConst {
|
||||
public static final String PREF_SCREEN_OFFLINE_VOICE = "pref_screen_offline_voice";
|
||||
public static final String PREF_SCREEN_WIFI_HOTSPOT = "pref_screen_wifi_hotspot";
|
||||
public static final String PREF_SCREEN_FTP_SERVER = "pref_screen_ftp_server";
|
||||
public static final String PREF_SCREEN_MORNING_UPDATES = "pref_morning_updates";
|
||||
|
||||
public static final String PREF_LANGUAGE = "language";
|
||||
public static final String PREF_LANGUAGE_AUTO = "auto";
|
||||
@ -240,6 +241,9 @@ public class DeviceSettingsPreferenceConst {
|
||||
public static final String WIFI_HOTSPOT_STOP = "wifi_hotspot_stop";
|
||||
public static final String WIFI_HOTSPOT_STATUS = "wifi_hotspot_status";
|
||||
|
||||
public static final String MORNING_UPDATES_ENABLED = "morning_updates_enabled";
|
||||
public static final String MORNING_UPDATES_CATEGORIES_SORTABLE = "morning_updates_categories";
|
||||
|
||||
public static final String FTP_SERVER_ROOT_DIR = "ftp_server_root_dir";
|
||||
public static final String FTP_SERVER_ADDRESS = "ftp_server_address";
|
||||
public static final String FTP_SERVER_USERNAME = "ftp_server_username";
|
||||
|
@ -494,6 +494,9 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp
|
||||
addPreferenceHandlerFor(PREF_GALAXY_BUDS_TOUCH_LEFT_SWITCH);
|
||||
addPreferenceHandlerFor(PREF_GALAXY_BUDS_TOUCH_RIGHT_SWITCH);
|
||||
|
||||
addPreferenceHandlerFor(MORNING_UPDATES_ENABLED);
|
||||
addPreferenceHandlerFor(MORNING_UPDATES_CATEGORIES_SORTABLE);
|
||||
|
||||
addPreferenceHandlerFor(PREF_SONY_AMBIENT_SOUND_CONTROL);
|
||||
addPreferenceHandlerFor(PREF_SONY_AMBIENT_SOUND_CONTROL_BUTTON_MODE);
|
||||
addPreferenceHandlerFor(PREF_SONY_FOCUS_VOICE);
|
||||
|
@ -26,6 +26,7 @@ import org.apache.commons.lang3.ArrayUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
|
||||
@ -44,6 +45,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsConfigService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiLanguageType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
public abstract class Huami2021Coordinator extends HuamiCoordinator {
|
||||
@Override
|
||||
@ -253,6 +255,7 @@ public abstract class Huami2021Coordinator extends HuamiCoordinator {
|
||||
settings.add(R.xml.devicesettings_buttonactions_lower_short);
|
||||
settings.add(R.xml.devicesettings_weardirection);
|
||||
settings.add(R.xml.devicesettings_camera_remote);
|
||||
settings.add(R.xml.devicesettings_morning_updates);
|
||||
|
||||
//
|
||||
// Connection
|
||||
@ -362,4 +365,22 @@ public abstract class Huami2021Coordinator extends HuamiCoordinator {
|
||||
private boolean supportsConfig(final GBDevice device, final ZeppOsConfigService.ConfigArg config) {
|
||||
return ZeppOsConfigService.deviceHasConfig(getPrefs(device), config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preference key where to save the list of possible value for a preference, comma-separated.
|
||||
*/
|
||||
public static String getPrefPossibleValuesKey(final String key) {
|
||||
return String.format(Locale.ROOT, "%s_huami_2021_possible_values", key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preference key where to that a config was reported as supported (boolean).
|
||||
*/
|
||||
public static String getPrefKnownConfig(final String key) {
|
||||
return String.format(Locale.ROOT, "huami_2021_known_config_%s", key);
|
||||
}
|
||||
|
||||
public static boolean deviceHasConfig(final Prefs devicePrefs, final ZeppOsConfigService.ConfigArg config) {
|
||||
return devicePrefs.getBoolean(Huami2021Coordinator.getPrefKnownConfig(config.name()), false);
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ public class Huami2021SettingsCustomizer extends HuamiSettingsCustomizer {
|
||||
removeUnsupportedElementsFromListPreference(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE, handler, prefs);
|
||||
removeUnsupportedElementsFromListPreference(HuamiConst.PREF_SHORTCUTS_SORTABLE, handler, prefs);
|
||||
removeUnsupportedElementsFromListPreference(HuamiConst.PREF_CONTROL_CENTER_SORTABLE, handler, prefs);
|
||||
removeUnsupportedElementsFromListPreference(DeviceSettingsPreferenceConst.MORNING_UPDATES_CATEGORIES_SORTABLE, handler, prefs);
|
||||
|
||||
for (final ZeppOsConfigService.ConfigArg config : ZeppOsConfigService.ConfigArg.values()) {
|
||||
if (config.getPrefKey() == null) {
|
||||
@ -78,102 +79,106 @@ public class Huami2021SettingsCustomizer extends HuamiSettingsCustomizer {
|
||||
case TIMESTAMP_MILLIS:
|
||||
default:
|
||||
// For other preferences, just hide them if they were not reported as supported by the device
|
||||
hidePrefIfNoConfigSupported(handler, prefs, config.getPrefKey(), config);
|
||||
hidePrefIfNoConfigSupported(handler, prefs, config.getPrefKey(), config.name());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide all config groups that may not be mapped directly to a preference
|
||||
final Map<String, List<ZeppOsConfigService.ConfigArg>> configScreens = new HashMap<String, List<ZeppOsConfigService.ConfigArg>>() {{
|
||||
final Map<String, List<String>> configScreens = new HashMap<String, List<String>>() {{
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_NIGHT_MODE, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.NIGHT_MODE_MODE,
|
||||
ZeppOsConfigService.ConfigArg.NIGHT_MODE_SCHEDULED_START,
|
||||
ZeppOsConfigService.ConfigArg.NIGHT_MODE_SCHEDULED_END
|
||||
ZeppOsConfigService.ConfigArg.NIGHT_MODE_MODE.name(),
|
||||
ZeppOsConfigService.ConfigArg.NIGHT_MODE_SCHEDULED_START.name(),
|
||||
ZeppOsConfigService.ConfigArg.NIGHT_MODE_SCHEDULED_END.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_SLEEP_MODE, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.SLEEP_MODE_SLEEP_SCREEN,
|
||||
ZeppOsConfigService.ConfigArg.SLEEP_MODE_SMART_ENABLE
|
||||
ZeppOsConfigService.ConfigArg.SLEEP_MODE_SLEEP_SCREEN.name(),
|
||||
ZeppOsConfigService.ConfigArg.SLEEP_MODE_SMART_ENABLE.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_LIFT_WRIST, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.LIFT_WRIST_MODE,
|
||||
ZeppOsConfigService.ConfigArg.LIFT_WRIST_SCHEDULED_START,
|
||||
ZeppOsConfigService.ConfigArg.LIFT_WRIST_SCHEDULED_END,
|
||||
ZeppOsConfigService.ConfigArg.LIFT_WRIST_RESPONSE_SENSITIVITY
|
||||
ZeppOsConfigService.ConfigArg.LIFT_WRIST_MODE.name(),
|
||||
ZeppOsConfigService.ConfigArg.LIFT_WRIST_SCHEDULED_START.name(),
|
||||
ZeppOsConfigService.ConfigArg.LIFT_WRIST_SCHEDULED_END.name(),
|
||||
ZeppOsConfigService.ConfigArg.LIFT_WRIST_RESPONSE_SENSITIVITY.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_PASSWORD, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.PASSWORD_ENABLED,
|
||||
ZeppOsConfigService.ConfigArg.PASSWORD_TEXT
|
||||
ZeppOsConfigService.ConfigArg.PASSWORD_ENABLED.name(),
|
||||
ZeppOsConfigService.ConfigArg.PASSWORD_TEXT.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_ALWAYS_ON_DISPLAY, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_MODE,
|
||||
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_SCHEDULED_START,
|
||||
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_SCHEDULED_END,
|
||||
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_FOLLOW_WATCHFACE,
|
||||
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_STYLE
|
||||
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_MODE.name(),
|
||||
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_SCHEDULED_START.name(),
|
||||
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_SCHEDULED_END.name(),
|
||||
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_FOLLOW_WATCHFACE.name(),
|
||||
ZeppOsConfigService.ConfigArg.ALWAYS_ON_DISPLAY_STYLE.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_AUTO_BRIGHTNESS, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.SCREEN_AUTO_BRIGHTNESS
|
||||
ZeppOsConfigService.ConfigArg.SCREEN_AUTO_BRIGHTNESS.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_HEARTRATE_MONITORING, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.HEART_RATE_ALL_DAY_MONITORING,
|
||||
ZeppOsConfigService.ConfigArg.HEART_RATE_HIGH_ALERTS,
|
||||
ZeppOsConfigService.ConfigArg.HEART_RATE_LOW_ALERTS,
|
||||
ZeppOsConfigService.ConfigArg.HEART_RATE_ACTIVITY_MONITORING,
|
||||
ZeppOsConfigService.ConfigArg.SLEEP_HIGH_ACCURACY_MONITORING,
|
||||
ZeppOsConfigService.ConfigArg.SLEEP_BREATHING_QUALITY_MONITORING,
|
||||
ZeppOsConfigService.ConfigArg.STRESS_MONITORING,
|
||||
ZeppOsConfigService.ConfigArg.STRESS_RELAXATION_REMINDER,
|
||||
ZeppOsConfigService.ConfigArg.SPO2_ALL_DAY_MONITORING,
|
||||
ZeppOsConfigService.ConfigArg.SPO2_LOW_ALERT
|
||||
ZeppOsConfigService.ConfigArg.HEART_RATE_ALL_DAY_MONITORING.name(),
|
||||
ZeppOsConfigService.ConfigArg.HEART_RATE_HIGH_ALERTS.name(),
|
||||
ZeppOsConfigService.ConfigArg.HEART_RATE_LOW_ALERTS.name(),
|
||||
ZeppOsConfigService.ConfigArg.HEART_RATE_ACTIVITY_MONITORING.name(),
|
||||
ZeppOsConfigService.ConfigArg.SLEEP_HIGH_ACCURACY_MONITORING.name(),
|
||||
ZeppOsConfigService.ConfigArg.SLEEP_BREATHING_QUALITY_MONITORING.name(),
|
||||
ZeppOsConfigService.ConfigArg.STRESS_MONITORING.name(),
|
||||
ZeppOsConfigService.ConfigArg.STRESS_RELAXATION_REMINDER.name(),
|
||||
ZeppOsConfigService.ConfigArg.SPO2_ALL_DAY_MONITORING.name(),
|
||||
ZeppOsConfigService.ConfigArg.SPO2_LOW_ALERT.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_INACTIVITY_EXTENDED, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_ENABLED,
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_SCHEDULED_START,
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_SCHEDULED_END,
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_DND_ENABLED,
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_DND_SCHEDULED_START,
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_DND_SCHEDULED_END
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_ENABLED.name(),
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_SCHEDULED_START.name(),
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_SCHEDULED_END.name(),
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_DND_ENABLED.name(),
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_DND_SCHEDULED_START.name(),
|
||||
ZeppOsConfigService.ConfigArg.INACTIVITY_WARNINGS_DND_SCHEDULED_END.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_HEADER_GPS, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_PRESET,
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_BAND,
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_COMBINATION,
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_SATELLITE_SEARCH,
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_AGPS_EXPIRY_REMINDER_ENABLED,
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_AGPS_EXPIRY_REMINDER_TIME
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_PRESET.name(),
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_BAND.name(),
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_COMBINATION.name(),
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_GPS_SATELLITE_SEARCH.name(),
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_AGPS_EXPIRY_REMINDER_ENABLED.name(),
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_AGPS_EXPIRY_REMINDER_TIME.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_SOUND_AND_VIBRATION, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.VOLUME,
|
||||
ZeppOsConfigService.ConfigArg.CROWN_VIBRATION,
|
||||
ZeppOsConfigService.ConfigArg.ALERT_TONE,
|
||||
ZeppOsConfigService.ConfigArg.COVER_TO_MUTE,
|
||||
ZeppOsConfigService.ConfigArg.VIBRATE_FOR_ALERT,
|
||||
ZeppOsConfigService.ConfigArg.TEXT_TO_SPEECH
|
||||
ZeppOsConfigService.ConfigArg.VOLUME.name(),
|
||||
ZeppOsConfigService.ConfigArg.CROWN_VIBRATION.name(),
|
||||
ZeppOsConfigService.ConfigArg.ALERT_TONE.name(),
|
||||
ZeppOsConfigService.ConfigArg.COVER_TO_MUTE.name(),
|
||||
ZeppOsConfigService.ConfigArg.VIBRATE_FOR_ALERT.name(),
|
||||
ZeppOsConfigService.ConfigArg.TEXT_TO_SPEECH.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_DO_NOT_DISTURB, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.DND_MODE,
|
||||
ZeppOsConfigService.ConfigArg.DND_SCHEDULED_START,
|
||||
ZeppOsConfigService.ConfigArg.DND_SCHEDULED_END
|
||||
ZeppOsConfigService.ConfigArg.DND_MODE.name(),
|
||||
ZeppOsConfigService.ConfigArg.DND_SCHEDULED_START.name(),
|
||||
ZeppOsConfigService.ConfigArg.DND_SCHEDULED_END.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_HEADER_WORKOUT_DETECTION, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_DETECTION_CATEGORY,
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_DETECTION_ALERT,
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_DETECTION_SENSITIVITY
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_DETECTION_CATEGORY.name(),
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_DETECTION_ALERT.name(),
|
||||
ZeppOsConfigService.ConfigArg.WORKOUT_DETECTION_SENSITIVITY.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_OFFLINE_VOICE, Arrays.asList(
|
||||
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_RESPOND_TURN_WRIST,
|
||||
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_RESPOND_SCREEN_ON,
|
||||
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_RESPONSE_DURING_SCREEN_LIGHTING,
|
||||
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_LANGUAGE
|
||||
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_RESPOND_TURN_WRIST.name(),
|
||||
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_RESPOND_SCREEN_ON.name(),
|
||||
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_RESPONSE_DURING_SCREEN_LIGHTING.name(),
|
||||
ZeppOsConfigService.ConfigArg.OFFLINE_VOICE_LANGUAGE.name()
|
||||
));
|
||||
put(DeviceSettingsPreferenceConst.PREF_SCREEN_MORNING_UPDATES, Arrays.asList(
|
||||
DeviceSettingsPreferenceConst.MORNING_UPDATES_ENABLED,
|
||||
DeviceSettingsPreferenceConst.MORNING_UPDATES_CATEGORIES_SORTABLE
|
||||
));
|
||||
}};
|
||||
|
||||
for (final Map.Entry<String, List<ZeppOsConfigService.ConfigArg>> configScreen : configScreens.entrySet()) {
|
||||
for (final Map.Entry<String, List<String>> configScreen : configScreens.entrySet()) {
|
||||
hidePrefIfNoConfigSupported(
|
||||
handler,
|
||||
prefs,
|
||||
configScreen.getKey(),
|
||||
configScreen.getValue().toArray(new ZeppOsConfigService.ConfigArg[0])
|
||||
configScreen.getValue().toArray(new String[0])
|
||||
);
|
||||
}
|
||||
|
||||
@ -368,7 +373,7 @@ public class Huami2021SettingsCustomizer extends HuamiSettingsCustomizer {
|
||||
}
|
||||
|
||||
// Get the list of possible values for this preference, as reported by the band
|
||||
final List<String> possibleValues = prefs.getList(ZeppOsConfigService.getPrefPossibleValuesKey(prefKey), null);
|
||||
final List<String> possibleValues = prefs.getList(Huami2021Coordinator.getPrefPossibleValuesKey(prefKey), null);
|
||||
if (possibleValues == null || possibleValues.isEmpty()) {
|
||||
// The band hasn't reported this setting, so we don't know the possible values.
|
||||
// Hide it
|
||||
@ -425,14 +430,15 @@ public class Huami2021SettingsCustomizer extends HuamiSettingsCustomizer {
|
||||
private void hidePrefIfNoConfigSupported(final DeviceSpecificSettingsHandler handler,
|
||||
final Prefs prefs,
|
||||
final String prefToHide,
|
||||
final ZeppOsConfigService.ConfigArg... configs) {
|
||||
final String... supportedPref) {
|
||||
final Preference pref = handler.findPreference(prefToHide);
|
||||
if (pref == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final ZeppOsConfigService.ConfigArg config : configs) {
|
||||
if (ZeppOsConfigService.deviceHasConfig(prefs, config)) {
|
||||
for (final String prefKey : supportedPref) {
|
||||
final boolean deviceHasConfig = prefs.getBoolean(Huami2021Coordinator.getPrefKnownConfig(prefKey), false);
|
||||
if (deviceHasConfig) {
|
||||
// This preference is supported, don't hide
|
||||
return;
|
||||
}
|
||||
|
@ -123,6 +123,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.service
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsContactsService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsFileUploadService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsFtpServerService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsMorningUpdatesService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsWifiService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.BitmapUtil;
|
||||
@ -153,6 +154,8 @@ public abstract class Huami2021Support extends HuamiSupport {
|
||||
private final ZeppOsWifiService wifiService = new ZeppOsWifiService(this);
|
||||
private final ZeppOsFtpServerService ftpServerService = new ZeppOsFtpServerService(this);
|
||||
private final ZeppOsContactsService contactsService = new ZeppOsContactsService(this);
|
||||
private final ZeppOsMorningUpdatesService morningUpdatesService = new ZeppOsMorningUpdatesService(this);
|
||||
|
||||
private final Map<Short, AbstractZeppOsService> mServiceMap = new HashMap<Short, AbstractZeppOsService>() {{
|
||||
put(fileUploadService.getEndpoint(), fileUploadService);
|
||||
put(configService.getEndpoint(), configService);
|
||||
@ -160,6 +163,7 @@ public abstract class Huami2021Support extends HuamiSupport {
|
||||
put(wifiService.getEndpoint(), wifiService);
|
||||
put(ftpServerService.getEndpoint(), ftpServerService);
|
||||
put(contactsService.getEndpoint(), contactsService);
|
||||
put(morningUpdatesService.getEndpoint(), morningUpdatesService);
|
||||
}};
|
||||
|
||||
public Huami2021Support() {
|
||||
@ -231,6 +235,21 @@ public abstract class Huami2021Support extends HuamiSupport {
|
||||
return;
|
||||
}
|
||||
|
||||
// morning updates preferences, they do not use the configService
|
||||
switch (config) {
|
||||
case DeviceSettingsPreferenceConst.MORNING_UPDATES_ENABLED:
|
||||
final boolean morningUpdatesEnabled = prefs.getBoolean(config, false);
|
||||
LOG.info("Setting morning updates enabled = {}", morningUpdatesEnabled);
|
||||
morningUpdatesService.setEnabled(morningUpdatesEnabled);
|
||||
return;
|
||||
case DeviceSettingsPreferenceConst.MORNING_UPDATES_CATEGORIES_SORTABLE:
|
||||
final List<String> categories = new ArrayList<>(prefs.getList(config, Collections.emptyList()));
|
||||
final List<String> allCategories = new ArrayList<>(prefs.getList(Huami2021Coordinator.getPrefPossibleValuesKey(config), Collections.emptyList()));
|
||||
LOG.info("Setting morning updates categories = {}", categories);
|
||||
morningUpdatesService.setCategories(categories, allCategories);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (configService.setConfig(prefs, config, configSetter)) {
|
||||
// If the ConfigSetter was able to set the config, just write it and return
|
||||
@ -1134,7 +1153,7 @@ public abstract class Huami2021Support extends HuamiSupport {
|
||||
setDisplayItems2021(
|
||||
builder,
|
||||
DISPLAY_ITEMS_MENU,
|
||||
new ArrayList<>(prefs.getList(ZeppOsConfigService.getPrefPossibleValuesKey(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE), Collections.emptyList())),
|
||||
new ArrayList<>(prefs.getList(Huami2021Coordinator.getPrefPossibleValuesKey(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE), Collections.emptyList())),
|
||||
new ArrayList<>(prefs.getList(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE, Collections.emptyList()))
|
||||
);
|
||||
return this;
|
||||
@ -1147,7 +1166,7 @@ public abstract class Huami2021Support extends HuamiSupport {
|
||||
setDisplayItems2021(
|
||||
builder,
|
||||
DISPLAY_ITEMS_SHORTCUTS,
|
||||
new ArrayList<>(prefs.getList(ZeppOsConfigService.getPrefPossibleValuesKey(HuamiConst.PREF_SHORTCUTS_SORTABLE), Collections.emptyList())),
|
||||
new ArrayList<>(prefs.getList(Huami2021Coordinator.getPrefPossibleValuesKey(HuamiConst.PREF_SHORTCUTS_SORTABLE), Collections.emptyList())),
|
||||
new ArrayList<>(prefs.getList(HuamiConst.PREF_SHORTCUTS_SORTABLE, Collections.emptyList()))
|
||||
);
|
||||
return this;
|
||||
@ -1159,7 +1178,7 @@ public abstract class Huami2021Support extends HuamiSupport {
|
||||
setDisplayItems2021(
|
||||
builder,
|
||||
DISPLAY_ITEMS_CONTROL_CENTER,
|
||||
new ArrayList<>(prefs.getList(ZeppOsConfigService.getPrefPossibleValuesKey(HuamiConst.PREF_CONTROL_CENTER_SORTABLE), Collections.emptyList())),
|
||||
new ArrayList<>(prefs.getList(Huami2021Coordinator.getPrefPossibleValuesKey(HuamiConst.PREF_CONTROL_CENTER_SORTABLE), Collections.emptyList())),
|
||||
new ArrayList<>(prefs.getList(HuamiConst.PREF_CONTROL_CENTER_SORTABLE, Collections.emptyList()))
|
||||
);
|
||||
return this;
|
||||
@ -1465,6 +1484,8 @@ public abstract class Huami2021Support extends HuamiSupport {
|
||||
requestAlarms(builder);
|
||||
//requestReminders(builder);
|
||||
//contactsService.requestCapabilities(builder);
|
||||
morningUpdatesService.getEnabled(builder);
|
||||
morningUpdatesService.getCategories(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1813,7 +1834,7 @@ public abstract class Huami2021Support extends HuamiSupport {
|
||||
LOG.error("Unknown display items type {}", String.format("0x%x", payload[1]));
|
||||
return;
|
||||
}
|
||||
final String allScreensPrefKey = ZeppOsConfigService.getPrefPossibleValuesKey(prefKey);
|
||||
final String allScreensPrefKey = Huami2021Coordinator.getPrefPossibleValuesKey(prefKey);
|
||||
|
||||
final boolean menuHasMoreSection;
|
||||
|
||||
|
@ -51,4 +51,20 @@ public abstract class AbstractZeppOsService {
|
||||
protected void write(final TransactionBuilder builder, final byte[] data) {
|
||||
this.mSupport.writeToChunked2021(builder, getEndpoint(), data, isEncrypted());
|
||||
}
|
||||
|
||||
protected static Boolean booleanFromByte(final byte b) {
|
||||
switch (b) {
|
||||
case 0x00:
|
||||
return false;
|
||||
case 0x01:
|
||||
return true;
|
||||
default:
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected byte bool(final boolean bool) {
|
||||
return (byte) (bool ? 0x01 : 0x00);
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePref
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.ActivateDisplayOnLift;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.ActivateDisplayOnLiftSensitivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.AlwaysOnDisplay;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.DoNotDisturb;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||
@ -616,22 +617,8 @@ public class ZeppOsConfigService extends AbstractZeppOsService {
|
||||
return String.format(Locale.ROOT, "%s_huami_2021_max", key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preference key where to save the list of possible value for a preference, comma-separated.
|
||||
*/
|
||||
public static String getPrefPossibleValuesKey(final String key) {
|
||||
return String.format(Locale.ROOT, "%s_huami_2021_possible_values", key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preference key where to that a config was reported as supported (boolean).
|
||||
*/
|
||||
public static String getPrefKnownConfig(final ConfigArg pref) {
|
||||
return String.format(Locale.ROOT, "huami_2021_known_config_%s", pref.name());
|
||||
}
|
||||
|
||||
public static boolean deviceHasConfig(final Prefs devicePrefs, final ZeppOsConfigService.ConfigArg config) {
|
||||
return devicePrefs.getBoolean(getPrefKnownConfig(config), false);
|
||||
return devicePrefs.getBoolean(Huami2021Coordinator.getPrefKnownConfig(config.name()), false);
|
||||
}
|
||||
|
||||
public ConfigSetter newSetter() {
|
||||
@ -941,7 +928,7 @@ public class ZeppOsConfigService extends AbstractZeppOsService {
|
||||
}
|
||||
|
||||
if (configArg != null && argPrefs != null && configType == configArg.getConfigType(mGroupVersions)) {
|
||||
prefs.put(getPrefKnownConfig(configArg), true);
|
||||
prefs.put(Huami2021Coordinator.getPrefKnownConfig(configArg.name()), true);
|
||||
|
||||
// Special cases for "follow phone" preferences. We need to ensure that "auto"
|
||||
// always has precedence
|
||||
@ -1030,7 +1017,7 @@ public class ZeppOsConfigService extends AbstractZeppOsService {
|
||||
prefs = singletonMap(configArg.getPrefKey(), decoder.decode(str.getValue()));
|
||||
if (includesConstraints) {
|
||||
prefs.put(
|
||||
getPrefPossibleValuesKey(configArg.getPrefKey()),
|
||||
Huami2021Coordinator.getPrefPossibleValuesKey(configArg.getPrefKey()),
|
||||
decodeStringValues(possibleValues, decoder)
|
||||
);
|
||||
}
|
||||
@ -1109,7 +1096,7 @@ public class ZeppOsConfigService extends AbstractZeppOsService {
|
||||
prefs = singletonMap(configArg.getPrefKey(), new HashSet<>(valuesList));
|
||||
if (includesConstraints) {
|
||||
prefs.put(
|
||||
getPrefPossibleValuesKey(configArg.getPrefKey()),
|
||||
Huami2021Coordinator.getPrefPossibleValuesKey(configArg.getPrefKey()),
|
||||
String.join(",", decodeByteValues(possibleValues, decoder))
|
||||
);
|
||||
}
|
||||
@ -1145,7 +1132,7 @@ public class ZeppOsConfigService extends AbstractZeppOsService {
|
||||
possibleLanguages.add(languageByteToLocale(possibleValue));
|
||||
}
|
||||
possibleLanguages.removeAll(Collections.singleton(null));
|
||||
prefs.put(getPrefPossibleValuesKey(configArg.getPrefKey()), String.join(",", possibleLanguages));
|
||||
prefs.put(Huami2021Coordinator.getPrefPossibleValuesKey(configArg.getPrefKey()), String.join(",", possibleLanguages));
|
||||
}
|
||||
}
|
||||
decoder = null;
|
||||
@ -1201,7 +1188,7 @@ public class ZeppOsConfigService extends AbstractZeppOsService {
|
||||
prefs = singletonMap(configArg.getPrefKey(), decoder.decode(value.getValue()));
|
||||
if (includesConstraints) {
|
||||
prefs.put(
|
||||
getPrefPossibleValuesKey(configArg.getPrefKey()),
|
||||
Huami2021Coordinator.getPrefPossibleValuesKey(configArg.getPrefKey()),
|
||||
String.join(",", decodeByteValues(possibleValues, decoder))
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,208 @@
|
||||
/* Copyright (C) 2023 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.service.devices.huami.zeppos.services;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.Huami2021Support;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.AbstractZeppOsService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.MapUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||
|
||||
public class ZeppOsMorningUpdatesService extends AbstractZeppOsService {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ZeppOsMorningUpdatesService.class);
|
||||
|
||||
private static final short ENDPOINT = 0x003f;
|
||||
|
||||
private static final byte CMD_ENABLED_GET = 0x03;
|
||||
private static final byte CMD_ENABLED_RET = 0x04;
|
||||
private static final byte CMD_ENABLED_SET = 0x07;
|
||||
private static final byte CMD_ENABLED_SET_ACK = 0x08;
|
||||
private static final byte CMD_CATEGORIES_REQUEST = 0x05;
|
||||
private static final byte CMD_CATEGORIES_RESPONSE = 0x06;
|
||||
private static final byte CMD_CATEGORIES_SET = 0x09;
|
||||
private static final byte CMD_CATEGORIES_SET_ACK = 0x0a;
|
||||
|
||||
private static final Map<Byte, String> MORNING_UPDATES_MAP = new HashMap<Byte, String>() {{
|
||||
put((byte) 0x02, "weather");
|
||||
put((byte) 0x03, "battery");
|
||||
put((byte) 0x04, "sleep");
|
||||
put((byte) 0x06, "event");
|
||||
put((byte) 0x07, "pai");
|
||||
put((byte) 0x08, "yesterdays_activity");
|
||||
put((byte) 0x0a, "cycle_tracking");
|
||||
}};
|
||||
|
||||
public ZeppOsMorningUpdatesService(Huami2021Support support) {
|
||||
super(support);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getEndpoint() {
|
||||
return ENDPOINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEncrypted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePayload(byte[] payload) {
|
||||
switch (payload[0]) {
|
||||
case CMD_ENABLED_RET:
|
||||
if (payload[1] != 0x01) {
|
||||
LOG.warn("Unexpected morning updates enabled byte {}", payload[1]);
|
||||
return;
|
||||
}
|
||||
final Boolean enabled = booleanFromByte(payload[2]);
|
||||
if (enabled == null) {
|
||||
LOG.error("Unexpected morning updates enabled byte");
|
||||
return;
|
||||
}
|
||||
final GBDeviceEventUpdatePreferences gbDeviceEventUpdatePreferences = new GBDeviceEventUpdatePreferences()
|
||||
.withPreference(Huami2021Coordinator.getPrefKnownConfig(DeviceSettingsPreferenceConst.MORNING_UPDATES_ENABLED), true)
|
||||
.withPreference(DeviceSettingsPreferenceConst.MORNING_UPDATES_ENABLED, enabled);
|
||||
getSupport().evaluateGBDeviceEvent(gbDeviceEventUpdatePreferences);
|
||||
LOG.info("Morning updates enabled = {}", enabled);
|
||||
return;
|
||||
case CMD_ENABLED_SET_ACK:
|
||||
LOG.info("Morning updates enabled set ack ACK, status = {}", payload[1]);
|
||||
return;
|
||||
case CMD_CATEGORIES_RESPONSE:
|
||||
LOG.info("Got morning update items from watch");
|
||||
decodeAndUpdateCategories(payload);
|
||||
return;
|
||||
case CMD_CATEGORIES_SET_ACK:
|
||||
LOG.info("Morning updates categories set ack ACK, status = {}", payload[1]);
|
||||
return;
|
||||
default:
|
||||
LOG.warn("Unexpected morning updates byte {}", String.format("0x%02x", payload[0]));
|
||||
}
|
||||
}
|
||||
|
||||
public void getEnabled(final TransactionBuilder builder) {
|
||||
write(builder, CMD_ENABLED_GET);
|
||||
}
|
||||
|
||||
public void setEnabled(final boolean enabled) {
|
||||
write("set morning updates enabled", new byte[] {CMD_ENABLED_SET, bool(enabled)});
|
||||
}
|
||||
|
||||
public void getCategories(final TransactionBuilder builder) {
|
||||
write(builder, CMD_CATEGORIES_REQUEST);
|
||||
}
|
||||
|
||||
public void setCategories(final List<String> categories, final List<String> allCategories) {
|
||||
// Build a sorted list, with the enabled at the start
|
||||
final List<String> categoriesSorted = new ArrayList<>(categories);
|
||||
for (String category : allCategories) {
|
||||
if (!categories.contains(category)) {
|
||||
categoriesSorted.add(category);
|
||||
}
|
||||
}
|
||||
|
||||
final Map<String, Byte> idMap = MapUtils.reverse(MORNING_UPDATES_MAP);
|
||||
|
||||
final ByteBuffer buf = ByteBuffer.allocate(2 + categoriesSorted.size() * 3)
|
||||
.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
buf.put(CMD_CATEGORIES_SET);
|
||||
buf.put((byte) categoriesSorted.size());
|
||||
|
||||
for (final String category : categoriesSorted) {
|
||||
final byte id;
|
||||
if (idMap.containsKey(category)) {
|
||||
id = idMap.get(category);
|
||||
} else {
|
||||
// name doesn't match a known value, attempt to parse it as hex
|
||||
final Matcher matcher = Pattern.compile("^0[xX]([0-9a-fA-F]{1,2})$").matcher(category);
|
||||
if (matcher.find()) {
|
||||
id = (byte) Integer.parseInt(matcher.group(1), 16);
|
||||
} else {
|
||||
LOG.warn("Unknown category {}, and failed to parse as hex, not setting", category);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
buf.put(id);
|
||||
buf.put((byte) 0x00);
|
||||
buf.put(bool(categories.contains(category)));
|
||||
}
|
||||
|
||||
write("set morning updates categories", buf.array());
|
||||
}
|
||||
|
||||
private void decodeAndUpdateCategories(final byte[] payload) {
|
||||
if (payload[1] != 0x01) {
|
||||
LOG.warn("Unexpected morning update items byte {}", payload[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
final int numCategories = payload[2];
|
||||
final int expectedLength = 3 + numCategories * 3;
|
||||
if (payload.length != expectedLength) {
|
||||
LOG.warn("Unexpected morning updates categories payload size {}, expected {}", payload.length, expectedLength);
|
||||
return;
|
||||
}
|
||||
|
||||
final List<String> enabledCategories = new ArrayList<>(numCategories);
|
||||
final List<String> allCategories = new ArrayList<>(numCategories);
|
||||
|
||||
for (int i = 3; i < expectedLength; i += 3) {
|
||||
final String itemName = MORNING_UPDATES_MAP.containsKey(payload[i])
|
||||
? MORNING_UPDATES_MAP.get(payload[i])
|
||||
: String.format("0x%x", payload[i]);
|
||||
|
||||
allCategories.add(itemName);
|
||||
|
||||
// i + 1 is always 0
|
||||
final Boolean itemEnabled = booleanFromByte(payload[i + 2]);
|
||||
if (itemEnabled == null) {
|
||||
LOG.warn("Unexpected enabled byte {} for item at i={}", payload[i + 2], i);
|
||||
} else if(itemEnabled) {
|
||||
enabledCategories.add(itemName);
|
||||
}
|
||||
}
|
||||
|
||||
final String prefKey = DeviceSettingsPreferenceConst.MORNING_UPDATES_CATEGORIES_SORTABLE;
|
||||
final String allCategoriesPrefKey = Huami2021Coordinator.getPrefPossibleValuesKey(prefKey);
|
||||
|
||||
final String allCategoriesPrefValue = StringUtils.join(",", allCategories.toArray(new String[0])).toString();
|
||||
final String prefValue = StringUtils.join(",", enabledCategories.toArray(new String[0])).toString();
|
||||
final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences()
|
||||
.withPreference(Huami2021Coordinator.getPrefKnownConfig(prefKey), true)
|
||||
.withPreference(allCategoriesPrefKey, allCategoriesPrefValue)
|
||||
.withPreference(prefKey, prefValue);
|
||||
|
||||
getSupport().evaluateGBDeviceEvent(eventUpdatePreferences);
|
||||
}
|
||||
}
|
@ -676,6 +676,25 @@
|
||||
<item>rowing_machine</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_morning_updates_categories">
|
||||
<item>@string/menuitem_weather</item>
|
||||
<item>@string/battery</item>
|
||||
<item>@string/menuitem_sleep</item>
|
||||
<item>@string/menuitem_events</item>
|
||||
<item>@string/menuitem_pai</item>
|
||||
<item>@string/yesterdays_activity</item>
|
||||
<item>@string/menuitem_cycles</item>
|
||||
</string-array>
|
||||
<string-array name="pref_morning_updates_categories_values">
|
||||
<item>weather</item>
|
||||
<item>battery</item>
|
||||
<item>sleep</item>
|
||||
<item>event</item>
|
||||
<item>pai</item>
|
||||
<item>yesterdays_activity</item>
|
||||
<item>cycle_tracking</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_gps_mode_preset">
|
||||
<item>@string/accuracy</item>
|
||||
<item>@string/balanced</item>
|
||||
|
@ -467,6 +467,10 @@
|
||||
<string name="pref_agps_expire_time">AGPS Expire Time</string>
|
||||
<string name="pref_camera_remote_title">Camera Remote</string>
|
||||
<string name="pref_camera_remote_summary">Allows the watch to trigger the phone\'s camera</string>
|
||||
<string name="pref_morning_updates_title">Morning Updates</string>
|
||||
<string name="pref_morning_updates_summary">Display updates every morning</string>
|
||||
<string name="pref_morning_updates_categories_title">Morning Updates Categories</string>
|
||||
<string name="pref_morning_updates_categories_summary">List of categories to display every morning</string>
|
||||
<string name="pref_workout_start_on_phone_title">Fitness app tracking</string>
|
||||
<string name="pref_workout_start_on_phone_summary">Start/stop fitness app tracking on phone when a GPS workout is started on the band</string>
|
||||
<string name="pref_workout_send_gps_title">Send GPS during workout</string>
|
||||
@ -1333,6 +1337,7 @@
|
||||
<string name='menuitem_eject_water'>Eject Water</string>
|
||||
<string name="menuitem_unknown_app">Unknown (%s)</string>
|
||||
<string name="menuitem_unsupported">[UNSUPPORTED] %s</string>
|
||||
<string name="yesterdays_activity">Yesterday\'s Activity</string>
|
||||
<string name="watch9_time_minutes">Minutes:</string>
|
||||
<string name="watch9_time_hours">Hours:</string>
|
||||
<string name="watch9_time_seconds">Seconds:</string>
|
||||
|
28
app/src/main/res/xml/devicesettings_morning_updates.xml
Normal file
28
app/src/main/res/xml/devicesettings_morning_updates.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_wb_sunny"
|
||||
android:key="pref_morning_updates"
|
||||
android:persistent="false"
|
||||
android:summary="@string/pref_morning_updates_summary"
|
||||
android:title="@string/pref_morning_updates_title">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_wb_sunny"
|
||||
android:key="morning_updates_enabled"
|
||||
android:summary="@string/pref_morning_updates_summary"
|
||||
android:title="@string/pref_morning_updates_title" />
|
||||
|
||||
<com.mobeta.android.dslv.DragSortListPreference
|
||||
android:defaultValue="@array/pref_huami2021_empty_array"
|
||||
android:dialogTitle="@string/pref_morning_updates_categories_title"
|
||||
android:entries="@array/pref_morning_updates_categories"
|
||||
android:entryValues="@array/pref_morning_updates_categories_values"
|
||||
android:icon="@drawable/ic_list_numbered"
|
||||
android:key="morning_updates_categories"
|
||||
android:persistent="true"
|
||||
android:summary="@string/pref_morning_updates_categories_summary"
|
||||
android:title="@string/pref_morning_updates_categories_title" />
|
||||
</PreferenceScreen>
|
||||
</androidx.preference.PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user