2024-01-10 18:54:00 +01:00
|
|
|
/* Copyright (C) 2015-2024 0nse, Andreas Shimokawa, Anemograph, Arjan
|
|
|
|
Schrijver, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Felix Konstantin
|
|
|
|
Maurer, José Rebelo, Martin, Normano64, Pavel Elagin, Petr Vaněk, Sebastian
|
|
|
|
Kranz, Taavi Eomäe
|
2017-03-10 14:53:19 +01:00
|
|
|
|
|
|
|
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
|
2024-01-10 18:54:00 +01:00
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
2015-08-03 23:09:49 +02:00
|
|
|
package nodomain.freeyourgadget.gadgetbridge.activities;
|
2015-01-07 14:00:18 +01:00
|
|
|
|
2016-05-26 14:39:54 +02:00
|
|
|
import android.Manifest;
|
|
|
|
import android.content.Context;
|
2015-03-15 21:36:39 +01:00
|
|
|
import android.content.Intent;
|
2022-02-25 07:27:08 +01:00
|
|
|
import android.content.SharedPreferences;
|
2015-09-16 00:53:54 +02:00
|
|
|
import android.content.pm.PackageManager;
|
|
|
|
import android.content.pm.ResolveInfo;
|
2018-01-04 15:13:06 +01:00
|
|
|
import android.database.Cursor;
|
2016-05-26 14:39:54 +02:00
|
|
|
import android.location.Criteria;
|
|
|
|
import android.location.Location;
|
2016-07-05 23:52:48 +02:00
|
|
|
import android.location.LocationListener;
|
2016-05-26 14:39:54 +02:00
|
|
|
import android.location.LocationManager;
|
2018-01-04 15:13:06 +01:00
|
|
|
import android.net.Uri;
|
2015-01-07 14:00:18 +01:00
|
|
|
import android.os.Bundle;
|
2018-01-04 15:13:06 +01:00
|
|
|
import android.provider.DocumentsContract;
|
2023-07-27 00:17:20 +02:00
|
|
|
import android.text.InputType;
|
2022-02-25 07:27:08 +01:00
|
|
|
import android.view.View;
|
|
|
|
import android.widget.AdapterView;
|
|
|
|
import android.widget.ArrayAdapter;
|
|
|
|
import android.widget.EditText;
|
|
|
|
import android.widget.LinearLayout;
|
|
|
|
import android.widget.Spinner;
|
2016-03-22 23:01:41 +01:00
|
|
|
import android.widget.Toast;
|
2015-01-07 14:00:18 +01:00
|
|
|
|
2023-07-27 23:42:00 +02:00
|
|
|
import androidx.core.app.ActivityCompat;
|
2023-07-22 21:23:27 +02:00
|
|
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
2023-07-27 00:17:20 +02:00
|
|
|
import androidx.preference.ListPreference;
|
2024-04-04 21:28:04 +02:00
|
|
|
import androidx.preference.MultiSelectListPreference;
|
2023-07-27 00:17:20 +02:00
|
|
|
import androidx.preference.Preference;
|
|
|
|
import androidx.preference.PreferenceFragmentCompat;
|
2019-05-20 16:36:06 +02:00
|
|
|
|
2023-08-12 10:51:56 +02:00
|
|
|
import com.google.android.material.color.DynamicColors;
|
2023-07-22 21:23:27 +02:00
|
|
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
|
|
|
2016-05-26 14:39:54 +02:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
2016-03-22 23:01:41 +01:00
|
|
|
import java.io.IOException;
|
2024-04-04 21:28:04 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
2020-07-28 15:42:44 +02:00
|
|
|
import java.util.HashSet;
|
2015-09-16 00:53:54 +02:00
|
|
|
import java.util.List;
|
2016-05-26 14:39:54 +02:00
|
|
|
import java.util.Locale;
|
2020-07-28 15:42:44 +02:00
|
|
|
import java.util.Set;
|
2015-09-16 00:53:54 +02:00
|
|
|
|
2017-12-12 22:36:15 +01:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
|
2016-04-18 00:20:40 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
2015-08-03 23:09:49 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
2020-07-28 15:42:44 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsPreferencesActivity;
|
2023-08-30 16:28:43 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.activities.discovery.DiscoveryPairingPreferenceActivity;
|
2018-01-04 15:13:06 +01:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.database.PeriodicExporter;
|
2023-07-27 23:42:00 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusSettingsActivity;
|
2015-08-03 23:09:49 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity;
|
2023-07-27 23:42:00 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleSettingsActivity;
|
2019-07-14 19:45:40 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.ConfigActivity;
|
2018-09-13 14:55:38 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.devices.zetime.ZeTimePreferenceActivity;
|
2024-02-15 21:32:44 +01:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.externalevents.TimeChangeReceiver;
|
2024-04-04 21:28:04 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
2022-08-18 23:03:28 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.model.Weather;
|
2018-01-09 08:54:18 +01:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
|
2016-03-22 23:01:41 +01:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
|
|
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
2018-01-07 12:50:59 +01:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
2016-06-24 10:25:08 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
2015-05-07 01:30:40 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
public class SettingsActivity extends AbstractSettingsActivityV2 {
|
2017-09-30 22:45:45 +02:00
|
|
|
public static final String PREF_MEASUREMENT_SYSTEM = "measurement_system";
|
|
|
|
|
2015-05-07 01:30:40 +02:00
|
|
|
@Override
|
2023-07-27 00:17:20 +02:00
|
|
|
protected String fragmentTag() {
|
|
|
|
return SettingsFragment.FRAGMENT_TAG;
|
2015-05-07 01:30:40 +02:00
|
|
|
}
|
|
|
|
|
2015-01-07 14:00:18 +01:00
|
|
|
@Override
|
2023-07-27 00:17:20 +02:00
|
|
|
protected PreferenceFragmentCompat newFragment() {
|
|
|
|
return new SettingsFragment();
|
|
|
|
}
|
2020-11-14 10:06:55 +01:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
public static class SettingsFragment extends AbstractPreferenceFragment {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(SettingsActivity.class);
|
2020-11-14 10:06:55 +01:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
static final String FRAGMENT_TAG = "SETTINGS_FRAGMENT";
|
|
|
|
|
2023-07-27 23:54:24 +02:00
|
|
|
private static final int EXPORT_LOCATION_FILE_REQUEST_CODE = 4711;
|
2023-07-27 00:17:20 +02:00
|
|
|
private EditText fitnessAppEditText = null;
|
|
|
|
private int fitnessAppSelectionListSpinnerFirstRun = 0;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
|
|
|
|
setPreferencesFromResource(R.xml.preferences, rootKey);
|
|
|
|
|
|
|
|
setInputTypeFor("rtl_max_line_length", InputType.TYPE_CLASS_NUMBER);
|
|
|
|
setInputTypeFor("location_latitude", InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
|
|
|
|
setInputTypeFor("location_longitude", InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
|
|
|
|
setInputTypeFor("auto_export_interval", InputType.TYPE_CLASS_NUMBER);
|
|
|
|
setInputTypeFor("auto_fetch_interval_limit", InputType.TYPE_CLASS_NUMBER);
|
|
|
|
|
|
|
|
Prefs prefs = GBApplication.getPrefs();
|
|
|
|
Preference pref = findPreference("pref_category_activity_personal");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
Intent enableIntent = new Intent(requireContext(), AboutUserPreferencesActivity.class);
|
|
|
|
startActivity(enableIntent);
|
|
|
|
return true;
|
|
|
|
});
|
2015-05-07 01:30:40 +02:00
|
|
|
}
|
2015-04-19 12:35:23 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
pref = findPreference("pref_charts");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
Intent enableIntent = new Intent(requireContext(), ChartsPreferencesActivity.class);
|
|
|
|
startActivity(enableIntent);
|
|
|
|
return true;
|
|
|
|
});
|
2019-07-14 19:45:40 +02:00
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
|
|
|
|
pref = findPreference("pref_key_miband");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
Intent enableIntent = new Intent(requireContext(), MiBandPreferencesActivity.class);
|
|
|
|
startActivity(enableIntent);
|
|
|
|
return true;
|
|
|
|
});
|
2018-09-13 14:55:38 +02:00
|
|
|
}
|
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
pref = findPreference("pref_key_qhybrid");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
startActivity(new Intent(requireContext(), ConfigActivity.class));
|
|
|
|
return true;
|
|
|
|
});
|
2015-08-19 00:03:52 +02:00
|
|
|
}
|
|
|
|
|
2023-07-27 23:42:00 +02:00
|
|
|
pref = findPreference("pref_key_pebble");
|
2023-07-27 00:17:20 +02:00
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
2023-07-27 23:42:00 +02:00
|
|
|
Intent enableIntent = new Intent(requireContext(), PebbleSettingsActivity.class);
|
2023-07-27 00:17:20 +02:00
|
|
|
startActivity(enableIntent);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
}
|
2015-08-19 00:03:52 +02:00
|
|
|
|
2023-07-27 23:42:00 +02:00
|
|
|
pref = findPreference("pref_key_hplus");
|
2023-07-27 00:17:20 +02:00
|
|
|
if (pref != null) {
|
2023-07-27 23:42:00 +02:00
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
Intent enableIntent = new Intent(requireContext(), HPlusSettingsActivity.class);
|
|
|
|
startActivity(enableIntent);
|
2023-07-27 00:17:20 +02:00
|
|
|
return true;
|
|
|
|
});
|
2015-08-19 00:03:52 +02:00
|
|
|
}
|
|
|
|
|
2023-07-27 23:42:00 +02:00
|
|
|
pref = findPreference("pref_key_zetime");
|
2023-07-27 00:17:20 +02:00
|
|
|
if (pref != null) {
|
2023-07-27 23:42:00 +02:00
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
Intent enableIntent = new Intent(requireContext(), ZeTimePreferenceActivity.class);
|
|
|
|
startActivity(enableIntent);
|
2023-07-27 00:17:20 +02:00
|
|
|
return true;
|
2024-02-15 21:32:44 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
pref = findPreference("datetime_synconconnect");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceChangeListener((preference, newVal) -> {
|
|
|
|
if (Boolean.TRUE.equals(newVal)) {
|
|
|
|
TimeChangeReceiver.scheduleNextDstChangeOrPeriodicSync(requireContext());
|
|
|
|
GBApplication.deviceService().onSetTime();
|
|
|
|
}
|
|
|
|
return true;
|
2023-07-27 00:17:20 +02:00
|
|
|
});
|
|
|
|
}
|
2015-09-16 00:53:54 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
pref = findPreference("log_to_file");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceChangeListener((preference, newVal) -> {
|
|
|
|
boolean doEnable = Boolean.TRUE.equals(newVal);
|
|
|
|
try {
|
|
|
|
if (doEnable) {
|
|
|
|
FileUtils.getExternalFilesDir(); // ensures that it is created
|
|
|
|
}
|
|
|
|
GBApplication.setupLogging(doEnable);
|
|
|
|
} catch (IOException ex) {
|
|
|
|
GB.toast(requireContext().getApplicationContext(),
|
|
|
|
getString(R.string.error_creating_directory_for_logfiles, ex.getLocalizedMessage()),
|
|
|
|
Toast.LENGTH_LONG,
|
|
|
|
GB.ERROR,
|
|
|
|
ex);
|
2016-03-22 23:01:41 +01:00
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
return true;
|
|
|
|
});
|
2023-07-28 22:31:48 +02:00
|
|
|
|
|
|
|
// If we didn't manage to initialize file logging, disable the preference
|
|
|
|
if (!GBApplication.getLogging().isFileLoggerInitialized()) {
|
|
|
|
pref.setEnabled(false);
|
|
|
|
pref.setSummary(R.string.pref_write_logfiles_not_available);
|
|
|
|
}
|
2016-03-22 23:01:41 +01:00
|
|
|
}
|
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
pref = findPreference("cache_weather");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceChangeListener((preference, newVal) -> {
|
|
|
|
boolean doEnable = Boolean.TRUE.equals(newVal);
|
2016-03-22 23:01:41 +01:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
Weather.getInstance().setCacheFile(requireContext().getCacheDir(), doEnable);
|
2022-08-18 23:03:28 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
return true;
|
|
|
|
});
|
2017-07-31 22:49:05 +02:00
|
|
|
}
|
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
pref = findPreference("language");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceChangeListener((preference, newVal) -> {
|
|
|
|
String newLang = newVal.toString();
|
|
|
|
try {
|
|
|
|
GBApplication.setLanguage(newLang);
|
|
|
|
requireActivity().recreate();
|
|
|
|
} catch (Exception ex) {
|
|
|
|
GB.toast(requireContext().getApplicationContext(),
|
|
|
|
"Error setting language: " + ex.getLocalizedMessage(),
|
|
|
|
Toast.LENGTH_LONG,
|
|
|
|
GB.ERROR,
|
|
|
|
ex);
|
2017-09-30 22:45:45 +02:00
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
return true;
|
2017-09-30 22:45:45 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
final Preference unit = findPreference(PREF_MEASUREMENT_SYSTEM);
|
|
|
|
if (unit != null) {
|
|
|
|
unit.setOnPreferenceChangeListener((preference, newVal) -> {
|
|
|
|
invokeLater(() -> GBApplication.deviceService().onSendConfiguration(PREF_MEASUREMENT_SYSTEM));
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
pref = findPreference("location_aquire");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
if (ActivityCompat.checkSelfPermission(requireContext().getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
|
|
|
ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 0);
|
|
|
|
}
|
2016-05-26 14:58:36 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
LocationManager locationManager = (LocationManager) requireContext().getSystemService(Context.LOCATION_SERVICE);
|
|
|
|
Criteria criteria = new Criteria();
|
|
|
|
String provider = locationManager.getBestProvider(criteria, false);
|
|
|
|
if (provider != null) {
|
|
|
|
Location location = locationManager.getLastKnownLocation(provider);
|
|
|
|
if (location != null) {
|
|
|
|
setLocationPreferences(location);
|
|
|
|
} else {
|
|
|
|
locationManager.requestSingleUpdate(provider, new LocationListener() {
|
|
|
|
@Override
|
|
|
|
public void onLocationChanged(Location location) {
|
|
|
|
setLocationPreferences(location);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onStatusChanged(String provider, int status, Bundle extras) {
|
|
|
|
LOG.info("provider status changed to " + status + " (" + provider + ")");
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onProviderEnabled(String provider) {
|
|
|
|
LOG.info("provider enabled (" + provider + ")");
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onProviderDisabled(String provider) {
|
|
|
|
LOG.info("provider disabled (" + provider + ")");
|
|
|
|
GB.toast(requireContext(), getString(R.string.toast_enable_networklocationprovider), 3000, 0);
|
|
|
|
}
|
|
|
|
}, null);
|
|
|
|
}
|
2016-07-03 21:29:02 +02:00
|
|
|
} else {
|
2023-07-27 00:17:20 +02:00
|
|
|
LOG.warn("No location provider found, did you deny location permission?");
|
2016-07-03 21:29:02 +02:00
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
return true;
|
|
|
|
});
|
2016-05-26 14:39:54 +02:00
|
|
|
}
|
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
pref = findPreference("weather_city");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceChangeListener((preference, newVal) -> {
|
|
|
|
// reset city id and force a new lookup
|
|
|
|
GBApplication.getPrefs().getPreferences().edit().putString("weather_cityid", null).apply();
|
|
|
|
Intent intent = new Intent("GB_UPDATE_WEATHER");
|
|
|
|
intent.setPackage(BuildConfig.APPLICATION_ID);
|
|
|
|
requireContext().sendBroadcast(intent);
|
|
|
|
return true;
|
|
|
|
});
|
2019-07-14 19:45:40 +02:00
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
|
|
|
|
|
|
|
|
pref = findPreference(GBPrefs.AUTO_EXPORT_LOCATION);
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
Intent i = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
|
|
|
i.setType("application/x-sqlite3");
|
|
|
|
i.addCategory(Intent.CATEGORY_OPENABLE);
|
2023-07-27 23:54:24 +02:00
|
|
|
i.putExtra(Intent.EXTRA_TITLE, "Gadgetbridge.db");
|
2023-07-27 00:17:20 +02:00
|
|
|
i.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
|
|
|
String title = requireContext().getApplicationContext().getString(R.string.choose_auto_export_location);
|
2023-07-27 23:54:24 +02:00
|
|
|
startActivityForResult(Intent.createChooser(i, title), EXPORT_LOCATION_FILE_REQUEST_CODE);
|
2023-07-27 00:17:20 +02:00
|
|
|
return true;
|
|
|
|
});
|
|
|
|
pref.setSummary(getAutoExportLocationSummary());
|
2018-01-04 15:13:06 +01:00
|
|
|
}
|
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
pref = findPreference(GBPrefs.AUTO_EXPORT_INTERVAL);
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceChangeListener((preference, autoExportInterval) -> {
|
|
|
|
String summary = String.format(
|
|
|
|
requireContext().getApplicationContext().getString(R.string.pref_summary_auto_export_interval),
|
|
|
|
Integer.valueOf((String) autoExportInterval));
|
|
|
|
preference.setSummary(summary);
|
|
|
|
boolean auto_export_enabled = GBApplication.getPrefs().getBoolean(GBPrefs.AUTO_EXPORT_ENABLED, false);
|
|
|
|
PeriodicExporter.scheduleAlarm(requireContext().getApplicationContext(), Integer.valueOf((String) autoExportInterval), auto_export_enabled);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
int autoExportInterval = GBApplication.getPrefs().getInt(GBPrefs.AUTO_EXPORT_INTERVAL, 0);
|
2018-01-08 11:27:28 +01:00
|
|
|
String summary = String.format(
|
2023-07-27 00:17:20 +02:00
|
|
|
requireContext().getApplicationContext().getString(R.string.pref_summary_auto_export_interval),
|
|
|
|
autoExportInterval);
|
|
|
|
pref.setSummary(summary);
|
2017-12-11 19:09:37 +01:00
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
|
|
|
|
pref = findPreference(GBPrefs.AUTO_EXPORT_ENABLED);
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceChangeListener((preference, autoExportEnabled) -> {
|
|
|
|
int autoExportInterval = GBApplication.getPrefs().getInt(GBPrefs.AUTO_EXPORT_INTERVAL, 0);
|
|
|
|
PeriodicExporter.scheduleAlarm(requireContext().getApplicationContext(), autoExportInterval, (boolean) autoExportEnabled);
|
|
|
|
return true;
|
|
|
|
});
|
2018-01-04 15:13:06 +01:00
|
|
|
}
|
2017-12-11 19:09:37 +01:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
pref = findPreference("auto_fetch_interval_limit");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceChangeListener((preference, autoFetchInterval) -> {
|
|
|
|
String summary = String.format(
|
|
|
|
requireContext().getApplicationContext().getString(R.string.pref_auto_fetch_limit_fetches_summary),
|
|
|
|
Integer.valueOf((String) autoFetchInterval));
|
|
|
|
preference.setSummary(summary);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
int autoFetchInterval = GBApplication.getPrefs().getInt("auto_fetch_interval_limit", 0);
|
2018-06-30 17:32:12 +02:00
|
|
|
String summary = String.format(
|
2023-07-27 00:17:20 +02:00
|
|
|
requireContext().getApplicationContext().getString(R.string.pref_auto_fetch_limit_fetches_summary),
|
|
|
|
autoFetchInterval);
|
|
|
|
pref.setSummary(summary);
|
2020-07-28 15:42:44 +02:00
|
|
|
}
|
2015-09-16 00:53:54 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
final ListPreference audioPlayer = findPreference("audio_player");
|
|
|
|
if (audioPlayer != null) {
|
|
|
|
// Get all receivers of Media Buttons
|
|
|
|
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
|
|
|
|
|
|
|
|
PackageManager pm = requireContext().getPackageManager();
|
|
|
|
List<ResolveInfo> mediaReceivers = pm.queryBroadcastReceivers(mediaButtonIntent,
|
|
|
|
PackageManager.GET_INTENT_FILTERS | PackageManager.GET_RESOLVED_FILTER);
|
|
|
|
|
|
|
|
CharSequence[] newEntries = new CharSequence[mediaReceivers.size() + 1];
|
|
|
|
CharSequence[] newValues = new CharSequence[mediaReceivers.size() + 1];
|
|
|
|
newEntries[0] = getString(R.string.pref_default);
|
|
|
|
newValues[0] = "default";
|
|
|
|
|
|
|
|
int i = 1;
|
|
|
|
Set<String> existingNames = new HashSet<>();
|
|
|
|
for (ResolveInfo resolveInfo : mediaReceivers) {
|
|
|
|
newEntries[i] = resolveInfo.activityInfo.loadLabel(pm) + " (" + resolveInfo.activityInfo.packageName + ")";
|
|
|
|
if (existingNames.contains(newEntries[i].toString().trim())) {
|
|
|
|
newEntries[i] = resolveInfo.activityInfo.loadLabel(pm) + " (" + resolveInfo.activityInfo.name + ")";
|
|
|
|
} else {
|
|
|
|
existingNames.add(newEntries[i].toString().trim());
|
|
|
|
}
|
|
|
|
newValues[i] = resolveInfo.activityInfo.packageName;
|
|
|
|
i++;
|
|
|
|
}
|
2021-07-06 08:31:22 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
audioPlayer.setEntries(newEntries);
|
|
|
|
audioPlayer.setEntryValues(newValues);
|
|
|
|
audioPlayer.setDefaultValue(newValues[0]);
|
|
|
|
}
|
2024-04-04 21:28:04 +02:00
|
|
|
|
|
|
|
pref = findPreference("pref_category_dashboard");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
Intent enableIntent = new Intent(requireContext(), DashboardPreferencesActivity.class);
|
|
|
|
startActivity(enableIntent);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
}
|
2021-07-06 08:31:22 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
final Preference theme = findPreference("pref_key_theme");
|
|
|
|
final Preference amoled_black = findPreference("pref_key_theme_amoled_black");
|
2021-07-06 08:31:22 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
if (amoled_black != null) {
|
|
|
|
String selectedTheme = prefs.getString("pref_key_theme", requireContext().getString(R.string.pref_theme_value_system));
|
|
|
|
if (selectedTheme.equals("light"))
|
2021-07-06 08:31:22 +02:00
|
|
|
amoled_black.setEnabled(false);
|
|
|
|
else
|
|
|
|
amoled_black.setEnabled(true);
|
2023-07-22 21:23:27 +02:00
|
|
|
amoled_black.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
2023-08-12 10:51:56 +02:00
|
|
|
sendThemeChangeIntent();
|
2023-07-22 21:23:27 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
2021-12-23 18:56:36 +01:00
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
|
|
|
|
if (theme != null) {
|
|
|
|
theme.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
|
|
|
final String val = newVal.toString();
|
|
|
|
if (amoled_black != null) {
|
|
|
|
if (val.equals("light"))
|
|
|
|
amoled_black.setEnabled(false);
|
|
|
|
else
|
|
|
|
amoled_black.setEnabled(true);
|
|
|
|
}
|
2023-08-12 10:51:56 +02:00
|
|
|
// Warn user if dynamic colors are not available
|
|
|
|
if (val.equals(requireContext().getString(R.string.pref_theme_value_dynamic)) && !DynamicColors.isDynamicColorAvailable()) {
|
|
|
|
new MaterialAlertDialogBuilder(requireContext())
|
|
|
|
.setTitle(R.string.warning)
|
|
|
|
.setMessage(R.string.pref_theme_dynamic_colors_not_available_warning)
|
|
|
|
.setIcon(R.drawable.ic_warning)
|
|
|
|
.setPositiveButton(R.string.ok, (dialog, whichButton) -> {
|
|
|
|
sendThemeChangeIntent();
|
|
|
|
})
|
|
|
|
.show();
|
|
|
|
} else {
|
|
|
|
sendThemeChangeIntent();
|
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
2022-02-25 07:27:08 +01:00
|
|
|
}
|
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
pref = findPreference("pref_discovery_pairing");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
Intent enableIntent = new Intent(requireContext(), DiscoveryPairingPreferenceActivity.class);
|
|
|
|
startActivity(enableIntent);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
}
|
2022-02-25 07:27:08 +01:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
//fitness app (OpenTracks) package name selection for OpenTracks observer
|
|
|
|
pref = findPreference("pref_key_opentracks_packagename");
|
|
|
|
if (pref != null) {
|
|
|
|
pref.setOnPreferenceClickListener(preference -> {
|
|
|
|
final LinearLayout outerLayout = new LinearLayout(requireContext());
|
|
|
|
outerLayout.setOrientation(LinearLayout.VERTICAL);
|
|
|
|
final LinearLayout innerLayout = new LinearLayout(requireContext());
|
|
|
|
innerLayout.setOrientation(LinearLayout.HORIZONTAL);
|
|
|
|
innerLayout.setPadding(20, 0, 20, 0);
|
|
|
|
final Spinner selectionListSpinner = new Spinner(requireContext());
|
|
|
|
String[] appListArray = getResources().getStringArray(R.array.fitness_tracking_apps_package_names);
|
|
|
|
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(requireContext(),
|
|
|
|
android.R.layout.simple_spinner_dropdown_item, appListArray);
|
|
|
|
selectionListSpinner.setAdapter(spinnerArrayAdapter);
|
|
|
|
fitnessAppSelectionListSpinnerFirstRun = 0;
|
|
|
|
addListenerOnSpinnerDeviceSelection(selectionListSpinner);
|
|
|
|
Prefs prefs1 = GBApplication.getPrefs();
|
|
|
|
String packageName = prefs1.getString("opentracks_packagename", "de.dennisguse.opentracks");
|
2023-07-28 00:01:54 +02:00
|
|
|
// Set the spinner to the selected package name by default
|
|
|
|
for (int i = 0; i < appListArray.length; i++) {
|
|
|
|
if (appListArray[i].equals(packageName)) {
|
|
|
|
selectionListSpinner.setSelection(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
fitnessAppEditText = new EditText(requireContext());
|
|
|
|
fitnessAppEditText.setText(packageName);
|
|
|
|
innerLayout.addView(fitnessAppEditText);
|
|
|
|
outerLayout.addView(selectionListSpinner);
|
|
|
|
outerLayout.addView(innerLayout);
|
|
|
|
|
2023-07-22 21:23:27 +02:00
|
|
|
new MaterialAlertDialogBuilder(requireContext())
|
2023-07-27 00:17:20 +02:00
|
|
|
.setCancelable(true)
|
|
|
|
.setTitle(R.string.pref_title_opentracks_packagename)
|
|
|
|
.setView(outerLayout)
|
2023-07-28 00:01:54 +02:00
|
|
|
.setPositiveButton(R.string.ok, (dialog, which) -> {
|
|
|
|
SharedPreferences.Editor editor = GBApplication.getPrefs().getPreferences().edit();
|
|
|
|
editor.putString("opentracks_packagename", fitnessAppEditText.getText().toString());
|
|
|
|
editor.apply();
|
2023-07-27 00:17:20 +02:00
|
|
|
})
|
2023-07-28 00:01:54 +02:00
|
|
|
.setNegativeButton(R.string.Cancel, (dialog, which) -> {})
|
2023-07-27 00:17:20 +02:00
|
|
|
.show();
|
|
|
|
return false;
|
|
|
|
});
|
2022-02-25 07:27:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
private void addListenerOnSpinnerDeviceSelection(Spinner spinner) {
|
|
|
|
spinner.setOnItemSelectedListener(new CustomOnDeviceSelectedListener());
|
2022-02-25 07:27:08 +01:00
|
|
|
}
|
2015-08-19 00:03:52 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
public class CustomOnDeviceSelectedListener implements AdapterView.OnItemSelectedListener {
|
|
|
|
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
|
|
|
if (++fitnessAppSelectionListSpinnerFirstRun > 1) { //this prevents the setText to be set when spinner just is being initialized
|
|
|
|
fitnessAppEditText.setText(parent.getItemAtPosition(pos).toString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onNothingSelected(AdapterView<?> arg0) {
|
|
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
2018-01-04 15:13:06 +01:00
|
|
|
}
|
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
@Override
|
|
|
|
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
2023-07-27 23:54:24 +02:00
|
|
|
if (requestCode == EXPORT_LOCATION_FILE_REQUEST_CODE && intent != null) {
|
2023-07-27 00:17:20 +02:00
|
|
|
Uri uri = intent.getData();
|
|
|
|
requireContext().getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
|
|
|
GBApplication.getPrefs().getPreferences()
|
|
|
|
.edit()
|
|
|
|
.putString(GBPrefs.AUTO_EXPORT_LOCATION, uri.toString())
|
|
|
|
.apply();
|
|
|
|
String summary = getAutoExportLocationSummary();
|
|
|
|
findPreference(GBPrefs.AUTO_EXPORT_LOCATION).setSummary(summary);
|
|
|
|
boolean autoExportEnabled = GBApplication
|
|
|
|
.getPrefs().getBoolean(GBPrefs.AUTO_EXPORT_ENABLED, false);
|
|
|
|
int autoExportPeriod = GBApplication
|
|
|
|
.getPrefs().getInt(GBPrefs.AUTO_EXPORT_INTERVAL, 0);
|
|
|
|
PeriodicExporter.scheduleAlarm(requireContext().getApplicationContext(), autoExportPeriod, autoExportEnabled);
|
|
|
|
}
|
2018-01-08 11:27:28 +01:00
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
Either returns the file path of the selected document, or the display name, or an empty string
|
|
|
|
*/
|
|
|
|
public String getAutoExportLocationSummary() {
|
|
|
|
String autoExportLocation = GBApplication.getPrefs().getString(GBPrefs.AUTO_EXPORT_LOCATION, null);
|
|
|
|
if (autoExportLocation == null) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
Uri uri = Uri.parse(autoExportLocation);
|
2018-05-15 23:12:18 +02:00
|
|
|
try {
|
2023-07-27 00:17:20 +02:00
|
|
|
return AndroidUtils.getFilePath(requireContext().getApplicationContext(), uri);
|
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
|
try {
|
|
|
|
Cursor cursor = requireContext().getContentResolver().query(
|
|
|
|
uri,
|
|
|
|
new String[]{DocumentsContract.Document.COLUMN_DISPLAY_NAME},
|
|
|
|
null, null, null, null
|
|
|
|
);
|
|
|
|
if (cursor != null && cursor.moveToFirst()) {
|
|
|
|
return cursor.getString(cursor.getColumnIndex(DocumentsContract.Document.COLUMN_DISPLAY_NAME));
|
|
|
|
}
|
|
|
|
} catch (Exception fdfsdfds) {
|
|
|
|
LOG.warn("fuck");
|
2018-05-15 23:12:18 +02:00
|
|
|
}
|
2018-01-08 11:27:28 +01:00
|
|
|
}
|
2023-07-27 00:17:20 +02:00
|
|
|
return "";
|
2018-01-08 11:27:28 +01:00
|
|
|
}
|
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
/*
|
|
|
|
* delayed execution so that the preferences are applied first
|
|
|
|
*/
|
|
|
|
private void invokeLater(Runnable runnable) {
|
|
|
|
getListView().post(runnable);
|
|
|
|
}
|
2015-08-19 00:03:52 +02:00
|
|
|
|
2023-07-27 00:17:20 +02:00
|
|
|
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);
|
|
|
|
GB.toast(requireContext(), getString(R.string.toast_aqurired_networklocation), 2000, 0);
|
2023-07-27 00:38:55 +02:00
|
|
|
GBApplication.getPrefs().getPreferences()
|
|
|
|
.edit()
|
|
|
|
.putString("location_latitude", latitude)
|
|
|
|
.putString("location_longitude", longitude)
|
|
|
|
.apply();
|
2023-07-27 00:17:20 +02:00
|
|
|
}
|
2023-08-12 10:51:56 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Signal running activities that the theme has changed
|
|
|
|
*/
|
|
|
|
private void sendThemeChangeIntent() {
|
|
|
|
Intent intent = new Intent();
|
|
|
|
intent.setAction(GBApplication.ACTION_THEME_CHANGE);
|
|
|
|
LocalBroadcastManager.getInstance(requireContext()).sendBroadcast(intent);
|
|
|
|
}
|
2016-07-05 23:52:48 +02:00
|
|
|
}
|
2015-01-07 14:00:18 +01:00
|
|
|
}
|