diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java deleted file mode 100644 index ec7d123b4..000000000 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java +++ /dev/null @@ -1,250 +0,0 @@ -/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Christian - Fischer, Daniele Gobbetti, José Rebelo, Lem Dulfo, Petr Vaněk, Taavi Eomäe - - 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.activities; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.preference.EditTextPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceManager; -import android.text.InputType; -import android.view.MenuItem; - -import androidx.core.app.NavUtils; -import androidx.localbroadcastmanager.content.LocalBroadcastManager; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Locale; - -import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; -import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils; - -/** - * A settings activity with support for preferences directly displaying their value. - * If you combine such preferences with a custom OnPreferenceChangeListener, you have - * to set that listener in #onCreate, *not* in #onPostCreate, otherwise the value will - * not be displayed. - * - * @deprecated use AbstractSettingsActivityV2 - */ -@Deprecated -public abstract class AbstractSettingsActivity extends AppCompatPreferenceActivity implements GBActivity { - - private static final Logger LOG = LoggerFactory.getLogger(AbstractSettingsActivity.class); - - private boolean isLanguageInvalid = false; - - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - switch (action) { - case GBApplication.ACTION_LANGUAGE_CHANGE: - setLanguage(GBApplication.getLanguage(), true); - break; - case GBApplication.ACTION_QUIT: - finish(); - break; - } - } - }; - - - /** - * A preference value change listener that updates the preference's summary - * to reflect its new value. - */ - private static class SimpleSetSummaryOnChangeListener implements Preference.OnPreferenceChangeListener { - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - if (preference instanceof EditTextPreference) { - if ((((EditTextPreference) preference).getEditText().getKeyListener().getInputType() & InputType.TYPE_CLASS_NUMBER) != 0) { - if ("".equals(String.valueOf(value))) { - // reject empty numeric input - return false; - } - } - } - updateSummary(preference, value); - return true; - } - - public void updateSummary(Preference preference, Object value) { - String stringValue = String.valueOf(value); - - if (preference instanceof ListPreference) { - // For list preferences, look up the correct display value in - // the preference's 'entries' list. - ListPreference listPreference = (ListPreference) preference; - int index = listPreference.findIndexOfValue(stringValue); - - // Set the summary to reflect the new value. - preference.setSummary( - index >= 0 - ? listPreference.getEntries()[index] - : null); - - } else { - // For all other preferences, set the summary to the value's - // simple string representation. - preference.setSummary(stringValue); - } - } - } - - private static class ExtraSetSummaryOnChangeListener extends SimpleSetSummaryOnChangeListener { - private final Preference.OnPreferenceChangeListener prefChangeListener; - - public ExtraSetSummaryOnChangeListener(Preference.OnPreferenceChangeListener prefChangeListener) { - this.prefChangeListener = prefChangeListener; - } - - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - boolean result = prefChangeListener.onPreferenceChange(preference, value); - if (result) { - return super.onPreferenceChange(preference, value); - } - return false; - } - } - - private static final SimpleSetSummaryOnChangeListener sBindPreferenceSummaryToValueListener = new SimpleSetSummaryOnChangeListener(); - - @Override - protected void onCreate(Bundle savedInstanceState) { - AbstractGBActivity.init(this); - - IntentFilter filterLocal = new IntentFilter(); - filterLocal.addAction(GBApplication.ACTION_QUIT); - filterLocal.addAction(GBApplication.ACTION_LANGUAGE_CHANGE); - LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal); - - super.onCreate(savedInstanceState); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - - for (String prefKey : getPreferenceKeysWithSummary()) { - final Preference pref = findPreference(prefKey); - if (pref != null) { - bindPreferenceSummaryToValue(pref); - } else { - LOG.error("Unknown preference key: " + prefKey + ", unable to display value."); - } - } - } - - @Override - protected void onResume() { - super.onResume(); - if (isLanguageInvalid) { - isLanguageInvalid = false; - recreate(); - } - } - - @Override - protected void onDestroy() { - LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver); - super.onDestroy(); - } - - /** - * Subclasses should reimplement this to return the keys of those - * preferences which should print its values as a summary below the - * preference name. - */ - protected String[] getPreferenceKeysWithSummary() { - return new String[0]; - } - - /** - * Binds a preference's summary to its value. More specifically, when the - * preference's value is changed, its summary (line of text below the - * preference title) is updated to reflect the value. The summary is also - * immediately updated upon calling this method. The exact display format is - * dependent on the type of preference. - * - * @see #sBindPreferenceSummaryToValueListener - */ - private static void bindPreferenceSummaryToValue(Preference preference) { - // Set the listener to watch for value changes. - SimpleSetSummaryOnChangeListener listener; - Preference.OnPreferenceChangeListener existingListener = preference.getOnPreferenceChangeListener(); - if (existingListener != null) { - listener = new ExtraSetSummaryOnChangeListener(existingListener); - } else { - listener = sBindPreferenceSummaryToValueListener; - } - preference.setOnPreferenceChangeListener(listener); - - // Trigger the listener immediately with the preference's current value. - try { - listener.updateSummary(preference, - PreferenceManager - .getDefaultSharedPreferences(preference.getContext()) - .getString(preference.getKey(), "")); - } catch (ClassCastException cce) { - //the preference is not a string, use the provided summary - //TODO: it shows true/false instead of the xml summary - listener.updateSummary(preference, preference.getSummary()); - } - } - - @Override - public boolean onOptionsItemSelected(final MenuItem item) { - final int itemId = item.getItemId(); - if (itemId == android.R.id.home) { - NavUtils.navigateUpFromSameTask(this); - return true; - } - return super.onOptionsItemSelected(item); - } - - public void setLanguage(Locale language, boolean invalidateLanguage) { - if (invalidateLanguage) { - isLanguageInvalid = true; - } - AndroidUtils.setLanguage(this, language); - } - - protected void addPreferenceHandlerFor(final String preferenceKey) { - Preference pref = findPreference(preferenceKey); - if (pref != null) { - pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newVal) { - GBApplication.deviceService().onSendConfiguration(preferenceKey); - return true; - } - }); - } else { - LOG.warn("Could not find preference " + preferenceKey); - } - } -} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java index 497593f6e..de7daf623 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java @@ -412,10 +412,6 @@ public class ControlCenterv2 extends AppCompatActivity final Intent dbIntent = new Intent(this, DataManagementActivity.class); startActivity(dbIntent); return false; - } else if (itemId == R.id.action_notification_management) { - final Intent blIntent = new Intent(this, NotificationManagementActivity.class); - startActivity(blIntent); - return false; } else if (itemId == R.id.device_action_discover) { launchDiscoveryActivity(); return false; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/NotificationManagementActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/NotificationManagementActivity.java index a03752769..fd04ebd45 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/NotificationManagementActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/NotificationManagementActivity.java @@ -22,7 +22,6 @@ import android.net.Uri; import android.os.Bundle; import android.provider.Settings; -import androidx.fragment.app.Fragment; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceFragmentCompat; @@ -36,7 +35,6 @@ import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class NotificationManagementActivity extends AbstractSettingsActivityV2 { - private static final Logger LOG = LoggerFactory.getLogger(NotificationManagementActivity.class); private static final int RINGTONE_REQUEST_CODE = 4712; private static final String DEFAULT_RINGTONE_URI = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE).toString(); @@ -51,6 +49,8 @@ public class NotificationManagementActivity extends AbstractSettingsActivityV2 { } public static class NotificationPreferencesFragment extends AbstractPreferenceFragment { + private static final Logger LOG = LoggerFactory.getLogger(NotificationPreferencesFragment.class); + static final String FRAGMENT_TAG = "NOTIFICATION_PREFERENCES_FRAGMENT"; @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java index 25da4f76d..4483dc172 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java @@ -381,6 +381,15 @@ public class SettingsActivity extends AbstractSettingsActivityV2 { }); } + pref = findPreference("pref_category_notifications"); + if (pref != null) { + pref.setOnPreferenceClickListener(preference -> { + Intent enableIntent = new Intent(requireContext(), NotificationManagementActivity.class); + startActivity(enableIntent); + return true; + }); + } + final Preference theme = findPreference("pref_key_theme"); final Preference amoled_black = findPreference("pref_key_theme_amoled_black"); @@ -558,7 +567,7 @@ public class SettingsActivity extends AbstractSettingsActivityV2 { private void setLocationPreferences(Location location) { String latitude = String.format(Locale.US, "%.6g", location.getLatitude()); String longitude = String.format(Locale.US, "%.6g", location.getLongitude()); - LOG.info("got location. Lat: " + latitude + " Lng: " + longitude); + LOG.info("got location. Lat: {} Lng: {}", latitude, longitude); GB.toast(requireContext(), getString(R.string.toast_aqurired_networklocation), 2000, 0); GBApplication.getPrefs().getPreferences() .edit() diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsPreferencesActivity.java index 2c8a8ec67..9addbe151 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsPreferencesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsPreferencesActivity.java @@ -20,16 +20,25 @@ import android.content.Intent; import android.os.Bundle; import android.text.InputType; +import androidx.annotation.NonNull; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; +import com.mobeta.android.dslv.DragSortListPreference; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.AboutUserPreferencesActivity; import nodomain.freeyourgadget.gadgetbridge.activities.AbstractPreferenceFragment; import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivityV2; +import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; +import nodomain.freeyourgadget.gadgetbridge.util.preferences.DevicePrefs; public class ChartsPreferencesActivity extends AbstractSettingsActivityV2 { + private GBDevice device; + @Override protected String fragmentTag() { return ChartsPreferencesFragment.FRAGMENT_TAG; @@ -37,16 +46,63 @@ public class ChartsPreferencesActivity extends AbstractSettingsActivityV2 { @Override protected PreferenceFragmentCompat newFragment() { - return new ChartsPreferencesFragment(); + return ChartsPreferencesFragment.newInstance(device); + } + + @Override + protected void onCreate(final Bundle savedInstanceState) { + device = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE); + + super.onCreate(savedInstanceState); } public static class ChartsPreferencesFragment extends AbstractPreferenceFragment { static final String FRAGMENT_TAG = "CHARTS_PREFERENCES_FRAGMENT"; + private GBDevice device; + + static ChartsPreferencesFragment newInstance(final GBDevice device) { + final ChartsPreferencesFragment fragment = new ChartsPreferencesFragment(); + fragment.setDevice(device); + return fragment; + } + + private void setDevice(final GBDevice device) { + final Bundle args = getArguments() != null ? getArguments() : new Bundle(); + args.putParcelable("device", device); + setArguments(args); + } + @Override public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { + final Bundle arguments = getArguments(); + if (arguments != null) { + this.device = arguments.getParcelable(GBDevice.EXTRA_DEVICE); + } + setPreferencesFromResource(R.xml.charts_preferences, rootKey); + // If a device was provided, show the charts tabs preference, since that's the only one + // that is device-specific for now. We also sync changes to the device-specific preference. + //final DragSortListPreference prefChartsTabs = findPreference(DeviceSettingsPreferenceConst.PREFS_DEVICE_CHARTS_TABS); + //if (prefChartsTabs != null) { + // if (device != null) { + // final DevicePrefs devicePrefs = GBApplication.getDevicePrefs(device.getAddress()); + // final String myTabs = devicePrefs.getString(DeviceSettingsPreferenceConst.PREFS_DEVICE_CHARTS_TABS, null); + // if (myTabs != null) { + // prefChartsTabs.setValue(myTabs); + // } + // prefChartsTabs.setOnPreferenceChangeListener((preference, newValue) -> { + // devicePrefs.getPreferences().edit() + // .putString(DeviceSettingsPreferenceConst.PREFS_DEVICE_CHARTS_TABS, String.valueOf(newValue)) + // .apply(); + // return true; + // }); + // } else { + // prefChartsTabs.setVisible(false); + // } + //} + setInputTypeFor(GBPrefs.CHART_MAX_HEART_RATE, InputType.TYPE_CLASS_NUMBER); setInputTypeFor(GBPrefs.CHART_MIN_HEART_RATE, InputType.TYPE_CLASS_NUMBER); setInputTypeFor("chart_sleep_lines_limit", InputType.TYPE_CLASS_NUMBER); @@ -57,11 +113,18 @@ public class ChartsPreferencesActivity extends AbstractSettingsActivityV2 { final Preference aboutUserPref = findPreference("pref_category_activity_personal"); if (aboutUserPref != null) { - aboutUserPref.setOnPreferenceClickListener(preference -> { - final Intent enableIntent = new Intent(getActivity(), AboutUserPreferencesActivity.class); - startActivity(enableIntent); - return true; - }); + if (device != null) { + aboutUserPref.setOnPreferenceClickListener(preference -> { + final Intent enableIntent = new Intent(getActivity(), AboutUserPreferencesActivity.class); + startActivity(enableIntent); + return true; + }); + } else { + final Preference aboutUserHeader = findPreference("pref_category_activity_personal_title"); + if (aboutUserHeader != null) { + aboutUserHeader.setVisible(false); + } + } } } } diff --git a/app/src/main/res/drawable/ic_navigation.xml b/app/src/main/res/drawable/ic_navigation.xml new file mode 100644 index 000000000..47548d8a1 --- /dev/null +++ b/app/src/main/res/drawable/ic_navigation.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_paint.xml b/app/src/main/res/drawable/ic_paint.xml new file mode 100644 index 000000000..b5d7741c4 --- /dev/null +++ b/app/src/main/res/drawable/ic_paint.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_report.xml b/app/src/main/res/drawable/ic_report.xml new file mode 100644 index 000000000..6b84b9fa3 --- /dev/null +++ b/app/src/main/res/drawable/ic_report.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index f723eb899..0dd3a5a7c 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -13,9 +13,6 @@ - Broadcast Media Button Intents Directly Enable if device media control is not working for certain applications Preferred Audioplayer + Navigation apps + External Integrations + Automations + Startup, language, region, location + Date of birth, gender, height, weight, goals + App notifications, whitelist/blacklist + Theme, main screen + Widgets, devices to include + Auto export, auto fetch + Logs, Intent API + Settings that will be removed in a future version Default Date and Time Sync time Sync time to Gadgetbridge device(s) when connecting, when time or time zone changes on Android device, and periodically + Main screen Theme Light Dark @@ -232,6 +244,7 @@ The icon in the status bar and the notification in the lockscreen are shown The icon in the status bar and the notification in the lockscreen are hidden Notifications + User interface Repetitions Phone Calls Call notification delay diff --git a/app/src/main/res/xml/charts_preferences.xml b/app/src/main/res/xml/charts_preferences.xml index 786b2cafe..d5edce769 100644 --- a/app/src/main/res/xml/charts_preferences.xml +++ b/app/src/main/res/xml/charts_preferences.xml @@ -1,6 +1,19 @@ + + + - + + + + + + + - - - - - - - - - - - - - @@ -125,90 +86,199 @@ android:title="@string/pref_rtl_max_line_length" app:iconSpaceReserved="false" /> - + - + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - + android:icon="@drawable/ic_navigation" + android:key="pref_key_opentracks_packagename" + android:summary="@string/pref_summary_opentracks_packagename" + android:title="@string/pref_title_opentracks_packagename" /> - - - - + - + + + + + + + + + android:summary="@string/pref_description_developer_options" + android:title="@string/pref_header_development"> + - - - - - @@ -388,9 +428,10 @@ -