I have in preferences.xml following EditTextPreference:
<EditTextPreference
android:name="#string/pref_test"
android:defaultValue="0.6"
android:inputType="numberDecimal"
android:key="editTestPref"
android:maxLength="5"
android:summary=""
android:title="#string/pref_test" />
In one of my activities I read the value.
But the problem is if the user enters nothing (""), my app crashes. Sure I could do a if statement in the activity to check if its empty string, but I want to do following:
In Preferences.java I get changes of the preferenceEditText. There I want to set a default value if the user enters "":
if (preference.getKey().equals("editTestPref")) {
if(newValue.equals(""))
{
final SharedPreferences.Editor prefsEditor = prefs.edit();
prefsEditor.putString("editTestPref", "1");
prefsEditor.commit();
summary = "0.6"; // to update the summary of preference
}
else
{
summary= (String) newValue;
}
}
I also tried this code:
SharedPreferences customSharedPreference = getSharedPreferences(
"myCustomSharedPrefs", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = customSharedPreference
.edit();
editor.putString("editTestPref", "1");
editor.commit();
Both do not work, they do not update the sharedPreference value. It is still "".
Implement SharedPreferences.OnSharedPreferenceChangeListener like so:
public class YourPrefsActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
// ... your existing code ...
#Override
protected void onResume() {
super.onResume();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// Set up a listener whenever a key changes
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if ("editTestPref".equals(key)) {
String val = sharedPreferences.getString("editTestPref", "");
if (val == null || val.trim().equals("")) {
val = "0.6"; // <-- your default value
sharedPreferences.edit().putString(key, val).commit();
}
}
}
}
The method is called when the user changed the preferences value, and checks if he entered an empty string. If so, the value is replaced by your default value.
You should rather use if(newValue.isEmpty()) instead of checking the characters
i dont see anything wrong in your code but try this if it works..
Replace this
prefsEditor.putString("editTestPref", "1");
with
prefsEditor.putString("editTestPref", String.valueof(1));
Best Luck.
Related
Got a problem with the Shared Preferences in Android - I want to be able to put some Strings (Save the IDs of a Picture) as favorite for the next launches - it works perfect, it recognizes if the ID is already inside the Shared Preferences and removes it if necessary, but when I stop the App by pressing the home button (without killing the app process) and then return to it, it doesn´t recognize it anymore. If I kill the process and restart the app, it works fine.
So here´s my code
MainActivity onCreate
preferences = getSharedPreferences("favo", MODE_PRIVATE);
edit = getSharedPreferences("favo", MODE_PRIVATE).edit();
MainActivity onResume
#Override
protected void onResume() {
preferences = getSharedPreferences("favo", MODE_PRIVATE);
edit = getSharedPreferences("favo", MODE_PRIVATE).edit();
super.onResume();
}
I´ve already tried to do it without onResume but it doesn´t change the result.
Method to change the Shared Preferences
if (checkTheSharedPreferences(numberFavo)){
v.setBackgroundResource(R.drawable.favo);
edit.putString(pref, pref);
edit.apply();
showIt = "Zu Favoriten hinzugefügt";
}else{
v.setBackgroundResource(R.drawable.favo2);
edit.remove(pref);
edit.apply();
showIt = "Aus Favoriten entfernt";
}
If my method to check if the SharedPreferences returns true it means that the String isn´t inside the SharedPrefs and can be added, otherwise it will be removed as the user wants to remove it from his favorites.
Method to check if the String is inside the Prefs
public Boolean checkTheSharedPreferences(int number) {
SharedPreferences preferences = getSharedPreferences("favo", MODE_PRIVATE);
Map<String, ?> map = preferences.getAll();
for (Map.Entry<String, ?> entry : map.entrySet()) {
if (entry.getValue().toString().equals(bilderIDs.get(number))) {
return false;
}
}
return true;
}
As mentioned above, it works perfect, unless the App gets invisible/into the background and is opened again without a restart.
Thanks in advance
EDIT
Seems like it works if I wait for about 30 seconds after onResume is called, but that´s not really a possibility to wait for so long as it is on the UI Thread and the User might presses the button to remove/add the SharedPref within the 30 seconds
SharedPreferences.Editor.apply() is a async method.It will store values in other thread.SharedPreferences.Editor.commit() is a sync method.
if (checkTheSharedPreferences(numberFavo)){
v.setBackgroundResource(R.drawable.favo);
edit.putBoolean("myfav" + numberFavo, true);
edit.commit();
showIt = "Zu Favoriten hinzugefügt";
}else{
v.setBackgroundResource(R.drawable.favo2);
edit.remove("myfav" + numberFavo);
edit.commit();
showIt = "Aus Favoriten entfernt";
}
public Boolean checkTheSharedPreferences(int number) {
SharedPreferences preferences = getSharedPreferences("favo", MODE_PRIVATE);
return preferences.getBoolean("myfav" + number,false);
}
#Override
protected void onResume() {
super.onResume();
preferences = getSharedPreferences("favo", MODE_PRIVATE);
edit = getSharedPreferences("favo", MODE_PRIVATE).edit();
}
I try call SharedPreferences, and I pass a parameters but not work (not update and not put data)
I don't know I do wrong?
public void put(String value){
SharedPreferences.Editor editor = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE).edit();
editor.putString("isFirstRunCheck", value);
editor.commit();
}
public void checkFirstRun3(){
SharedPreferences prefs = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);
String restoredText = prefs.getString("text", null);
String name ="";
if (restoredText != null) {
name = prefs.getString("isFirstRunCheck", "");//"No name defined" is the default value.
}
if(name.equals("true")){
Toast.makeText(getActivity(), "click si ", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getActivity(), "click no ", Toast.LENGTH_SHORT).show();
}
}
I put my "put()" I do not see it work
if(cbx.isChecked()){
put("true");
}else{
put("false");
}
cbx.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(cbx.isChecked()){
put("true");
}else{
put("false");
}
}
});
I'm not sure why you don't think this is working, but I'm guessing it is because your code doesn't do what you think it does.
First of all, the comment on this line is wrong:
name = prefs.getString("isFirstRunCheck", "");//"No name defined" is the default value.
The second parameter to getString() is the default value- in this case you are specify that the default value should be an empty string if you have not previously saved a value to the "isFirstRunCheck" key.
Second, you seem to be expecting a value of "si". However, you are only ever calling put("true") and put("false")- you never call put("si"), so your conditional in checkFirstRun3() will always be false.
As an aside, a String is an odd way to save boolean data. SharedPreferences has a getBoolean() and a putBoolean() that will likely suit your needs better.
Try to change
SharedPreferences.Editor editor = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE).edit();
to
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(YourActivity.this);
SharedPreferences.Editor spe = sp.edit();
Use
spe.putString("yourStringKey", yourStringValue).commit()
and then get your data using the "yourStringKey"
and don't forget to call your put(someData) method.
Got this code, which basicly updates my textviews depending on how far the user is in the quiz, which is stored in sharedPrefs. But when the correct answer is entered the prefs doesn't update. Does the commit() need too long time to set the prefs, so the activity calls the method setText() before the sharedPrefs are updated or what am i doing wrong?
private void setText() {
SharedPreferences score = this.getSharedPreferences("football", MODE_PRIVATE);
questionNumber = score.getInt("football", 0);
question.setText(questions.get(questionNumber).get(0));
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.bCheckAnswer:
if (questions.get(questionNumber).contains(etAnswer.getText().toString())) {
Integer newQ = questionNumber += 1;
SharedPreferences change = this.getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = change.edit();
editor.putInt("football", newQ);
editor.commit();
setText();
}else{
question.setText("error occured");
}
break;
}
You're not opening the SharedPreference the same way when setting and getting.
Change this:
SharedPreferences change = this.getPreferences(Context.MODE_PRIVATE);
to this:
SharedPreferences change = this.getSharedPreferences("football", MODE_PRIVATE);
Notice the differences:
getPreferences vs getSharedPreferences
you didn't give the preference reference as "football"
Are you sure the prefs doesn't get updated or is it just that your textview isn't getting updated? If this is being done in your Activity, you should not be changing layout (your text view) from within the Activity. You should use a Handler to make UI changes.
I know, this issue has been dealt with in many threads, but I cannot figure out this one.
So I set a shared preference like this:
SharedPreferences prefs = MainActivity.this.getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putStringSet(spinnerName, myValueSet );
editor.apply();
I read the preferences like this:
SharedPreferences prefs = MainActivity.this.getPreferences(MODE_PRIVATE);
Set<String> spinnerValuesSet = null;
spinnerValuesSet = prefs.getStringSet(spinnerName,null );
Everything works, except for my changes are visible while this activity runs i.e. - I display the values from the SharedPreferences, allow the user to delete or add and then update the ListView. This works, but after I restart the application, I get the initial values.
This for example is my method to delete one value from the list, update the values in SharedPreferences and update the ListView
Button btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
SharedPreferences prefs = MainActivity.this.getPreferences(MODE_PRIVATE);
Set<String> spinnerValuesSet = prefs.getStringSet(spinnerName,null );
for (String s : spinnerValuesSet)
{
if(s == currentSelectedItemString)
{
spinnerValuesSet.remove(s);
SharedPreferences.Editor editor = prefs.edit();
editor.putStringSet(spinnerName, spinnerValuesSet );
editor.apply();
break;
}
}
updateListValues();
}
});
And this is the method that updates the ListView:
private void updateListValues()
{
SharedPreferences prefs = MainActivity.this.getPreferences(MODE_PRIVATE);
Set<String> spinnerValuesSet = prefs.getStringSet(spinnerName,null );
if(spinnerValuesSet.size() > 0)
{
names = new ArrayList<String>();
names.clear();
int k=0;
for (String s : spinnerValuesSet) {
names.add(k, s);
k++;
}
namesAA = new ArrayAdapter<String> ( this, android.R.layout.simple_list_item_activated_1, names );
myList.setAdapter(namesAA);
}
}
Any help is much appreciated.
The Objects returned by the various get methods of SharedPreferences should be treated as immutable. See SharedPreferences Class Overview for reference.
You must call remove(String) through the SharedPreferences.Editor returned by SharedPreferences.edit() rather than directly on the Set returned by SharedPreferences.getStringSet(String, Set<String>).
You will need to construct a new Set of Strings containing the updated content each time since you have to remove the Set entry from SharedPreferences when you want to update its content.
Problem happens because the Set returned by SharedPreference is immutable. https://code.google.com/p/android/issues/detail?id=27801
I solved this by created a new instance of Set and storing in all the values returned from SharedPreferences.
//Set<String> address_ids = ids from Shared Preferences...
//Create a new instance and store everything there.
Set<String> all_address_ids = new HashSet<String>();
all_address_ids.addAll(address_ids);
Now use the new instance to push the update back to SharedPreferences
I may be wrong but I think the way you are retrieving the Shared Preferences is the problem. Try using
SharedPreferences prefs = getSharedPreferences("appPreferenceKey", Context.Mode_Private);
Use editor.commit(); instead of editor.apply();
Example Code:
SharedPreferences prefs = MainActivity.this.getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putStringSet(spinnerName, myValueSet );
editor.commit();
I hope this helps.
Depending on the OS Build you may have to save values in a different way.
boolean apply = Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD;
public static void saveValue(SharedPreferences.Editor editor)
{
if(apply) {
editor.apply();
} else {
editor.commit();
}
}
I'm writing an android app with a preferencesActivity in which selections made in my instance of preferencesActivity affect the values of other preferences items displayed. While I'm able to change the values of the underlying SharedPreferences items pogrammatically, those changed values aren't reflected in the displayed list items until I exit my preferencesActivity and reload it. Below is a stripped down version of my settings class and xml file which illustrate the problem. If a user sets Guitar as the value for the preference with the key instrumentList, I'd like the preference with key tuningChoice to revert to Standard.
//necessary import declarations go here
public class Settings extends PreferenceActivity implements OnSharedPreferenceChangeListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(this);
app_preferences.registerOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged (SharedPreferences sharedPreferences, String key) {
Log.d("onSharedPreferencesChanged", "sharedPreferences changed. key: " + key);
Editor preferencesMod = sharedPreferences.edit();
String instrumentChoice = sharedPreferences.getString("instrumentList", "Guitar");
if(key.equals("instrumentList")) {
Log.d("Settings", "key is instrumentList. chooseTuning before if: " + sharedPreferences.getString("chooseTuning", "no luck"));
if(instrumentChoice.equals("Guitar")) {
preferencesMod.putString("chooseTuning", "Standard");
preferencesMod.commit();
Log.d("Settings", "chooseTuning after if: " + sharedPreferences.getString("chooseTuning", "ciao"));
}
}
}
}
xml file preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="Settings">
<ListPreference android:title="Choose an Instrument" android:key="instrumentList" android:entryValues="#array/instruments" android:entries="#array/instruments"/>
<ListPreference android:title="Choose Tuning" android:key="chooseTuning" android:entryValues="#array/tuningChoices" android:entries="#array/tuningChoices" android:persistent="true"/>
</PreferenceScreen>
I can call addPreferencesFromResource again in my onSharedPreferenceChanged method and that loads a duplicate of all the preferences items, displayed below the old items, with the correct values. If I could figure out some way to cancel out the initial addPreferencesFromResource called during onCreate, I guess I would be set.
Any help would be appreciated, Thanks
I do something along these lines...hopefully it helps:
ListPreference list = (ListPreference) getPreferenceManager().findPreference("myList");
list.setValue(sharedPrefs.getString("myList", "default"));
list.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
sharedPrefs.put("myList", newValue.toString());
return true;
}
});
You need to prevent addPReferencesFromResource from running twice? Is this loading your default values? If so, add an additional SharedPreference called DEFAULTS_LOADED and read its value in on create like: (WARNING PSUEDO CODE):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean loadDefaults = app_preferences.getBoolean(DEFAULTS_LOADED, true);
if(loadDefaults)
{
addPreferencesFromResource(R.xml.preferences);
Editor editor = app_preferences.edit();
editor.putBoolean(DEFAULTS_LOADED, true);
editor.commit();
}
app_preferences.registerOnSharedPreferenceChangeListener(this);
}
This will prevent you defaults from being written to the shared preferences every time your activity starts. I assume this is at least a portion of your issue.
If anyone comes to this problem, this is the solution:
ListView list = preferenceActivity.getListView();
list.performItemClick(list, 1, list.getItemIdAtPosition(1));
Maybe I am too late for answering this. But, I hope this might help beginner like me.
PackageInfo packageInfo = null;
try {
packageInfo = preference.getContext().getPackageManager().getPackageInfo(preference.getContext().getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
preference.setSummary(packageInfo.versionName);