Shared preferences inactive on app exit - android

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;
}
});

Related

Starting a service via a SwitchPreference

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;
}
});
}
}

How to evaluate Checkboxpreference?

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.

Change in shared preference not firing

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();
}

How to change SwitchPreference title when is clicked

I'm working with my PreferenceActivity where I have a SwitchPreference to which I didn't assing a title using android:title="Title" because I'd like to change it whenever the Switch is clicked.
I've tried this way but didn't work. I also searched on SO related topics without solving my problem.
public class PrefsFragment extends PreferenceFragment {
private SwitchPreference pref;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
// Load the preferences from an XML resource
pref = (SwitchPreference)findPreference("SWITCH");
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue.toString().equals("SWITCH")) {
boolean test = (Boolean) newValue;
if (test) {
pref.setTitle("ChangedTitle");
} else {
pref.setTitle("DefaultTitle");
}
}
return true;
}
});
}
}
settings.xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="Settings">
<ListPreference
android:key="yourPref"
android:title="Title"
android:dialogTitle="Select"
android:summary="%s"
android:defaultValue="4"
android:entries="#array/titles"
android:entryValues="#array/values"/>
</PreferenceCategory>
<PreferenceCategory
android:title="Title">
<SwitchPreference
android:key="SWITCH"/>
</PreferenceCategory>
</PreferenceScreen>
Could you help me please?
Try calling preference.setTitle("YOUR TEXT"); within the listener callback, rather than pref.setTitle"YOUR TEXT"); The listener is passing in the preference that was changed.
The problem is with your OnSharedPreferenceChangeListener.
Instead of this,
pref = (SwitchPreference)findPreference("SWITCH");
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue.toString().equals("SWITCH")) {
boolean test = (Boolean) newValue;
if (test) {
pref.setTitle("ChangedTitle");
} else {
pref.setTitle("DefaultTitle");
}
}
return true;
}
});
Try this
SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
if (s.equals("SWITCH")) {
SwitchPreference sp = (SwitchPreference) findPreference(s);
boolean test = sharedPreferences.getBoolean(s, false);
if (test) {
sp.setTitle("ChangedTitle");
} else {
sp.setTitle("DefaultTitle");
}
}
}
}

Using AsyncTask in PreferenceFragment

I am tring to create a sharedpreference to save some authentication info to a third party service. In my preferences.xml there is a login and password fields but i would like to check if the values are valid (authenticate) when edited. What would be a good approach?
So far, i have this:
on create
findPreference("sync_service_enabled").setOnPreferenceChangeListener(this);
findPreference("sync_service_user").setOnPreferenceChangeListener(this);
findPreference("sync_service_pwd").setOnPreferenceChangeListener(this);
my listener
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference.getKey().contains("sync_service")){
new AuthenticationRemoteAsyncTask(this.getActivity(), user, password, service).execute();
}
return true;
I also need to save a token generated by the remote service so I need to wait for the aynstask to be finished.
Any sugestion?
I resolved my problem criating a custom dialogpreference. I Replaced the positive button onclicklistener so it dont close the dialog automatically and start my remote task. The asynctask will notify my preferencedialog after success and only then I close the dialog.
CODE
#Override
protected void showDialog(Bundle state) {
super.showDialog(state);
...
positiveButton.setOnClickListener(this);
negativeButton.setOnClickListener(this);
}
onclick handler
public void onClick(View view){
this.result = null;
if(view.getId() == positiveButton.getId()) {
String password = textPassword.getText().toString();
String user = textLogin.getText().toString();
new AuthenticationTask(getContext(),user, password)
.notify(this).execute();
}else{
alertDialog.dismiss();
}
}
check the result before close
#Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (result != null) {
SharedPreferences.Editor editor = getEditor();
editor.putString("sync_service_token",result);
editor.commit();
}
}
AuthenticationTask is a custom class that wrapp all the async stuff and call a notify method.

Categories

Resources