2

My code here will be simplified for readability.

Methods for getting the Set and adding a password to it:

public void addPass(String pass)
{
   // Get the current list.
   SharedPreferences sp = getSharedPreferences("passes", 0);
   SharedPreferences.Editor editor = getSharedPreferences("passes", 0).edit();
   Set<String> passes = sp.getStringSet("myStrings", new HashSet<String>());

   // Add the new value.
   passes.add(pass);

   // Save the list.
   editor.putStringSet("myStrings", passes);
   editor.commit();
}

public Set<String> getPasses()
{
    SharedPreferences sp = getSharedPreferences("passes", 0);
    return sp.getStringSet("myStrings", new HashSet<String>());
}

Reading from the Set

Set<String> x = getPasses();
String[] passes = x.toArray(new String[0]); // convert the set to array

toast(Arrays.toString(passes)); // test what the set looks like

I converted the set to an array because it was easier to test conditions with an array for me.

Adding to the Set

EditText password1 = new EditText(this);
String p1 = password1.getText().toString();

addPass(p1.trim()); // add it to the set
toast("Account successfully created.");

Problem

When I first ran this code, I added three String values: "a", "b", "c" (in that order).

All the value were added to the Set correctly and it was confirmed with this line of code from above:

toast(Arrays.toString(passes)); // test what the set looks like

It outputted [b, c, a] after the "c" was added to the set.

The problem is that when I closed the app and reopened it, the Set only contained "a". I could add the "b" and "c" values again, but the cycle would just continue where the Set only kept the first value added to it after the activity was recreated.

I've troubleshooted for a while and cannot fix it. I can provide more detail on how and when I'm using this code if necessary. I'm hoping I don't need to and someone can point out a problem in the code as shown.

Michael Yaworski
  • 13,410
  • 19
  • 69
  • 97

3 Answers3

3

Was searching for a solution for the same issue, a solution to this would be

// Get the current list.
SharedPreferences sp = getSharedPreferences("passes", 0);
SharedPreferences.Editor editor = getSharedPreferences("passes", 0).edit();
Set<String> passes = sp.getStringSet("myStrings", new HashSet<String>());

//Make a copy, update it and save it
Set<String> newPasses = new HashSet<String>();
newPasses.add(pass);
newPasses.addAll(passes);
editor.putStringSet("myStrings", newPasses); editor.commit();
s-hunter
  • 24,172
  • 16
  • 88
  • 130
1

It might be that your issue stems from using getStringSet(), have a look at the docs:

public abstract Set<String> getStringSet (String key, Set<String> defValues)

Retrieve a set of String values from the preferences.

Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all.

Michael Yaworski
  • 13,410
  • 19
  • 69
  • 97
Melquiades
  • 8,496
  • 1
  • 31
  • 46
1

Based on this doc , and this SO Post about the exact same problem as yours, it seems you should create a new copy of the returned instance of the HashSet, and you seem to have done that, at least from what code you've pasted here. Maybe there's something else that's being missed.

However, check out the answer on this post . What the guy did was:

  • Add the first value to SharedPreferences as a String Set.
  • To add subsequent values, first read the existing pref into a new String Set.
  • Remove the old String Set key.
  • Modify the new string set to add the new values you want to store.
  • Add the new String Set to preferences.

While that is a long and silly way to do things, it seems like the last option. So basically, store all the values you want to store, in one go (not in instalments). If you want to add new values, remove the old key, create a new key with the old + new values, then store the new key.

Hope that helps.

Community
  • 1
  • 1
sanjeev mk
  • 4,276
  • 6
  • 44
  • 69
  • "it seems you should create a new copy of the returned instance of the HashSet, and you seem to have done that" -> where has he done that ? (also @mikeyaworski) – Mr_and_Mrs_D Dec 23 '13 at 12:36
  • @Mr_and_Mrs_D This line in `add_pass` : `Set passes = sp.getStringSet("myStrings", new HashSet());` . `passes` is a new instance created there. – sanjeev mk Dec 23 '13 at 12:42
  • Nope - the `new HashSet())` is just the default value. It's an exact dup of the post you linked to – Mr_and_Mrs_D Dec 23 '13 at 17:28