can anyone tell me how can I start/stop a location service (or any other service) when a SwitchPreference in a PreferenceScreen is toggled on/of?
I'm using a settingsFragemnt (extending PreferenceFragemntCompat), which is hosted in my settings activity.
You should add OnPreferenceChangeListener which will allow you to listen switch changes:
final SwitchPreference onOffRandomColor = (SwitchPreference) findPreference(this.getResources()
.getString(R.string.sp_key_on_off_random_color));
onOffRandomColor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object o) {
if(onOffRandomColor.isChecked()){
}else {
}
return false;
}
});
Next step is to run service:
startService(new Intent(this, LocationService.class));
my fragment looks like this:
public class SettingsFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(#Nullable Bundle savedInstanceState, String rootKey){
setPreferencesFromResource(R.xml.prefs, rootKey);
// setting summaries for both list preferences ---------------------------------------------
ListPreference photo_quality = findPreference("photo_quality");
if (photo_quality != null){
photo_quality.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
}
ListPreference uploads = findPreference("upload_options");
if (uploads != null) {
uploads.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
}
// setting the visibility for location service ---------------------------------------------
if (!Auth.getCanDeactiveGps()){
Objects.requireNonNull(getPreferenceScreen()
.findPreference("location_category")).setVisible(false);
}
// handling locationSwitchPreference change ------------------------------------------------
SwitchPreference locationSwitch = findPreference("location");
if (locationSwitch != null){
locationSwitch.setChecked(Settings.getBoolean(Settings.DO_NOT_LOCATE,
false));
locationSwitch.setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Settings.setBoolean(Settings.DO_NOT_LOCATE, true);
return false;
}
});
}
}
Related
I am using Switch Preference in my preference activity to change app theme but it is not working properly . I can't figure out what am i doing wrong here is my code
Here is my prefs.xml
<SwitchPreference
android:defaultValue="false"
android:key="#string/pref_key_dark_mode"
android:title="#string/pref_title_dark_mode"
android:summary="#string/pref_summary_dark_mode"/>
</PreferenceCategory>
and here is my Settings activity
public class SettingsActivity extends AppCompatPreferenceActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// load settings fragment
getFragmentManager().beginTransaction().replace(android.R.id.content, new MainSettingsFragment()).commit();
}
public static class MainSettingsFragment extends PreferenceFragment {
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs_main);
// Stuff to do with night mode switch
final SwitchPreference nightMode = (SwitchPreference) findPreference(getString(R.string.pref_key_dark_mode));
nightMode.setDefaultValue(false);
nightMode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (nightMode.isChecked()){
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
getActivity().recreate();
nightMode.setChecked(false);
}else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
getActivity().recreate();
nightMode.setChecked(true);
}
return false;
}
});
}
}
}
And here is what am i doing in my MainActivity.java
private void setNightMode() {
preferences = getPreferences(MODE_PRIVATE);
if (preferences.getBoolean(getString(R.string.pref_key_dark_mode), true))
{
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
}
I am calling setNightMode(); before on create and onResume
Try This it should help
final SwitchPreference nightMode = (SwitchPreference) findPreference(getString(R.string.pref_key_dark_mode));
nightMode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if ((Boolean)newValue){
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
}else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
getActivity().recreate();
}
});
I want to evaluate checkboxpreference, tried some method from here but non of it worked. I need to get the value in the OnSharedPreferenceChangeListener, but not in PreferenceActivity. It gives an error like:
ava.lang.ClassCastException: android.app.SharedPreferencesImpl cannot be cast to android.support.v7.preference.CheckBoxPreference
Could somebody explain the problem?
sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.d(MainActivity.this.getClass().getSimpleName(), "Einstellungen wurde geƤndert.");
prefsChanged = true;
if(key.equals("use_gps")) {
//TODO: CheckBox evaluate and LocationUpdate start or remove if it's not checked
CheckBoxPreference preference = (CheckBoxPreference) getSharedPreferences("use_gps", MODE_PRIVATE);
if(preference.isChecked()) {
requestLocationUpdates();
Log.d(getClass().getSimpleName(), "preference ischecked");
} else {
removeLocationUpdates();
Log.d(getClass().getSimpleName(), " preference isnotchecked");
}
}
}
};
Thanks for all the help, solution was in MAinActivity onCreate():
if(key.equals("use_gps")) {
//TODO: CheckBox auswerten udn ggfs. Standortbestimmung starten oder stoppen
boolean checkbox = sharedPreferences.getBoolean("use_gps", true);
if (checkbox == true){
Toast.makeText(MainActivity.this, "true", Toast.LENGTH_LONG).show();
requestLocationUpdates();
} else {
Toast.makeText(MainActivity.this, "false", Toast.LENGTH_LONG).show();
removeLocationUpdates();
}
}
}
This should help, instead of using OnSharedPreferenceChangeListener(), use registerOnSharedPreferenceChangeListener() to link listener to the any of your preference outside of the Preference an
Code snippet for the non-preference Activity where you want to attach the listener for a preference:
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener()
{
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
Log.v("CHANGE ", "YES");
boolean use_gps_stat = sharedPreferences.getBoolean("use_gps", true);
if(key == "use_gps")
{
Toast.makeText(getApplicationContext(), "Changed", Toast.LENGTH_LONG).show();
if(use_gps_stat)
{
Toast.makeText(getApplicationContext(), "Checked", Toast.LENGTH_LONG).show();
requestLocationUpdates();
Log.d(getClass().getSimpleName(), "preference ischecked");
}
else
{
Toast.makeText(getApplicationContext(), "Unchecked", Toast.LENGTH_LONG).show();
removeLocationUpdates();
Log.d(getClass().getSimpleName(), " preference isnotchecked");
}
}
}
});
In your preference activity add this to overriden onCreate:
bindPreferenceSummaryToValue_CheckBox(findPreference("use_gps"));
So it should look like this:
public static class MainPreferenceFragment extends PreferenceFragment
{
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preference);
bindPreferenceSummaryToValue_CheckBox(
findPreference("use_gps"));
.
.
.
And add bindPreferenceSummaryToValue_CheckBox outside onCreate:
private static void bindPreferenceSummaryToValue_CheckBox(Preference preference)
{
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.getContext())
.getBoolean(preference.getKey(), true));
}
For sBindPreferenceSummaryToValueListener simply add to the class extending to AppCompatPreferenceActivity:
private static Preference.OnPreferenceChangeListener
sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener()
{
#Override
public boolean onPreferenceChange(Preference preference, Object newValue)
{
//Do something on prefernce change.
return true;
}
};
I recently tried this code structure and worked, if there are any queries let me know down in the comments.
I have a Floating Action Button in my layout. Users can choose the position of this button, left or right. This can be selected in the preferences.
The code to do this works OK, but a change in the preference is not detected by the listener.
If the app is restarted, the Floating Action Button is displayed according to the new preference, so I know the process with this preference works, but unfortunately the listener seems to fail.
What do I have to do to get the listener firing when the preference has changed?
Listener in my MainActivity:
private final SharedPreferences.OnSharedPreferenceChangeListener
mPositionFabListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.e(TAG,"Are we getting here?");
// We do not get here when preference has changed. Why not??
// Code to update Floating Action Button to new position
}
};
I register the listener in the onResume() method of the MainActivity and unregister in the onPause().
#Override
protected void onResume() {
super.onResume();
PrefUtils.registerOnPrefChangeListener(mPositionFabListener);
}
#Override
protected void onPause() {
PrefUtils.unregisterOnPrefChangeListener(mPositionFabListener);
super.onPause();
}
The registerOnPrefChangeListener method is declared in a seperate class:
public class PrefUtils {
public static boolean getBoolean(String key, boolean defValue) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApplication.getContext());
return settings.getBoolean(key, defValue);
}
public static void putBoolean(String key, boolean value) {
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(MainApplication.getContext()).edit();
editor.putBoolean(key, value);
editor.apply();
}
public static int getInt(String key, int defValue) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApplication.getContext());
return settings.getInt(key, defValue);
}
public static void putInt(String key, int value) {
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(MainApplication.getContext()).edit();
editor.putInt(key, value);
editor.apply();
}
public static void registerOnPrefChangeListener(OnSharedPreferenceChangeListener listener) {
try {
PreferenceManager.getDefaultSharedPreferences(MainApplication.getContext()).registerOnSharedPreferenceChangeListener(listener);
} catch (Exception ignored) {}
}
public static void unregisterOnPrefChangeListener(OnSharedPreferenceChangeListener listener) {
try {
PreferenceManager.getDefaultSharedPreferences(MainApplication.getContext()).unregisterOnSharedPreferenceChangeListener(listener);
} catch (Exception ignored) {}
}
}
UPDATE:
In the GeneralPrefsFragment class I put in this listener for testing purposes. This listener is working. So why does it not work in the MainActivity?
public class GeneralPrefsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Preference preference = findPreference(PrefUtils.POSITION_FLOATING_MENU_BUTTON);
Preference.OnPreferenceChangeListener mListener = new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
PrefUtils.putBoolean(PrefUtils.POSITION_FLOATING_MENU_BUTTON, Boolean.TRUE.equals(newValue));
PreferenceManager.getDefaultSharedPreferences(MainApplication.getContext()).edit().commit(); // to be sure all prefs are written
Log.e(TAG, "The listener in " + TAG + " is listening");
// This listener is fired as soon as changes in the preference are made!
// Why is the same kind of listener not fired in the MainActivity?
return true;
}
};
preference.setOnPreferenceChangeListener(mListener);
}
}
SOLUTION:
I got a fix. I still do not know why the former setup didn't work, but I got it working, thanks to the code in this answer.
In the MainAcivity's onCreate() method I placed the following listener and this one gets triggered when the preferences have changed.
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.OnSharedPreferenceChangeListener mPrefsFabListener =
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (PrefUtils.POSITION_FLOATING_MENU_BUTTON.equals(key)) {
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
CoordinatorLayout.LayoutParams paramsFab = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
if (PrefUtils.getBoolean(PrefUtils.POSITION_FLOATING_MENU_BUTTON, false)) {
paramsFab.gravity = Gravity.BOTTOM | Gravity.START;
} else {
paramsFab.gravity = Gravity.BOTTOM | Gravity.END;
}
}
}
};
prefs.registerOnSharedPreferenceChangeListener(mPrefsFabListener);
The OnSharedPreferenceChangeListener gets unregistered in the onPause() method of the MainAcitivity. That is a problem, because the MainActivity gets paused as soon as the General Preferences Activity is started in order to change the preferences. So, the listener is unregistered and therefore not listening right at the point where it is needed!
I removed the unregisterOnPrefChangeListener from the onPause() and put in the following code. This worked perfectly!
#Override
protected void onDestroy() {
PrefUtils.unregisterOnPrefChangeListener(mPositionFabListener);
super.onDestroy();
}
Please help me out with my issue. I'm using preference fragment to let users choose to keep screen light on or allow the screen to go dim.
This works well when you get in preferences but once you exit app, it doesn't work on next launch.
Funny, if you open settings screen and click back, the feature works yet again until you exit app.
Would love to know how to fix this.
private void setInitialState() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
if (sp.getBoolean(getString(R.string.keep_screen_on_key), false)) {
startKeepScreenOn();
} else {
dsSwitch.setEnabled(false);
}
}
ksoSwitch = (SwitchPreference)
findPreference(getString(R.string.keep_screen_on_key));
dsSwitch = (SwitchPreference) findPreference(getString(R.string.dim_screen_key));
setInitialState();
ksoSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue.equals(true)) {
dsSwitch.setEnabled(true);
startKeepScreenOn();
}
else {
dsSwitch.setEnabled(false);
wl.release();
wl = null;
}
return true;
}
});
dsSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
wl.release();
startKeepScreenOn();
return true;
}
});
EDIT: I tried this new code but it still seems they are reset. Can anyone tell me, and propose a solution to my settings being reset?
public class UserSettingActivity extends PreferenceActivity implements OnPreferenceChangeListener{
static SwitchPreference mucus_stamps;
static SwitchPreference fertile_infertil;
static SwitchPreference cervical_mucus;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* Populate the activity with the top-level headers.
*/
#Override
public void onBuildHeaders(List<Header> target) {
Log.i("PROJECTCARUSO","onBuildHeaders");
loadHeadersFromResource(R.xml.preference_headers, target);
}
/**
* This fragment shows the preferences for the first header.
*/
public static class Prefs1Fragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.notification_settings);
}
}
/**
* This fragment shows the preferences for the second header.
*/
public static class Prefs2Fragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.charting_settings);
//findPreference("cervical_mucus").setOnPreferenceChangeListener(
mucus_stamps = (SwitchPreference) findPreference("mucus_stamps");
fertile_infertil = (SwitchPreference) findPreference("fertile_infertil");
cervical_mucus = (SwitchPreference) findPreference("cervical_mucus");
cervical_mucus.setOnPreferenceChangeListener(
new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// string test w/o "==" usage.
if (newValue.equals(false)) {
Log.i("PROJECTCARUSO","false");
mucus_stamps.setChecked(false);
fertile_infertil.setChecked(false);
} else {
Log.i("PROJECTCARUSO","true");
mucus_stamps.setChecked(true);
fertile_infertil.setChecked(true);
}
// true instead of false so the new value gets kept
return true;
};
});
if(!cervical_mucus.isChecked()){
mucus_stamps.setSelectable(false);
mucus_stamps.setEnabled(false);
fertile_infertil.setSelectable(false);
fertile_infertil.setEnabled(false);
} else {
mucus_stamps.setSelectable(true);
mucus_stamps.setEnabled(true);
fertile_infertil.setSelectable(true);
fertile_infertil.setEnabled(true);
}
}
}
protected void onPause()
{
super.onPause();
}
protected void onResume()
{
super.onResume();
}
#Override
public boolean onPreferenceChange(Preference arg0, Object arg1) {
// TODO Auto-generated method stub
return true;
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="#string/pref_chart_profile"
android:textSize="20px">
<SwitchPreference
android:title="#+string/pref_symptothermal"
android:summary="#+string/pref_symptothermal_summary"
android:key="symptothermal"
android:defaultValue="true"
android:layout="#layout/pref_layout"/>
<SwitchPreference
android:id="#+id/cervical_mucus"
android:title="#+string/pref_cervical_mucus"
android:summary="#+string/pref_cervical_mucus_summary"
android:key="cervical_mucus"
android:defaultValue="true"
android:layout="#layout/pref_layout" />
<SwitchPreference
android:id="#+id/mucus_stamps"
android:title="#+string/pref_mucus_stamps"
android:summary="#+string/pref_mucus_stamps_summary"
android:key="mucus_stamps"
android:defaultValue="true"
android:layout="#layout/pref_layout" />
<SwitchPreference
android:id="#+id/fertile_infertil"
android:title="#+string/pref_fertile_infertile"
android:summary="#+string/pref_fertile_infertile_summary"
android:key="fertile_infertil"
android:defaultValue="true"
android:layout="#layout/pref_layout" />
</PreferenceCategory>
</PreferenceScreen>
Depending on what you want.
The value is saved(tested), but "selectable" is not a preference value. Therefore you have to set it when the preferencescreen is launched.
Do this:
Before your oncreate:
SwitchPreference mucus_stamps;
Then above your findPreference("mucus_stamps")
mucu_stamps = (SwitchPreference) findPreference("mucus_stamps");
Now, outside the onclicklistener, you can set it.
if(!mucus_stamps.isChecked()){
mucus_stamps.setSelectable(false);
mucus_stamps.setEnabled(false);
}
(I added "setEnablet" to show you that you can disable it aswell, not just make it "non-selectable". Selectable only says that you can't click anything outside the "off/on" area to change it to on/off.)
Personally I prefer to do it like this:
mucus_stamps = (SwitchPreference) findPreference("mucus_stamps");
mucus_stamps.setOnPreferenceChangeListener(
new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
// string test w/o "==" usage.
if (newValue.equals(false)) {
mucus_stamps.setChecked(false);
mucus_stamps.setSelectable(false);
} else {
mucus_stamps.setChecked(true);
}
// true instead of false so the new value gets kept
return true;
};
});
if(!mucus_stamps.isChecked()){
mucus_stamps.setSelectable(false);
mucus_stamps.setEnabled(false);
}
And, you don't need to implement OnPreferenceChangeListener when you do it the way you or I do. Not that it really matters.
:)