I have a problem with onSharedPreferenceChanged is only called the first time when a MultiSelectListPreference has changed. I open my settings activity and change the value which works fine and onSharedPreferenceChanged is getting called. If I open the dialog again, it shows the correct entries selected. I select another entry and hit OK. onSharedPreferenceChanged should now getting called but isn't. If I now open the dialog again, no entries are selected. Am I missing something or did I do somethign wrong?
Here's my preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<MultiSelectListPreference
android:key="operations"
android:title="#string/pref_operations"
android:dialogTitle="#string/pref_operations"
android:entries="#array/pref_operations_entries"
android:entryValues="#array/pref_operations_values"
android:defaultValue="#array/pref_operations_default" />
</PreferenceScreen>
And my settings fragment
public class SettingsFragment extends PreferenceFragment
implements SharedPreferences.OnSharedPreferenceChangeListener
{
public static final String KEY_OPERATIONS_PREFERENCE = "operations";
private MultiSelectListPreference operationsPreference;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
operationsPreference = (MultiSelectListPreference) getPreferenceScreen().findPreference(KEY_OPERATIONS_PREFERENCE);
}
#Override
public void onResume()
{
super.onResume();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
Set<String> operations = operationsPreference.getValues();
String summary = "";
for (String s : operations)
summary += s + " ";
operationsPreference.setSummary(summary);
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause()
{
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
if (key.equals(KEY_OPERATIONS_PREFERENCE))
{
Set<String> operations = operationsPreference.getValues();
String summary = "";
for (String s : operations)
summary += s + " ";
operationsPreference.setSummary(summary);
}
}
}
Umm frankly I built my sharedPreferances differently...ill attach my code example and hopefully it'll be of use to you
here goes:
this is the sharedpreferences class
public class AppPreferences {
public static final String KEY_LANG = "language";
final String APP_SHARED_PREFS = AppPreferences.class.getSimpleName(); // Name
// of
// the
// file
// -.xml
private SharedPreferences _sharedPrefs;
private Editor _prefsEditor;
public AppPreferences(Context context) {
this._sharedPrefs = context.getSharedPreferences(APP_SHARED_PREFS,
Activity.MODE_PRIVATE);
this._prefsEditor = _sharedPrefs.edit();
}
public String getlanguage() {
return _sharedPrefs.getString(KEY_LANG, "");
}
public void savelanguage(String text) {
_prefsEditor.putString(KEY_LANG, text);
_prefsEditor.commit();
}
}
to use it youll need to create
in your class
private AppPreferences _appPrefs;
and an example for use is
_appPrefs = new AppPreferences(getApplicationContext());
_appPrefs.savelanguage("English");
language = _appPrefs.getlanguage();
this is how i built it... works like a charm... and not complicated at all
It's because you unregister the listener in your onPause callback method which is invoked when Dialog is shown in an Activity.
Related
I'm using android studio for a project api 21 minimum,
I have an activity with a textfield and a button, when click, I want the text of the textfield stored for the life of the application, I'm using a global variable for that.
I've got a class variable that extends Application:
package com.example.user.variableglobale;
import android.app.Application;
public class Variable extends Application {
private String chiffre;
public String getChiffre() {
return this.chiffre;
}
public void setChiffre(String chiffre) {
this.chiffre = chiffre;
}
inside my main :
final Variable VG = (Variable) getApplication();
final TestVar tV = new TestVar();
btnOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tV.testVar(MainActivity.this);
VG.setChiffre(String.valueOf(txt.getText()));
}
});
and here is the java class called with the button:
public class TestVar {
public void testVar(Context context) {
Variable VG = (Variable) context.getApplicationContext();
String temp = VG.getChiffre();
Toast.makeText(context.getApplicationContext(), "test java VG " + temp, Toast.LENGTH_SHORT).show();
}
}
Can anyone explain the way to use global variable inside java class?
When I click on the button, a toast appears with a "null" value for "temp" (seem to be not initialized).
In my example, I tried with "context", to no avail.
ok, finally it work,
inside my onclickListener i have to swap declaration of variable and calling of my class... everything ok
I think a better way to store that variable would be to store it in shared preferences. You can access it in any activity and it persists even if app is closed.
You can use it withoud needing a class for variable like this.
main:
static final String CHIFFRE_KEY = "chiffre_key";
final TestVar tV = new TestVar();
btnOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(CHIFFRE_KEY, String.valueOf(txt.getText()));
editor.commit();
tV.testVar(MainActivity.this);
}
});
and testVar method would look like this
public void testVar(Context context) {
String vg = getActivity().getPreferences(Context.MODE_PRIVATE).getString(CHIFFRE_KEY);
Toast.makeText(context.getApplicationContext(), "test java VG " + vg, Toast.LENGTH_SHORT).show();
}
You can read more about Shared Preferences here
I'm posting this question again as I didn't get any answers last time, and I still haven't solved the problem.
I have a settings menu with a PreferenceScreen in which I create a lot of CheckBoxPreferences during runtime (Adding them into the "Exclusion List" prefscreen). I created them no problem, here's the XML code below that it starts with:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen
android:key="exclusion_list_key"
android:title="Exclusion List"
android:persistent="true"
android:summary="" >
</PreferenceScreen>
</PreferenceScreen>
I create the checkboxes in the onCreate method of my PreferenceFragment and add them to the "Exclusion List" PreferenceScreen and that works fine.
I'm trying to set the summary of the "Exclusion List" to be a list of all the checkbox titles that are checked off (so if the checkbox is checked, it's name will be listed in the summary of the "Exclusion List").
In the onCreate() method, the summary gets set properly, there's no problem.
But in the onPreferenceChanged() method, I set the summary of "Exclusion List" to the 'summary' string I built (which contains the correct value), but it doesn't update it! When i press back from my checkbox menu, the "Exclusion List" does not have the updated values.
The last few lines are the ones of interest. I did some printlns to see what's going on:
The listener works fine, runs when expected
My summary var contains what's expected
After calling setSummary(summary), the getSummary() returns the expected value (so that means it got set properly)
However, when I actually press back and see "Exclusion List", it's summary doesn't actually get updated!
Did I miss something? Thanks in advance!
All the code for reference:
public class Settings extends AppCompatActivity {
public static final String EXC_LIST_KEY = "exclusion_list_key";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
String summary = "";
//Create all the checkboxes inside of the PreferenceScreen
for (int i = 0; i < MainActivity.contactNames.length; i++) {
CheckBoxPreference checkbox = new CheckBoxPreference(getActivity());
checkbox.setTitle(MainActivity.contactNames[i][0]);
checkbox.setKey(MainActivity.contactNames[i][2]);
checkbox.setSummary(MainActivity.contactNames[i][1]);
checkbox.setDefaultValue(false);
((PreferenceScreen) findPreference(EXC_LIST_KEY)).addPreference(checkbox);
if (checkbox.isChecked()) {
summary = summary + checkbox.getTitle() + "\n";
}
}
findPreference(EXC_LIST_KEY).setSummary(summary);
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
//Checkbox keys all start with 'key_'
if (key.startsWith("key_")) {
String summary = "";
for (int i = 0; i < MainActivity.contactNames.length; i++) {
CheckBoxPreference checkbox = (CheckBoxPreference) findPreference(MainActivity.contactNames[i][2]);
if (checkbox.isChecked()) {
summary = summary + checkbox.getTitle() + "\n";
}
}
System.out.println("Summary I have: " + summary); //Correct summary is printed out
findPreference(EXC_LIST_KEY).setSummary(summary); //Isn't updating the value???
System.out.println("Summary system has: " + findPreference(EXC_LIST_KEY).getSummary()); //Correct summary is printed out
}
}
}
}
try Adding this code in your SettingsFragment
#Override
public void onResume() {
super.onResume();
SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
// CHANGE 1: load saved values to set the summaries
onSharedPreferenceChanged(prefs, "exclusion_list_key");
// CHANGE 2: register shared prefs listener in onResume
prefs.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
super.onPause();
SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
prefs.unregisterOnSharedPreferenceChangeListener(this);
}
Got it working by adding the following line of code to the end of my onSharedPreferenceChanged() method:
((BaseAdapter)getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
I'm creating a PreferenceFragment based on the developer guide but I get a NullPointerException at the getDefaultSharedPreferences() call in onCreate() when I try to restore saved user preferences. I inflate the PreferenceFragment from xml and I set default values too. The exception is thrown at getDefaultSharedPreferencesName() within getDefaultSharedPreferences().
Here is the PreferenceFragment class:
public class SettingsFragment extends PreferenceFragment implements
OnSharedPreferenceChangeListener {
public static final String KEY_MAX_WALK_DISTANCE_PREFERENCE = "max_walk_distance_preference";
public static final String KEY_MAX_SEARCH_TIME_PREFERENCE = "max_search_time_preference";
Context context = getActivity();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
// load user preferences
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(context);
if (sharedPreferences != null) {
Preference walkDistance = findPreference(KEY_MAX_WALK_DISTANCE_PREFERENCE);
if (walkDistance != null) {
walkDistance.setSummary(sharedPreferences.getString(
KEY_MAX_WALK_DISTANCE_PREFERENCE, "")
+ getResources().getString(
R.string.max_walk_distance_postfix));
}
Preference searchTime = findPreference(KEY_MAX_SEARCH_TIME_PREFERENCE);
if (searchTime != null) {
searchTime.setSummary(sharedPreferences.getString(
KEY_MAX_SEARCH_TIME_PREFERENCE, "")
+ getResources().getString(
R.string.max_search_time_postfix));
}
}
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key.equals(KEY_MAX_WALK_DISTANCE_PREFERENCE)) {
Preference walkDistance = findPreference(key);
// Set summary to be the user-description for the selected value
walkDistance.setSummary(sharedPreferences.getString(key, "")
+ getResources().getString(
R.string.max_walk_distance_postfix));
} else if (key.equals(KEY_MAX_SEARCH_TIME_PREFERENCE)) {
Preference searchTime = findPreference(key);
// Set summary to be the user-description for the selected value
searchTime.setSummary(sharedPreferences.getString(key, "")
+ getResources()
.getString(R.string.max_search_time_postfix));
}
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
}
Here is the XML:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<EditTextPreference
android:dialogTitle="#string/max_walk_distance_dialogtitle"
android:key="max_walk_distance_preference"
android:summary="#string/max_walk_distance_summary"
android:title="#string/max_walk_distance_title"
android:inputType="number"
android:defaultValue="500" />
<EditTextPreference
android:dialogTitle="#string/max_search_time_dialogtitle"
android:key="max_search_time_preference"
android:summary="#string/max_search_time_summary"
android:title="#string/max_search_time_title"
android:inputType="number"
android:defaultValue="10"/>
</PreferenceScreen>
Context context = getActivity();
Your fragment is not associated with any activity when the object is instantiated and getActivity() returns null. Hence the NPE when trying to get preferences with a null Context.
Postpone the getActivity() to e.g. your onCreate() (which is called after onAttach()).
getActivity returns untill onAttach is called. Change
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(context)
with
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(getActivity())
I'm writing an app for the Sony Smartwatch, using their SDK. Here's part of the main activity:
class SmartTickerActivity extends ControlExtension {
private Handler mHandler;
SmartTickerActivity(final String hostAppPackageName, final Context context, Handler handler) {
super(context, hostAppPackageName);
if (handler == null) {
throw new IllegalArgumentException("handler == null");
}
}
#Override
public void onStart() {
//do some stuff
PreferenceManager.setDefaultValues(mContext, R.xml.preference, false);
}
The problem is that the saved preferences aren't being applied on the Smartwatch when the application launches. Nor are the default preference values from XML. However, if I click on any of the app's preferences on the phone, the saved preference values are immediately applied to the Smartwatch.
Note that the main class has no onCreate() method, and that's throwing me for a loop.
Here's part of the Preference activity:
public class MyPreferenceActivity extends PreferenceActivity {
private OnSharedPreferenceChangeListener mListener = new OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = findPreference(key);
if (pref instanceof ListPreference) {
ListPreference listPref = (ListPreference) pref;
pref.setSummary(listPref.getEntry().toString());
}
if (pref instanceof EditTextPreference) {
EditTextPreference editTextPref = (EditTextPreference) pref;
pref.setSummary(editTextPref.getText().toString());
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preference);
setSummaries();
setTypeface(SmartTickerActivity.mainLayout);
if (previewLayout != null) setTypeface(previewLayout);
// Handle read me
Preference readMe = findPreference(getText(R.string.preference_key_read_me));
readMe.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference readMe) {
showDialog(DIALOG_READ_ME);
return true;
}
});
// Handle about
Preference about = findPreference(getText(R.string.preference_key_about));
about.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference about) {
showDialog(DIALOG_ABOUT);
return true;
}
});
// Handle preview
Preference preview = findPreference(getText(R.string.preference_key_preview_dialog));
preview.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preview) {
showDialog(DIALOG_PREVIEW);
return true;
}
});
}
I'm rather inexperienced at Android development, so the problem might very well have nothing to do whatsoever with the Sony SDK. Can anyone help?
You are correct, the preferences of the official sample extensions are not loaded until the PreferenceActivity is shown for the first time. If you use correct default values when accessing the preferences, this should not be a problem.
If you would like for the preferences to be loaded when the extension is initiated the first time, you could extend the android.app.Application class, and the onCreate method.
For example:
public class MySmartWatchApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
PreferenceManager.setDefaultValues(this, R.xml.app_preferences, false);
}
}
I'm trying to save some filters/state in one activity, and then use that data in the next activity.
I'm using SharedPreferences, but it isn't working as I'd expected it to.
public class FilterActivity extends Activity {
private static final String TAG = FilterActivity.class.getName();
EditText distanceEditor;
#Override
public void onPause() {
super.onPause();
SharedPreferences preferences = getSharedPreferences(PreferenceKey.FILTER_PREFERENCES_NAME, MODE_WORLD_READABLE);
String distance = distanceEditor.getText().toString();
preferences.edit().putString(PreferenceKey.DISTANCE, distance);
preferences.edit().commit();
Log.i(TAG, "Wrote max-distance=" + distance);
Log.i(TAG, "Preferences contains distance=" + preferences.getString(PreferenceKey.DISTANCE, "FAIL"));
}
public static class PreferenceKey {
public static final String FILTER_PREFERENCES_NAME = "FilterActivity:" + "Filter_Preference_File";
public static final String DISTANCE = "FilterActivity:" + "DISTANCE";
}
}
Then, the Activity that should use this preference:
public class MapActivity extends MapActivity {
#Override
public void onResume() {
super.onResume();
SharedPreferences preferences = getSharedPreferences(FilterActivity.PreferenceKey.FILTER_PREFERENCES_NAME, MODE_WORLD_READABLE);
String maxDistance = preferences.getString(FilterActivity.PreferenceKey.DISTANCE, "FAIL");
Log.i(TAG, "Read max-distance=" + maxDistance);
}
}
But the output I get is:
.FilterActivity( 4847): Wrote max-distance=99.9
.FilterActivity( 4847): Preferences contains distance=FAIL
.MapActivity( 4847): Read max-distance=FAIL
Can anyone tell me what I'm doing wrong here?
I am developing against API Level-8.
In the following two lines,
preferences.edit().putString(PreferenceKey.DISTANCE, distance);
preferences.edit().commit();
two different SharedPreferences.Editors are being returned. Hence the value is not being committed. Instead, you have to use:
SharedPreferences.Editor spe = preferences.edit();
spe.putString(PreferenceKey.DISTANCE, distance);
spe.commit();