diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 5f47392bb..758b7e9b5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -87,6 +87,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import nodomain.freeyourgadget.gadgetbridge.util.preferences.DevicePrefs; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.AMAZFITBIP; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.AMAZFITCOR; @@ -1501,8 +1502,8 @@ public class GBApplication extends Application { return context.getSharedPreferences("devicesettings_" + deviceIdentifier, Context.MODE_PRIVATE); } - public static Prefs getDevicePrefs(final String deviceIdentifier) { - return new Prefs(getDeviceSpecificSharedPrefs(deviceIdentifier)); + public static DevicePrefs getDevicePrefs(final String deviceIdentifier) { + return new DevicePrefs(getDeviceSpecificSharedPrefs(deviceIdentifier)); } public static void deleteDeviceSpecificSharedPrefs(String deviceIdentifier) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/BatteryInfoActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/BatteryInfoActivity.java index 5fee6f77d..03fc4e938 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/BatteryInfoActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/BatteryInfoActivity.java @@ -193,7 +193,7 @@ public class BatteryInfoActivity extends AbstractGBActivity { battery_status_device_name_text.setText(gbDevice.getAliasOrName()); setBatteryLabels(); - for (BatteryConfig batteryConfig : coordinator.getBatteryConfig()) { + for (BatteryConfig batteryConfig : coordinator.getBatteryConfig(gbDevice)) { if (batteryConfig.getBatteryIndex() == batteryIndex) { battery_status_extra_name.setText(batteryConfig.getBatteryLabel()); battery_status_device_icon.setImageResource(batteryConfig.getBatteryIcon()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index 8ba3c2b41..e7131c3b2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -34,6 +34,12 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_HEADER_FTP_SERVER_STATUS = "pref_header_ftp_server_status"; public static final String PREF_HEADER_FTP_SERVER_CONFIGURATION = "pref_header_ftp_server_configuration"; + public static final String PREF_BATTERY_SHOW_IN_NOTIFICATION = "battery_show_in_notification_"; + public static final String PREF_BATTERY_NOTIFY_LOW_ENABLED = "battery_notify_low_enabled_"; + public static final String PREF_BATTERY_NOTIFY_LOW_THRESHOLD = "battery_notify_low_threshold_"; + public static final String PREF_BATTERY_NOTIFY_FULL_ENABLED = "battery_notify_full_enabled_"; + public static final String PREF_BATTERY_NOTIFY_FULL_THRESHOLD = "battery_notify_full_threshold_"; + public static final String PREF_SCREEN_NIGHT_MODE = "pref_screen_night_mode"; public static final String PREF_SCREEN_SLEEP_MODE = "pref_screen_sleep_mode"; public static final String PREF_SCREEN_LIFT_WRIST = "pref_screen_lift_wrist"; 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 da39162d3..86a5c9157 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 @@ -43,9 +43,12 @@ import android.os.Bundle; import android.text.InputType; import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import androidx.preference.EditTextPreference; import androidx.preference.ListPreference; import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreferenceCompat; import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; @@ -75,8 +78,11 @@ import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import nodomain.freeyourgadget.gadgetbridge.util.preferences.GBSimpleSummaryProvider; +import nodomain.freeyourgadget.gadgetbridge.util.preferences.MinMaxTextWatcher; public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment implements DeviceSpecificSettingsHandler { @@ -129,6 +135,8 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i getPreferenceManager().setSharedPreferencesName("devicesettings_" + settingsFileSuffix); + LOG.debug("onCreatePreferences: {}", rootKey); + if (rootKey == null) { // we are the main preference screen boolean first = true; @@ -150,6 +158,7 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i // Use the root key here to set the root screen, so that the actionbar title gets updated setPreferencesFromResource(setting, rootKey); first = false; + addDynamicSettings(rootKey); } else { addPreferencesFromResource(setting); } @@ -185,6 +194,91 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i setChangeListener(); } + private void addDynamicSettings(final String rootKey) { + if (rootKey.equals(DeviceSpecificSettingsScreen.BATTERY.getKey())) { + addBatterySettings(); + } + } + + private void addBatterySettings() { + final DeviceCoordinator coordinator = device.getDeviceCoordinator(); + final PreferenceScreen batteryScreen = getPreferenceScreen(); + if (batteryScreen == null) { + return; + } + final BatteryConfig[] batteryConfigs = coordinator.getBatteryConfig(device); + for (final BatteryConfig batteryConfig : batteryConfigs) { + if (batteryConfigs.length > 1) { + final Preference prefHeader = new PreferenceCategory(requireContext()); + prefHeader.setKey("pref_battery_header_" + batteryConfig.getBatteryIndex()); + prefHeader.setIconSpaceReserved(false); + if (batteryConfig.getBatteryLabel() > 0) { + prefHeader.setTitle(batteryConfig.getBatteryLabel()); + } else { + prefHeader.setTitle(requireContext().getString(R.string.battery_i, batteryConfig.getBatteryIndex())); + } + batteryScreen.addPreference(prefHeader); + } + + final SwitchPreferenceCompat showInNotification = new SwitchPreferenceCompat(requireContext()); + showInNotification.setLayoutResource(R.layout.preference_checkbox); + showInNotification.setKey(PREF_BATTERY_SHOW_IN_NOTIFICATION + batteryConfig.getBatteryIndex()); + showInNotification.setTitle(R.string.show_in_notification); + showInNotification.setIconSpaceReserved(false); + showInNotification.setDefaultValue(true); + batteryScreen.addPreference(showInNotification); + + final SwitchPreferenceCompat notifyLowEnabled = new SwitchPreferenceCompat(requireContext()); + notifyLowEnabled.setLayoutResource(R.layout.preference_checkbox); + notifyLowEnabled.setKey(PREF_BATTERY_NOTIFY_LOW_ENABLED + batteryConfig.getBatteryIndex()); + notifyLowEnabled.setTitle(R.string.battery_low_notify_enabled); + notifyLowEnabled.setDefaultValue(true); + notifyLowEnabled.setIconSpaceReserved(false); + batteryScreen.addPreference(notifyLowEnabled); + + final EditTextPreference notifyLowThreshold = new EditTextPreference(requireContext()); + notifyLowThreshold.setKey(PREF_BATTERY_NOTIFY_LOW_THRESHOLD + batteryConfig.getBatteryIndex()); + notifyLowThreshold.setTitle(R.string.battery_low_threshold); + notifyLowThreshold.setDialogTitle(R.string.battery_low_threshold); + notifyLowThreshold.setIconSpaceReserved(false); + notifyLowThreshold.setOnBindEditTextListener(editText -> { + editText.setInputType(InputType.TYPE_CLASS_NUMBER); + editText.addTextChangedListener(new MinMaxTextWatcher(editText, 0, 100, true)); + editText.setSelection(editText.getText().length()); + }); + notifyLowThreshold.setSummaryProvider(new GBSimpleSummaryProvider( + requireContext().getString(R.string.default_percentage, batteryConfig.getDefaultLowThreshold()), + R.string.battery_percentage_str + )); + + batteryScreen.addPreference(notifyLowThreshold); + + final SwitchPreferenceCompat notifyFullEnabled = new SwitchPreferenceCompat(requireContext()); + notifyFullEnabled.setLayoutResource(R.layout.preference_checkbox); + notifyFullEnabled.setKey(PREF_BATTERY_NOTIFY_FULL_ENABLED + batteryConfig.getBatteryIndex()); + notifyFullEnabled.setTitle(R.string.battery_full_notify_enabled); + notifyFullEnabled.setDefaultValue(true); + notifyFullEnabled.setIconSpaceReserved(false); + batteryScreen.addPreference(notifyFullEnabled); + + final EditTextPreference notifyFullThreshold = new EditTextPreference(requireContext()); + notifyFullThreshold.setKey(PREF_BATTERY_NOTIFY_FULL_THRESHOLD + batteryConfig.getBatteryIndex()); + notifyFullThreshold.setTitle(R.string.battery_full_threshold); + notifyFullThreshold.setDialogTitle(R.string.battery_full_threshold); + notifyFullThreshold.setIconSpaceReserved(false); + notifyFullThreshold.setOnBindEditTextListener(editText -> { + editText.setInputType(InputType.TYPE_CLASS_NUMBER); + editText.addTextChangedListener(new MinMaxTextWatcher(editText, 0, 100, true)); + editText.setSelection(editText.getText().length()); + }); + notifyFullThreshold.setSummaryProvider(new GBSimpleSummaryProvider( + requireContext().getString(R.string.default_percentage, batteryConfig.getDefaultFullThreshold()), + R.string.battery_percentage_str + )); + batteryScreen.addPreference(notifyFullThreshold); + } + } + /* * delayed execution so that the preferences are applied first */ @@ -1110,6 +1204,12 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i coordinator.getSupportedDeviceSpecificConnectionSettings() ); + if (coordinator.getBatteryCount() > 0) { + deviceSpecificSettings.addRootScreen( + DeviceSpecificSettingsScreen.BATTERY + ); + } + if (coordinator.supportsActivityTracking()) { deviceSpecificSettings.addRootScreen( DeviceSpecificSettingsScreen.ACTIVITY_INFO, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsScreen.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsScreen.java index 0a6ee13db..d0cb78ad2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsScreen.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsScreen.java @@ -24,6 +24,7 @@ public enum DeviceSpecificSettingsScreen { ACTIVITY_INFO("pref_screen_activity_info", R.xml.devicesettings_root_activity_info), AUDIO("pref_screen_audio", R.xml.devicesettings_root_audio), AUTHENTICATION("pref_screen_authentication", R.xml.devicesettings_root_authentication), + BATTERY("pref_screen_battery", R.xml.devicesettings_root_battery), CALENDAR("pref_screen_calendar", R.xml.devicesettings_root_calendar), CALLS_AND_NOTIFICATIONS("pref_screen_calls_and_notifications", R.xml.devicesettings_root_calls_and_notifications), CONNECTION("pref_screen_connection", R.xml.devicesettings_root_connection), diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java index d8af331ff..79bc970d6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java @@ -133,7 +133,7 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { @Override public GBDevice createDevice(GBDeviceCandidate candidate, DeviceType deviceType) { GBDevice gbDevice = new GBDevice(candidate.getDevice().getAddress(), candidate.getName(), null, null, deviceType); - for (BatteryConfig batteryConfig : getBatteryConfig()) { + for (BatteryConfig batteryConfig : getBatteryConfig(gbDevice)) { gbDevice.setBatteryIcon(batteryConfig.getBatteryIcon(), batteryConfig.getBatteryIndex()); gbDevice.setBatteryLabel(batteryConfig.getBatteryLabel(), batteryConfig.getBatteryIndex()); } @@ -684,8 +684,12 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { } //multiple battery support, default is 1, maximum is 3, 0 will disable the battery in UI @Override - public BatteryConfig[] getBatteryConfig() { - return new BatteryConfig[0]; + public BatteryConfig[] getBatteryConfig(final GBDevice device) { + final BatteryConfig[] batteryConfigs = new BatteryConfig[getBatteryCount()]; + for (int i = 0; i < getBatteryCount(); i++) { + batteryConfigs[i] = new BatteryConfig(i); + } + return batteryConfigs; } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java index 21d1d51fb..c921aa1a7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java @@ -649,7 +649,7 @@ public interface DeviceCoordinator { */ int getBatteryCount(); - BatteryConfig[] getBatteryConfig(); + BatteryConfig[] getBatteryConfig(GBDevice device); boolean supportsPowerOff(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java index 620d9310b..5f4fd4c3c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/BangleJSCoordinator.java @@ -47,6 +47,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.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.banglejs.BangleJSDeviceSupport; @@ -192,6 +193,19 @@ public class BangleJSCoordinator extends AbstractBLEDeviceCoordinator { return true; } + @Override + public BatteryConfig[] getBatteryConfig(final GBDevice device) { + return new BatteryConfig[]{ + new BatteryConfig( + 0, + GBDevice.BATTERY_ICON_DEFAULT, + GBDevice.BATTERY_LABEL_DEFAULT, + 15, + 100 + ) + }; + } + @Override public int[] getSupportedDeviceSpecificSettings(final GBDevice device) { final List settings = new ArrayList<>(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBuds2DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBuds2DeviceCoordinator.java index 489fbb98a..c510b1cd1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBuds2DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBuds2DeviceCoordinator.java @@ -43,7 +43,7 @@ public class GalaxyBuds2DeviceCoordinator extends GalaxyBudsGenericCoordinator { } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_buds_pro_case, R.string.battery_case); BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_buds_pro_left, R.string.left_earbud); BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_buds_pro_right, R.string.right_earbud); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBuds2ProDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBuds2ProDeviceCoordinator.java index 9579a2962..cd7410bd9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBuds2ProDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBuds2ProDeviceCoordinator.java @@ -44,7 +44,7 @@ public class GalaxyBuds2ProDeviceCoordinator extends GalaxyBudsGenericCoordinato } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_buds_pro_case, R.string.battery_case); BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_buds_pro_left, R.string.left_earbud); BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_buds_pro_right, R.string.right_earbud); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java index 037325354..a031bd2a6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsDeviceCoordinator.java @@ -38,7 +38,7 @@ public class GalaxyBudsDeviceCoordinator extends GalaxyBudsGenericCoordinator { } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_galaxy_buds_l, R.string.left_earbud); BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_galaxy_buds_r, R.string.right_earbud); return new BatteryConfig[]{battery1, battery2}; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java index e6a1ec6e0..f5f1c1171 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsLiveDeviceCoordinator.java @@ -37,7 +37,7 @@ public class GalaxyBudsLiveDeviceCoordinator extends GalaxyBudsGenericCoordinato } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_tws_case, R.string.battery_case); BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_galaxy_buds_live_l, R.string.left_earbud); BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_galaxy_buds_live_r, R.string.right_earbud); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java index d7dee6e99..72bea0463 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/galaxy_buds/GalaxyBudsProDeviceCoordinator.java @@ -44,7 +44,7 @@ public class GalaxyBudsProDeviceCoordinator extends GalaxyBudsGenericCoordinator } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_buds_pro_case, R.string.battery_case); BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_buds_pro_left, R.string.left_earbud); BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_buds_pro_right, R.string.right_earbud); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminRealtimeSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminRealtimeSettingsFragment.java index b68ab95de..1ae635e7b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminRealtimeSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminRealtimeSettingsFragment.java @@ -67,6 +67,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; import nodomain.freeyourgadget.gadgetbridge.util.XDatePreference; import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference; +import nodomain.freeyourgadget.gadgetbridge.util.preferences.MinMaxTextWatcher; public class GarminRealtimeSettingsFragment extends AbstractPreferenceFragment { private static final Logger LOG = LoggerFactory.getLogger(GarminRealtimeSettingsFragment.class); @@ -851,43 +852,4 @@ public class GarminRealtimeSettingsFragment extends AbstractPreferenceFragment { ).build(); GBApplication.deviceService(device).onSendConfiguration("protobuf:" + GB.hexdump(smart.toByteArray())); } - - private static class MinMaxTextWatcher implements TextWatcher { - private final EditText editText; - private final int min; - private final int max; - - private MinMaxTextWatcher(final EditText editText, final int min, final int max) { - this.editText = editText; - this.min = min; - this.max = max; - } - - @Override - public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) { - } - - @Override - public void onTextChanged(final CharSequence s, final int start, final int before, final int count) { - } - - @Override - public void afterTextChanged(final Editable editable) { - try { - final int val = Integer.parseInt(editable.toString()); - editText.getRootView().findViewById(android.R.id.button1) - .setEnabled(val >= min && val <= max); - if (val < min) { - editText.setError(editText.getContext().getString(R.string.min_val, min)); - } else if (val > max) { - editText.setError(editText.getContext().getString(R.string.max_val, max)); - } else { - editText.setError(null); - } - } catch (final NumberFormatException e) { - editText.getRootView().findViewById(android.R.id.button1) - .setEnabled(false); - } - } - } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunDeviceCoordinator.java index 6c33ca7e6..c660219a6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunDeviceCoordinator.java @@ -22,7 +22,6 @@ import android.content.Context; import android.net.Uri; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; @@ -34,6 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport; @@ -72,12 +72,6 @@ public class LefunDeviceCoordinator extends AbstractBLEDeviceCoordinator { return false; } - @Nullable - @Override - public Class getPairingActivity() { - return null; - } - @Override public boolean supportsActivityDataFetching() { return true; @@ -98,11 +92,6 @@ public class LefunDeviceCoordinator extends AbstractBLEDeviceCoordinator { return null; } - @Override - public boolean supportsScreenshots(final GBDevice device) { - return false; - } - @Override public int getAlarmSlotCount(GBDevice device) { return NUM_ALARM_SLOTS; @@ -118,34 +107,27 @@ public class LefunDeviceCoordinator extends AbstractBLEDeviceCoordinator { return MANUFACTURER_NAME; } - @Override - public boolean supportsAppsManagement(final GBDevice device) { - return false; - } - - @Override - public Class getAppsManagementActivity() { - return null; - } - - @Override - public boolean supportsCalendarEvents() { - return false; - } - @Override public boolean supportsRealtimeData() { return true; } @Override - public boolean supportsWeather() { - return false; + public boolean supportsFindDevice() { + return true; } @Override - public boolean supportsFindDevice() { - return true; + public BatteryConfig[] getBatteryConfig(final GBDevice device) { + return new BatteryConfig[]{ + new BatteryConfig( + 0, + GBDevice.BATTERY_ICON_DEFAULT, + GBDevice.BATTERY_LABEL_DEFAULT, + 15, + 100 + ) + }; } @Override @@ -167,13 +149,11 @@ public class LefunDeviceCoordinator extends AbstractBLEDeviceCoordinator { return LefunDeviceSupport.class; } - @Override public int getDeviceNameResource() { return R.string.devicetype_lefun; } - @Override public int getDefaultIconResource() { return R.drawable.ic_device_h30_h10; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java index 5d4ebcee2..5ffca1cb2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/nothing/AbstractEarCoordinator.java @@ -61,7 +61,7 @@ public abstract class AbstractEarCoordinator extends AbstractBLClassicDeviceCoor } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_tws_case, R.string.battery_case); BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_nothing_ear_l, R.string.left_earbud); BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_nothing_ear_r, R.string.right_earbud); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qc35/QC35Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qc35/QC35Coordinator.java index 3e9627b52..69bbb0ca7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qc35/QC35Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qc35/QC35Coordinator.java @@ -17,25 +17,18 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qc35; import android.app.Activity; -import android.content.Context; -import android.net.Uri; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLClassicDeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; -import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qc35.QC35BaseSupport; @@ -50,12 +43,6 @@ public class QC35Coordinator extends AbstractBLClassicDeviceCoordinator { return Pattern.compile("Bose QC 35.*"); } - @Nullable - @Override - public Class getPairingActivity() { - return null; - } - @Override public int[] getSupportedDeviceSpecificSettings(GBDevice device) { return new int[]{ @@ -69,82 +56,28 @@ public class QC35Coordinator extends AbstractBLClassicDeviceCoordinator { return QC35BaseSupport.class; } - @Override - public boolean supportsActivityDataFetching() { - return false; - } - - @Override - public boolean supportsActivityTracking() { - return false; - } - - @Override - public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { - return null; - } - - @Override - public InstallHandler findInstallHandler(Uri uri, Context context) { - return null; - } - - @Override - public boolean supportsScreenshots(final GBDevice device) { - return false; - } - - @Override - public int getAlarmSlotCount(GBDevice device) { - return 0; - } - - @Override - public boolean supportsHeartRateMeasurement(GBDevice device) { - return false; - } - @Override public String getManufacturer() { return "Bose"; } - @Override - public boolean supportsAppsManagement(final GBDevice device) { - return false; - } - - @Override - public Class getAppsManagementActivity() { - return null; - } - - @Override - public boolean supportsCalendarEvents() { - return false; - } - - @Override - public boolean supportsRealtimeData() { - return false; - } - - @Override - public boolean supportsWeather() { - return false; - } - - @Override - public boolean supportsFindDevice() { - return false; - } - - @Override public int getDeviceNameResource() { return R.string.devicetype_bose_qc35; } + @Override + public BatteryConfig[] getBatteryConfig(final GBDevice device) { + return new BatteryConfig[]{ + new BatteryConfig( + 0, + GBDevice.BATTERY_ICON_DEFAULT, + GBDevice.BATTERY_LABEL_DEFAULT, + 25, + 100 + ) + }; + } @Override public int getDefaultIconResource() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java index debff2c5e..cba18d037 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java @@ -25,7 +25,6 @@ import android.net.Uri; import android.os.ParcelUuid; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,12 +45,12 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpec import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; -import nodomain.freeyourgadget.gadgetbridge.devices.cmfwatchpro.CmfWatchProSettingsCustomizer; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; @@ -78,13 +77,6 @@ public class QHybridCoordinator extends AbstractBLEDeviceCoordinator { return Collections.singletonList(new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString("3dda0001-957f-7d4a-34a6-74696673696d")).build()); } - @Nullable - @Override - public Class getPairingActivity() { - return null; - } - - @Override public boolean supportsActivityDataFetching() { List devices = GBApplication.app().getDeviceManager().getSelectedDevices(); @@ -126,14 +118,6 @@ public class QHybridCoordinator extends AbstractBLEDeviceCoordinator { return installHandler.isValid() ? installHandler : null; } - @Override - public boolean supportsFlashing() { return false; } - - @Override - public boolean supportsScreenshots(final GBDevice device) { - return false; - } - private boolean supportsAlarmConfiguration() { List devices = GBApplication.app().getDeviceManager().getSelectedDevices(); LOG.debug("devices count: " + devices.size()); @@ -223,16 +207,6 @@ public class QHybridCoordinator extends AbstractBLEDeviceCoordinator { return ".wapp"; } - @Override - public boolean supportsCalendarEvents() { - return false; - } - - @Override - public boolean supportsRealtimeData() { - return false; - } - @Override public boolean supportsWeather() { return isHybridHR(); @@ -248,6 +222,19 @@ public class QHybridCoordinator extends AbstractBLEDeviceCoordinator { } + @Override + public BatteryConfig[] getBatteryConfig(final GBDevice device) { + return new BatteryConfig[]{ + new BatteryConfig( + 0, + GBDevice.BATTERY_ICON_DEFAULT, + GBDevice.BATTERY_LABEL_DEFAULT, + isHybridHR(device) ? 10 : 2, + 100 + ) + }; + } + @Override public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) { final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java index 61b8709f3..3443ef19f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/SonyHeadphonesCoordinator.java @@ -17,12 +17,7 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones; -import android.app.Activity; -import android.content.Context; -import android.net.Uri; - import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import org.apache.commons.lang3.ArrayUtils; @@ -38,12 +33,10 @@ import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLClassicDeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; 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.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones.SonyHeadphonesSupport; @@ -67,77 +60,6 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException { } - @Nullable - @Override - public Class getPairingActivity() { - return null; - } - - @Override - public boolean supportsActivityDataFetching() { - return false; - } - - @Override - public boolean supportsActivityTracking() { - return false; - } - - @Override - public SampleProvider getSampleProvider(GBDevice device, DaoSession session) { - return null; - } - - @Override - public InstallHandler findInstallHandler(Uri uri, Context context) { - return null; - } - - @Override - public boolean supportsScreenshots(final GBDevice device) { - return false; - } - - @Override - public int getAlarmSlotCount(GBDevice device) { - return 0; - } - - @Override - public boolean supportsHeartRateMeasurement(GBDevice device) { - return false; - } - - @Override - public boolean supportsAppsManagement(final GBDevice device) { - return false; - } - - @Override - public Class getAppsManagementActivity() { - return null; - } - - @Override - public boolean supportsCalendarEvents() { - return false; - } - - @Override - public boolean supportsRealtimeData() { - return false; - } - - @Override - public boolean supportsWeather() { - return false; - } - - @Override - public boolean supportsFindDevice() { - return false; - } - @Override public boolean supportsPowerOff() { return supports(SonyHeadphonesCapabilities.PowerOffFromPhone); @@ -170,6 +92,26 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC return batteryCount; } + @Override + public BatteryConfig[] getBatteryConfig(final GBDevice device) { + final List batteries = new ArrayList<>(3); + + if (supports(SonyHeadphonesCapabilities.BatterySingle)) { + batteries.add(new BatteryConfig(batteries.size())); + } + + if (supports(SonyHeadphonesCapabilities.BatteryCase)) { + batteries.add(new BatteryConfig(batteries.size(), R.drawable.ic_tws_case, R.string.battery_case)); + } + + if (supports(SonyHeadphonesCapabilities.BatteryDual)) { + batteries.add(new BatteryConfig(batteries.size(), R.drawable.ic_galaxy_buds_l, R.string.left_earbud)); + batteries.add(new BatteryConfig(batteries.size(), R.drawable.ic_galaxy_buds_r, R.string.right_earbud)); + } + + return batteries.toArray(new BatteryConfig[0]); + } + @Override public int[] getSupportedDeviceSpecificSettings(final GBDevice device) { final List settings = new ArrayList<>(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java index 10ba13b0e..dbec95e60 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM3Coordinator.java @@ -25,6 +25,7 @@ import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; @@ -36,7 +37,7 @@ public class SonyWF1000XM3Coordinator extends SonyHeadphonesCoordinator { } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { final BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_tws_case, R.string.battery_case); final BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_galaxy_buds_l, R.string.left_earbud); final BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_galaxy_buds_r, R.string.right_earbud); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM4Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM4Coordinator.java index 85260ac29..3eaddac4e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM4Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM4Coordinator.java @@ -23,6 +23,7 @@ import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; public class SonyWF1000XM4Coordinator extends SonyHeadphonesCoordinator { @@ -32,7 +33,7 @@ public class SonyWF1000XM4Coordinator extends SonyHeadphonesCoordinator { } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { final BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_tws_case, R.string.battery_case); final BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_galaxy_buds_l, R.string.left_earbud); final BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_galaxy_buds_r, R.string.right_earbud); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM5Coordinator.java index 413240901..284e8d086 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWF1000XM5Coordinator.java @@ -25,6 +25,7 @@ import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; @@ -36,7 +37,7 @@ public class SonyWF1000XM5Coordinator extends SonyHeadphonesCoordinator { } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { final BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_tws_case, R.string.battery_case); final BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_galaxy_buds_l, R.string.left_earbud); final BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_galaxy_buds_r, R.string.right_earbud); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java index 7b83dd49e..f1299617d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/sony/headphones/coordinators/SonyWFSP800NCoordinator.java @@ -25,9 +25,8 @@ import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCapabilities; import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.SonyHeadphonesCoordinator; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; -import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; public class SonyWFSP800NCoordinator extends SonyHeadphonesCoordinator { @Override @@ -36,7 +35,7 @@ public class SonyWFSP800NCoordinator extends SonyHeadphonesCoordinator { } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { final BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_sony_wf_800n_case, R.string.battery_case); final BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_sony_wf_800n_left, R.string.left_earbud); final BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_sony_wf_800n_right, R.string.right_earbud); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/SoundcoreLiberty3ProCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/SoundcoreLiberty3ProCoordinator.java index 096db6a3e..8beedf280 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/SoundcoreLiberty3ProCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/soundcore/SoundcoreLiberty3ProCoordinator.java @@ -58,7 +58,7 @@ public class SoundcoreLiberty3ProCoordinator extends AbstractDeviceCoordinator { } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_buds_pro_case, R.string.battery_case); BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_nothing_ear_l, R.string.left_earbud); BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_nothing_ear_r, R.string.right_earbud); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/test/TestDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/test/TestDeviceCoordinator.java index cd9cbe40f..09dfbd22a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/test/TestDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/test/TestDeviceCoordinator.java @@ -518,9 +518,9 @@ public class TestDeviceCoordinator extends AbstractDeviceCoordinator { } @Override - public BatteryConfig[] getBatteryConfig() { + public BatteryConfig[] getBatteryConfig(final GBDevice device) { if (getBatteryCount() == 1) { - return super.getBatteryConfig(); + return super.getBatteryConfig(device); } final BatteryConfig[] ret = new BatteryConfig[getBatteryCount()]; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java index 55308c9b8..66d304ec3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDevice.java @@ -64,7 +64,6 @@ public class GBDevice implements Parcelable { public static final short BATTERY_UNKNOWN = -1; public static final short BATTERY_ICON_DEFAULT = -1; public static final short BATTERY_LABEL_DEFAULT = -1; - private static final short BATTERY_THRESHOLD_PERCENT = 10; public static final String EXTRA_DEVICE = "device"; public static final String EXTRA_UUID = "extraUUID"; public static final String EXTRA_UPDATE_SUBJECT = "EXTRA_UPDATE_SUBJECT"; @@ -88,7 +87,6 @@ public class GBDevice implements Parcelable { // multiple battery support: at this point we support up to three batteries private int[] mBatteryLevel = {BATTERY_UNKNOWN, BATTERY_UNKNOWN, BATTERY_UNKNOWN}; private float[] mBatteryVoltage = {BATTERY_UNKNOWN, BATTERY_UNKNOWN, BATTERY_UNKNOWN}; - private short mBatteryThresholdPercent = BATTERY_THRESHOLD_PERCENT; private BatteryState[] mBatteryState = {UNKNOWN, UNKNOWN, UNKNOWN}; private int[] mBatteryIcons = {BATTERY_ICON_DEFAULT, BATTERY_ICON_DEFAULT, BATTERY_ICON_DEFAULT}; private int[] mBatteryLabels = {BATTERY_LABEL_DEFAULT, BATTERY_LABEL_DEFAULT, BATTERY_LABEL_DEFAULT}; @@ -136,7 +134,6 @@ public class GBDevice implements Parcelable { mState = State.values()[in.readInt()]; mBatteryLevel = in.createIntArray(); mBatteryVoltage = in.createFloatArray(); - mBatteryThresholdPercent = (short) in.readInt(); mBatteryState = ordinalsToEnums(in.createIntArray()); mBatteryIcons = in.createIntArray(); mBatteryLabels = in.createIntArray(); @@ -166,7 +163,6 @@ public class GBDevice implements Parcelable { mState = device.mState; mBatteryLevel = device.mBatteryLevel; mBatteryVoltage = device.mBatteryVoltage; - mBatteryThresholdPercent = device.mBatteryThresholdPercent; mBatteryState = device.mBatteryState; mBatteryIcons = device.mBatteryIcons; mBatteryLabels = device.mBatteryLabels; @@ -193,7 +189,6 @@ public class GBDevice implements Parcelable { dest.writeInt(mState.ordinal()); dest.writeIntArray(mBatteryLevel); dest.writeFloatArray(mBatteryVoltage); - dest.writeInt(mBatteryThresholdPercent); dest.writeIntArray(enumsToOrdinals(mBatteryState)); dest.writeIntArray(mBatteryIcons); dest.writeIntArray(mBatteryLabels); @@ -612,14 +607,6 @@ public class GBDevice implements Parcelable { this.mBatteryState[index] = mBatteryState; } - public short getBatteryThresholdPercent() { - return mBatteryThresholdPercent; - } - - public void setBatteryThresholdPercent(short batteryThresholdPercent) { - this.mBatteryThresholdPercent = batteryThresholdPercent; - } - public int getBatteryIcon(int index) { return this.mBatteryIcons[index]; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryConfig.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryConfig.java index 72a67c30f..dd03b3b4a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryConfig.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/BatteryConfig.java @@ -19,16 +19,29 @@ package nodomain.freeyourgadget.gadgetbridge.model; import java.util.Objects; -public class BatteryConfig { +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +public class BatteryConfig { private final int batteryIndex; private final int batteryIcon; private final int batteryLabel; + private final int defaultLowThreshold; + private final int defaultFullThreshold; + + public BatteryConfig(int batteryIndex) { + this(batteryIndex, GBDevice.BATTERY_ICON_DEFAULT, GBDevice.BATTERY_LABEL_DEFAULT); + } public BatteryConfig(int batteryIndex, int batteryIcon, int batteryLabel) { + this(batteryIndex, batteryIcon, batteryLabel, 10, 100); + } + + public BatteryConfig(final int batteryIndex, final int batteryIcon, final int batteryLabel, final int defaultLowThreshold, final int defaultFullThreshold) { this.batteryIndex = batteryIndex; this.batteryIcon = batteryIcon; this.batteryLabel = batteryLabel; + this.defaultLowThreshold = defaultLowThreshold; + this.defaultFullThreshold = defaultFullThreshold; } public int getBatteryIndex() { @@ -43,6 +56,14 @@ public class BatteryConfig { return batteryLabel; } + public int getDefaultLowThreshold() { + return defaultLowThreshold; + } + + public int getDefaultFullThreshold() { + return defaultFullThreshold; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index e8e024f38..10c7eeb2f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -92,6 +92,7 @@ import nodomain.freeyourgadget.gadgetbridge.externalevents.NotificationListener; import nodomain.freeyourgadget.gadgetbridge.externalevents.opentracks.OpenTracksController; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; +import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; @@ -112,6 +113,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.PendingIntentUtils; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.SilentMode; +import nodomain.freeyourgadget.gadgetbridge.util.preferences.DevicePrefs; import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_HIGH_PRIORITY_ID; @@ -529,36 +531,54 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { gbDevice.setBatteryState(deviceEvent.state); gbDevice.setBatteryVoltage(deviceEvent.voltage, deviceEvent.batteryIndex); + final DevicePrefs devicePrefs = GBApplication.getDevicePrefs(gbDevice.getAddress()); + final BatteryConfig batteryConfig = gbDevice.getDeviceCoordinator().getBatteryConfig(gbDevice)[deviceEvent.batteryIndex]; + if (deviceEvent.level == GBDevice.BATTERY_UNKNOWN) { // no level available, just "high" or "low" - if (BatteryState.BATTERY_LOW.equals(deviceEvent.state)) { - GB.updateBatteryNotification(context.getString(R.string.notif_battery_low, gbDevice.getAliasOrName()), + GB.removeBatteryFullNotification(context); + if (devicePrefs.getBatteryNotifyLowEnabled(batteryConfig) && BatteryState.BATTERY_LOW.equals(deviceEvent.state)) { + GB.updateBatteryLowNotification(context.getString(R.string.notif_battery_low, gbDevice.getAliasOrName()), deviceEvent.extendedInfoAvailable() ? context.getString(R.string.notif_battery_low_extended, gbDevice.getAliasOrName(), context.getString(R.string.notif_battery_low_bigtext_last_charge_time, DateFormat.getDateTimeInstance().format(deviceEvent.lastChargeTime.getTime())) + context.getString(R.string.notif_battery_low_bigtext_number_of_charges, String.valueOf(deviceEvent.numCharges))) : "" , context); + } else if (devicePrefs.getBatteryNotifyFullEnabled(batteryConfig) && BatteryState.BATTERY_CHARGING_FULL.equals(deviceEvent.state)) { + GB.removeBatteryLowNotification(context); + GB.updateBatteryFullNotification(context.getString(R.string.notif_battery_full, gbDevice.getAliasOrName()), "", context); } else { - GB.removeBatteryNotification(context); + GB.removeBatteryLowNotification(context); + GB.removeBatteryFullNotification(context); } } else { createStoreTask("Storing battery data", context, deviceEvent).execute(); + final boolean batteryNotifyLowEnabled = devicePrefs.getBatteryNotifyLowEnabled(batteryConfig); + final boolean isBatteryLow = deviceEvent.level <= devicePrefs.getBatteryNotifyLowThreshold(batteryConfig) && + (BatteryState.BATTERY_LOW.equals(deviceEvent.state) || BatteryState.BATTERY_NORMAL.equals(deviceEvent.state)); + + final boolean batteryNotifyFullEnabled = devicePrefs.getBatteryNotifyFullEnabled(batteryConfig); + final boolean isBatteryFull = deviceEvent.level >= devicePrefs.getBatteryNotifyFullThreshold(batteryConfig) && + (BatteryState.BATTERY_CHARGING.equals(deviceEvent.state) || BatteryState.BATTERY_CHARGING_FULL.equals(deviceEvent.state)); + //show the notification if the battery level is below threshold and only if not connected to charger - if (deviceEvent.level <= gbDevice.getBatteryThresholdPercent() && - (BatteryState.BATTERY_LOW.equals(deviceEvent.state) || - BatteryState.BATTERY_NORMAL.equals(deviceEvent.state)) - ) { - GB.updateBatteryNotification(context.getString(R.string.notif_battery_low_percent, gbDevice.getAliasOrName(), String.valueOf(deviceEvent.level)), + if (batteryNotifyLowEnabled && isBatteryLow) { + GB.removeBatteryFullNotification(context); + GB.updateBatteryLowNotification(context.getString(R.string.notif_battery_low_percent, gbDevice.getAliasOrName(), String.valueOf(deviceEvent.level)), deviceEvent.extendedInfoAvailable() ? context.getString(R.string.notif_battery_low_percent, gbDevice.getAliasOrName(), String.valueOf(deviceEvent.level)) + "\n" + context.getString(R.string.notif_battery_low_bigtext_last_charge_time, DateFormat.getDateTimeInstance().format(deviceEvent.lastChargeTime.getTime())) + context.getString(R.string.notif_battery_low_bigtext_number_of_charges, String.valueOf(deviceEvent.numCharges)) : "" , context); + } else if (batteryNotifyFullEnabled && isBatteryFull) { + GB.removeBatteryLowNotification(context); + GB.updateBatteryFullNotification(context.getString(R.string.notif_battery_full, gbDevice.getAliasOrName()), "", context); } else { - GB.removeBatteryNotification(context); + GB.removeBatteryLowNotification(context); + GB.removeBatteryFullNotification(context); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java index f1adfe8aa..362e7dae8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java @@ -334,7 +334,6 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport { gbDevice.setState(GBDevice.State.INITIALIZING); gbDevice.sendDeviceUpdateIntent(getContext()); - gbDevice.setBatteryThresholdPercent((short) 15); rxCharacteristic = getCharacteristic(BangleJSConstants.UUID_CHARACTERISTIC_NORDIC_UART_RX); txCharacteristic = getCharacteristic(BangleJSConstants.UUID_CHARACTERISTIC_NORDIC_UART_TX); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/GetBatteryLevelRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/GetBatteryLevelRequest.java index 01abed039..df0bc08a3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/GetBatteryLevelRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/GetBatteryLevelRequest.java @@ -19,7 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants; import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.GetBatteryLevelCommand; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus; @@ -40,9 +39,6 @@ public class GetBatteryLevelRequest extends Request { GetBatteryLevelCommand cmd = new GetBatteryLevelCommand(); cmd.deserialize(data); - GBDevice device = getSupport().getDevice(); - device.setBatteryThresholdPercent((short)15); - GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo(); batteryInfo.level = (short)((int)cmd.getBatteryLevel() & 0xff); getSupport().evaluateGBDeviceEvent(batteryInfo); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qc35/QC35BaseSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qc35/QC35BaseSupport.java index cadd38a6c..808e41201 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qc35/QC35BaseSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qc35/QC35BaseSupport.java @@ -16,12 +16,6 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.qc35; -import android.net.Uri; - -import java.util.ArrayList; -import java.util.UUID; - -import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread; import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol; @@ -32,7 +26,6 @@ public class QC35BaseSupport extends AbstractSerialDeviceSupport { public boolean connect() { getDeviceProtocol(); getDeviceIOThread().start(); - getDevice().setBatteryThresholdPercent((short)25); return true; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java index be9f9e160..1b84873c0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java @@ -783,8 +783,6 @@ public class QHybridSupport extends QHybridBaseSupport { short level = characteristic.getValue()[0]; gbDevice.setBatteryLevel(level); - gbDevice.setBatteryThresholdPercent((short) 2); - GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo(); batteryInfo.level = gbDevice.getBatteryLevel(); batteryInfo.state = BatteryState.BATTERY_NORMAL; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/misfit/MisfitWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/misfit/MisfitWatchAdapter.java index 007cdc84c..8f8bde0b0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/misfit/MisfitWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/misfit/MisfitWatchAdapter.java @@ -169,8 +169,6 @@ public class MisfitWatchAdapter extends WatchAdapter { short level = characteristic.getValue()[0]; gbDevice.setBatteryLevel(level); - gbDevice.setBatteryThresholdPercent((short) 2); - GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo(); batteryInfo.level = gbDevice.getBatteryLevel(); batteryInfo.state = BatteryState.BATTERY_NORMAL; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/configuration/ConfigurationGetRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/configuration/ConfigurationGetRequest.java index 53087a75d..d9d49c1f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/configuration/ConfigurationGetRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/configuration/ConfigurationGetRequest.java @@ -59,7 +59,6 @@ public class ConfigurationGetRequest extends FileEncryptedLookupAndGetRequest im }else if(item instanceof ConfigurationPutRequest.BatteryConfigItem){ device.setBatteryLevel((short) ((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryPercentage()); device.setBatteryVoltage(((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryVoltage() / 1000f); - device.setBatteryThresholdPercent((short) 10); GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo(); batteryInfo.level = (short) ((ConfigurationPutRequest.BatteryConfigItem) item).getBatteryPercentage(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java index c5ff4c44d..041d7de6a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java @@ -194,7 +194,7 @@ public class DeviceHelper { DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName()); GBDevice gbDevice = new GBDevice(dbDevice.getIdentifier(), dbDevice.getName(), dbDevice.getAlias(), dbDevice.getParentFolder(), deviceType); DeviceCoordinator coordinator = gbDevice.getDeviceCoordinator(); - for (BatteryConfig batteryConfig : coordinator.getBatteryConfig()) { + for (BatteryConfig batteryConfig : coordinator.getBatteryConfig(gbDevice)) { gbDevice.setBatteryIcon(batteryConfig.getBatteryIcon(), batteryConfig.getBatteryIndex()); gbDevice.setBatteryLabel(batteryConfig.getBatteryLabel(), batteryConfig.getBatteryIndex()); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java index 41df59403..a85d44f28 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java @@ -49,6 +49,7 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -62,6 +63,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; +import nodomain.freeyourgadget.gadgetbridge.util.preferences.DevicePrefs; public class GB { public static final String ACTION_ACTIVITY_SYNC = "nodomain.freeyourgadget.gadgetbridge.action.ACTIVITY_SYNC_FINISH"; @@ -72,6 +74,7 @@ public class GB { public static final String NOTIFICATION_CHANNEL_HIGH_PRIORITY_ID = "gadgetbridge_high_priority"; public static final String NOTIFICATION_CHANNEL_ID_TRANSFER = "gadgetbridge transfer"; public static final String NOTIFICATION_CHANNEL_ID_LOW_BATTERY = "low_battery"; + public static final String NOTIFICATION_CHANNEL_ID_FULL_BATTERY = "full_battery"; public static final String NOTIFICATION_CHANNEL_ID_GPS = "gps"; public static final int NOTIFICATION_ID = 1; @@ -82,6 +85,7 @@ public class GB { public static final int NOTIFICATION_ID_PHONE_FIND = 6; public static final int NOTIFICATION_ID_GPS = 7; public static final int NOTIFICATION_ID_SCAN = 8; + public static final int NOTIFICATION_ID_FULL_BATTERY = 9; public static final int NOTIFICATION_ID_ERROR = 42; private static final Logger LOG = LoggerFactory.getLogger(GB.class); @@ -147,6 +151,12 @@ public class GB { NotificationManager.IMPORTANCE_DEFAULT); notificationManager.createNotificationChannel(channelLowBattery); + NotificationChannel channelFullBattery = new NotificationChannel( + NOTIFICATION_CHANNEL_ID_FULL_BATTERY, + context.getString(R.string.notification_channel_full_battery_name), + NotificationManager.IMPORTANCE_DEFAULT); + notificationManager.createNotificationChannel(channelFullBattery); + NotificationChannel channelGps = new NotificationChannel( NOTIFICATION_CHANNEL_ID_GPS, context.getString(R.string.notification_channel_gps), @@ -183,9 +193,8 @@ public class GB { GBDevice device = devices.get(0); String deviceName = device.getAliasOrName(); String text = device.getStateString(); - if (device.getBatteryLevel() != GBDevice.BATTERY_UNKNOWN) { - text += ": " + context.getString(R.string.battery) + " " + device.getBatteryLevel() + "%"; - } + + text += buildDeviceBatteryString(context, device); boolean connected = device.isInitialized(); builder.setContentTitle(deviceName) @@ -230,9 +239,7 @@ public class GB { String deviceName = device.getAliasOrName(); String text = device.getStateString(); - if (device.getBatteryLevel() != GBDevice.BATTERY_UNKNOWN) { - text += ": " + context.getString(R.string.battery) + " " + device.getBatteryLevel() + "%"; - } + text += buildDeviceBatteryString(context, device); contentText.append(deviceName).append(" (").append(text).append(")
"); } @@ -271,6 +278,29 @@ public class GB { return builder.build(); } + public static String buildDeviceBatteryString(final Context context, final GBDevice device) { + final DevicePrefs devicePrefs = GBApplication.getDevicePrefs(device.getAddress()); + final List batteryLevels = new ArrayList<>(); + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 3; i++) { + if (devicePrefs.getBatteryShowInNotification(i) && device.getBatteryLevel(i) != GBDevice.BATTERY_UNKNOWN) { + batteryLevels.add(device.getBatteryLevel(i)); + } + } + if (!batteryLevels.isEmpty()) { + sb.append(": ").append(context.getString(R.string.battery)).append(" "); + + for (int i = 0; i < batteryLevels.size(); i++) { + sb.append(batteryLevels.get(i)).append("%"); + if (i + 1 < batteryLevels.size()) { + sb.append(", "); + } + } + } + + return sb.toString(); + } + public static Notification createNotification(String text, Context context) { NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID_CONNECTION_STATUS); builder.setTicker(text) @@ -532,7 +562,7 @@ public class GB { notify(NOTIFICATION_ID_INSTALL, notification, context); } - private static Notification createBatteryNotification(String text, String bigText, Context context) { + private static Notification createBatteryLowNotification(String text, String bigText, Context context) { Intent notificationIntent = new Intent(context, ControlCenterv2.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); @@ -554,18 +584,52 @@ public class GB { return nb.build(); } - public static void updateBatteryNotification(String text, String bigText, Context context) { + private static Notification createBatteryFullNotification(String text, String bigText, Context context) { + Intent notificationIntent = new Intent(context, ControlCenterv2.class); + notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_CLEAR_TASK); + PendingIntent pendingIntent = PendingIntentUtils.getActivity(context, 0, + notificationIntent, 0, false); + + NotificationCompat.Builder nb = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID_FULL_BATTERY) + .setContentTitle(context.getString(R.string.notif_battery_full_title)) + .setContentText(text) + .setContentIntent(pendingIntent) + .setSmallIcon(R.drawable.ic_notification_full_battery) + .setPriority(Notification.PRIORITY_HIGH) + .setOngoing(false); + + if (bigText != null) { + nb.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText)); + } + + return nb.build(); + } + + public static void updateBatteryLowNotification(String text, String bigText, Context context) { if (GBEnvironment.env().isLocalTest()) { return; } - Notification notification = createBatteryNotification(text, bigText, context); + Notification notification = createBatteryLowNotification(text, bigText, context); notify(NOTIFICATION_ID_LOW_BATTERY, notification, context); } - public static void removeBatteryNotification(Context context) { + public static void removeBatteryLowNotification(Context context) { removeNotification(NOTIFICATION_ID_LOW_BATTERY, context); } + public static void updateBatteryFullNotification(String text, String bigText, Context context) { + if (GBEnvironment.env().isLocalTest()) { + return; + } + Notification notification = createBatteryFullNotification(text, bigText, context); + notify(NOTIFICATION_ID_FULL_BATTERY, notification, context); + } + + public static void removeBatteryFullNotification(Context context) { + removeNotification(NOTIFICATION_ID_FULL_BATTERY, context); + } + public static Notification createExportFailedNotification(String text, Context context) { Intent notificationIntent = new Intent(context, SettingsActivity.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/preferences/DevicePrefs.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/preferences/DevicePrefs.java new file mode 100644 index 000000000..df76dec38 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/preferences/DevicePrefs.java @@ -0,0 +1,34 @@ +package nodomain.freeyourgadget.gadgetbridge.util.preferences; + +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.*; + +import android.content.SharedPreferences; + +import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; + +public class DevicePrefs extends Prefs { + public DevicePrefs(final SharedPreferences preferences) { + super(preferences); + } + + public boolean getBatteryShowInNotification(final int batteryIndex) { + return getBoolean(PREF_BATTERY_SHOW_IN_NOTIFICATION + batteryIndex, true); + } + + public boolean getBatteryNotifyLowEnabled(final BatteryConfig batteryConfig) { + return getBoolean(PREF_BATTERY_NOTIFY_LOW_ENABLED + batteryConfig.getBatteryIndex(), true); + } + + public int getBatteryNotifyLowThreshold(final BatteryConfig batteryConfig) { + return getInt(PREF_BATTERY_NOTIFY_LOW_THRESHOLD + batteryConfig.getBatteryIndex(), batteryConfig.getDefaultLowThreshold()); + } + + public boolean getBatteryNotifyFullEnabled(final BatteryConfig batteryConfig) { + return getBoolean(PREF_BATTERY_NOTIFY_FULL_ENABLED + batteryConfig.getBatteryIndex(), true); + } + + public int getBatteryNotifyFullThreshold(final BatteryConfig batteryConfig) { + return getInt(PREF_BATTERY_NOTIFY_FULL_THRESHOLD + batteryConfig.getBatteryIndex(), batteryConfig.getDefaultFullThreshold()); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/preferences/GBSimpleSummaryProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/preferences/GBSimpleSummaryProvider.java new file mode 100644 index 000000000..3035f6886 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/preferences/GBSimpleSummaryProvider.java @@ -0,0 +1,40 @@ +package nodomain.freeyourgadget.gadgetbridge.util.preferences; + +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.preference.EditTextPreference; +import androidx.preference.Preference; + +/** + * Like the EditTextPreference.SimpleSummaryProvider, but with a customizable not-set string. + */ +public final class GBSimpleSummaryProvider implements Preference.SummaryProvider { + private final String defaultText; + + @StringRes + private final int templateString; + + public GBSimpleSummaryProvider(final String defaultText) { + this(defaultText, 0); + } + + public GBSimpleSummaryProvider(final String defaultText, final int templateString) { + this.defaultText = defaultText; + this.templateString = templateString; + } + + @Nullable + @Override + public CharSequence provideSummary(@NonNull final EditTextPreference preference) { + if (TextUtils.isEmpty(preference.getText())) { + return defaultText; + } else if (templateString != 0) { + return preference.getContext().getString(templateString, preference.getText()); + } else { + return preference.getText(); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/preferences/MinMaxTextWatcher.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/preferences/MinMaxTextWatcher.java new file mode 100644 index 000000000..1dcb897e5 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/preferences/MinMaxTextWatcher.java @@ -0,0 +1,59 @@ +package nodomain.freeyourgadget.gadgetbridge.util.preferences; + +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.widget.EditText; + +import nodomain.freeyourgadget.gadgetbridge.R; + +public class MinMaxTextWatcher implements TextWatcher { + private final EditText editText; + private final int min; + private final int max; + private final boolean allowEmpty; + + public MinMaxTextWatcher(final EditText editText, final int min, final int max) { + this(editText, min, max, false); + } + + public MinMaxTextWatcher(final EditText editText, final int min, final int max, final boolean allowEmpty) { + this.editText = editText; + this.min = min; + this.max = max; + this.allowEmpty = allowEmpty; + } + + @Override + public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) { + } + + @Override + public void onTextChanged(final CharSequence s, final int start, final int before, final int count) { + } + + @Override + public void afterTextChanged(final Editable editable) { + if (TextUtils.isEmpty(editable.toString()) && allowEmpty) { + editText.getRootView().findViewById(android.R.id.button1) + .setEnabled(true); + return; + } + + try { + final int val = Integer.parseInt(editable.toString()); + editText.getRootView().findViewById(android.R.id.button1) + .setEnabled(val >= min && val <= max); + if (val < min) { + editText.setError(editText.getContext().getString(R.string.min_val, min)); + } else if (val > max) { + editText.setError(editText.getContext().getString(R.string.max_val, max)); + } else { + editText.setError(null); + } + } catch (final NumberFormatException e) { + editText.getRootView().findViewById(android.R.id.button1) + .setEnabled(false); + } + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_notification_full_battery.png b/app/src/main/res/drawable-hdpi/ic_notification_full_battery.png new file mode 100644 index 000000000..6a5d25c29 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_notification_full_battery.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_notification_full_battery.png b/app/src/main/res/drawable-mdpi/ic_notification_full_battery.png new file mode 100644 index 000000000..b8270c7d2 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_notification_full_battery.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_notification_full_battery.png b/app/src/main/res/drawable-xhdpi/ic_notification_full_battery.png new file mode 100644 index 000000000..3c5c84d69 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_notification_full_battery.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_notification_full_battery.png b/app/src/main/res/drawable-xxhdpi/ic_notification_full_battery.png new file mode 100644 index 000000000..b10c3ca6b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_notification_full_battery.png differ diff --git a/app/src/main/res/drawable/ic_battery.xml b/app/src/main/res/drawable/ic_battery.xml new file mode 100644 index 000000000..37c6193aa --- /dev/null +++ b/app/src/main/res/drawable/ic_battery.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 52c228b75..9d54d9bce 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -827,10 +827,12 @@ Unable to install the given firmware: It doesn\'t match your Pebble\'s hardware revision. Please wait while determining the installation status… Gadget battery Low! + Gadget battery Full! %1$s battery left: %2$s%% Last charge: %s \n Number of charges: %s %1$s battery low + %1$s battery full %1$s battery low: %2$s Export database failed! Please check your settings. Charts tabs @@ -1603,6 +1605,7 @@ High-priority Data transfer Low battery + Full battery GPS tracking Gadgetbridge GPS Sending GPS location to %1$d devices @@ -2214,6 +2217,7 @@ Switch control left Switch control right Touch Options + Battery %d Battery case Left earbud Right earbud @@ -2900,4 +2904,11 @@ Unsupported Minimum: %d Maximum: %d + Show in notification + Notify on low battery + Low battery threshold + Notify on full battery + Full battery threshold + Default (%1$d%%) + %1$s%% diff --git a/app/src/main/res/xml/devicesettings_root_battery.xml b/app/src/main/res/xml/devicesettings_root_battery.xml new file mode 100644 index 000000000..4d167ef58 --- /dev/null +++ b/app/src/main/res/xml/devicesettings_root_battery.xml @@ -0,0 +1,9 @@ + + + + +