diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index 4bbd36b6a..4671a325d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -20,7 +20,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.text.InputType; -import android.view.View; import android.widget.EditText; import androidx.annotation.NonNull; @@ -49,13 +48,10 @@ import java.util.Objects; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureWorldClocks; -import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; -import nodomain.freeyourgadget.gadgetbridge.devices.makibeshr3.MakibesHR3Constants; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; @@ -77,6 +73,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_EXPOSE_HR_THIRDPARTY; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_SHORTCUTS_SORTABLE; +import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_NIGHT_MODE; @@ -350,6 +347,7 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat imp addPreferenceHandlerFor(PREF_DATEFORMAT); addPreferenceHandlerFor(PREF_DISPLAY_ITEMS); addPreferenceHandlerFor(PREF_DISPLAY_ITEMS_SORTABLE); + addPreferenceHandlerFor(PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE); addPreferenceHandlerFor(PREF_SHORTCUTS); addPreferenceHandlerFor(PREF_SHORTCUTS_SORTABLE); addPreferenceHandlerFor(PREF_LANGUAGE); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java index 8fef25994..2ec6b9f77 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiConst.java @@ -59,6 +59,7 @@ public class HuamiConst { public static final String PREF_DISPLAY_ITEMS = "display_items"; public static final String PREF_DISPLAY_ITEMS_SORTABLE = "display_items_sortable"; + public static final String PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE = "workout_activity_types_sortable"; public static final String PREF_SHORTCUTS = "shortcuts"; public static final String PREF_SHORTCUTS_SORTABLE = "shortcuts_sortable"; public static final String PREF_EXPOSE_HR_THIRDPARTY = "expose_hr_thirdparty"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java index 8c9652404..e6d692330 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiSupport.java @@ -139,7 +139,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotific import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.actions.StopNotificationAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2NotificationStrategy; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2TextNotificationStrategy; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband5.MiBand5Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchActivityOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.InitOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.InitOperation2021; @@ -193,14 +192,12 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_BUTTON_ACTION_SELECTION_OFF; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_FELL_SLEEP_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_FELL_SLEEP_SELECTION; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_SELECTION_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_SELECTION_OFF; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_START_NON_WEAR_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_START_NON_WEAR_SELECTION; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_WOKE_UP_BROADCAST; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DEVICE_ACTION_WOKE_UP_SELECTION; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.DISPLAY_ITEM_BIT_CLOCK; -import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY; import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.ENDPOINT_DISPLAY_ITEMS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_COUNT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_PROFILE; @@ -2410,6 +2407,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { case HuamiConst.PREF_SHORTCUTS_SORTABLE: setShortcuts(builder); break; + case HuamiConst.PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE: + setWorkoutActivityTypes(builder); + break; case MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO: setRotateWristToSwitchInfo(builder); break; @@ -2992,6 +2992,48 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport { return this; } + protected HuamiSupport setWorkoutActivityTypes(final TransactionBuilder builder) { + final SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()); + + final List allActivityTypes = Arrays.asList(getContext().getResources().getStringArray(R.array.pref_miband5_workout_activity_types_values)); + final List defaultActivityTypes = Arrays.asList(getContext().getResources().getStringArray(R.array.pref_miband5_workout_activity_types_default)); + final String activityTypesPref = prefs.getString(HuamiConst.PREF_WORKOUT_ACTIVITY_TYPES_SORTABLE, null); + + final List enabledActivityTypes; + if (activityTypesPref == null || activityTypesPref.equals("")) { + enabledActivityTypes = defaultActivityTypes; + } else { + enabledActivityTypes = Arrays.asList(activityTypesPref.split(",")); + } + + LOG.info("Setting workout types to {}", enabledActivityTypes); + + final byte[] command = new byte[allActivityTypes.size() * 3 + 2]; + command[0] = 0x0b; + command[1] = 0x00; + + int pos = 2; + + for (final String workoutType : enabledActivityTypes) { + command[pos++] = HuamiWorkoutActivityType.fromPrefValue(workoutType).getCode(); + command[pos++] = 0x00; + command[pos++] = 0x01; + } + + // Send all the remaining disabled workout types + for (final String workoutType : allActivityTypes) { + if (!enabledActivityTypes.contains(workoutType)) { + command[pos++] = HuamiWorkoutActivityType.fromPrefValue(workoutType).getCode(); + command[pos++] = 0x00; + command[pos++] = 0x00; + } + } + + writeToChunked(builder, 9, command); + + return this; + } + protected HuamiSupport setBeepSounds(TransactionBuilder builder) { SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiWorkoutActivityType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiWorkoutActivityType.java new file mode 100644 index 000000000..70688310c --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/HuamiWorkoutActivityType.java @@ -0,0 +1,52 @@ +/* Copyright (C) 2022 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 . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.huami; + +import java.util.Locale; + +public enum HuamiWorkoutActivityType { + OutdoorRunning(0x01), + Walking(0x06), + Treadmill(0x08), + OutdoorCycling(0x09), + IndoorCycling(0x0a), + Elliptical(0x0c), + PoolSwimming(0x0e), + Freestyle(0x10), + JumpRope(0x15), + RowingMachine(0x17), + Yoga(0x3c); + + private final byte code; + + HuamiWorkoutActivityType(final int code) { + this.code = (byte) code; + } + + public byte getCode() { + return code; + } + + public static HuamiWorkoutActivityType fromPrefValue(final String prefValue) { + for (HuamiWorkoutActivityType type : values()) { + if (type.name().toLowerCase(Locale.ROOT).equals(prefValue.replace("_", "").toLowerCase(Locale.ROOT))) { + return type; + } + } + throw new RuntimeException("No matching HuamiWorkoutActivityType for pref value: " + prefValue); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java index d96edc865..e38fd3861 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/miband5/MiBand5Support.java @@ -65,5 +65,6 @@ public class MiBand5Support extends MiBand4Support { super.phase3Initialize(builder); LOG.info("phase3Initialize..."); setActivateDisplayOnLiftWristSensitivity(builder); // TODO? Move this to HuamiSupport? + setWorkoutActivityTypes(builder); // TODO: Supported by other bands? } } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index e9b7245bd..73cea0d25 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -580,6 +580,48 @@ @string/p_menuitem_music + + @string/activity_type_outdoor_running + @string/activity_type_walking + @string/activity_type_treadmill + @string/activity_type_outdoor_cycling + @string/activity_type_indoor_cycling + @string/activity_type_elliptical + @string/activity_type_swimming + @string/activity_type_freestyle + @string/activity_type_jump_roping + @string/activity_type_rowing_machine + @string/activity_type_yoga + + + + outdoor_running + walking + treadmill + outdoor_cycling + indoor_cycling + elliptical + pool_swimming + freestyle + jump_rope + rowing_machine + yoga + + + + outdoor_running + walking + treadmill + outdoor_cycling + indoor_cycling + elliptical + pool_swimming + freestyle + jump_rope + rowing_machine + yoga + + @string/menuitem_pai @string/menuitem_dnd diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a2422f918..7cff8e280 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -688,6 +688,8 @@ Shortcuts Choose the shortcuts on the band screen Sensitivity + Workout Activity Types + Choose the activity types to display on the workouts screen Force black on white color scheme Useful if you your watch has dark hands Hydration reminder @@ -875,13 +877,17 @@ Deep sleep Device not worn Running + Outdoor Running Walking + Freestyle Hiking Climbing Swimming Swimming (Open water) Indoor Cycling + Outdoor Cycling Elliptical Trainer + Elliptical Jumping Rope Yoga Soccer diff --git a/app/src/main/res/xml/devicesettings_miband5.xml b/app/src/main/res/xml/devicesettings_miband5.xml index e7ea6b1a2..326912155 100644 --- a/app/src/main/res/xml/devicesettings_miband5.xml +++ b/app/src/main/res/xml/devicesettings_miband5.xml @@ -20,4 +20,14 @@ android:persistent="true" android:summary="@string/bip_prefs_shotcuts_summary" android:title="@string/bip_prefs_shortcuts" /> +