11

I am building an Android Application. I want to store a set of strings in the Preferences to order to track who used the application based on their log in information.

I don't want to use a database so I know that I should use SharedPreferences to store a list of people who logged in. I want to be able to reset this list so keeping the individual log in data as Strings and NOT as StringSets is not an option. Using individual Strings means that I'll have to keep another list of those strings just so I can clean them up when I want to. A StringSet is easier to maintain.

Here's what I did thus far:

    //this is my preferences variable
    SharedPreferences prefs = getSharedPreferences("packageName", MODE_PRIVATE);

    //I create a StringSet then add elements to it
    Set<String> set = new HashSet<String>();
    
    set.add("test 1");
    set.add("test 2");
    set.add("test 3");

    //I edit the prefs and add my string set and label it as "List"
    prefs.edit().putStringSet("List", set);

    //I commit the edit I made
    prefs.edit().commit();

    //I create another Set, then I fetch List from my prefs file
    Set<String> fetch = prefs.getStringSet("List", null);

    //I then convert it to an Array List and try to see if I got the values 
    List<String> list = new ArrayList<String>(fetch);

    for(int i = 0 ; i < list.size() ; i++){
        Log.d("fetching values", "fetch value " + list.get(i));
    }

However, it turns out that the Set<String> fetch was null and I'm having a null pointer exception and it's probably because I wasn't storing or fetching my StringSet properly.

halfer
  • 19,824
  • 17
  • 99
  • 186
Razgriz
  • 7,179
  • 17
  • 78
  • 150

2 Answers2

16

Create an editor Object first :

SharedPreferences.Editor editor = prefs.edit();

And use the editor object to store and fetch your string set like this :

editor.putStringSet("List", set);
editor.apply();

Set<String> fetch = editor.getStringSet("List", null);
A Honey Bustard
  • 3,433
  • 2
  • 22
  • 38
  • Of course this is easier than my answer if you're building for API 11 or higher :) – Bill Mote Mar 22 '15 at 14:04
  • Okay will try this solution since I'm building for API 11++. What's the difference between apply and commit? – Razgriz Mar 22 '15 at 16:30
  • 1
    Okay this works. But I do have a question though. After adding test , test 2, and test 3, I fetch them again. However, upon fetching, it seems that the order was wrong. I know I can fix this by sorting after fetching, but is there a way to ensure that writing to a set gets executed in order? thanks! – Razgriz Mar 22 '15 at 16:46
  • 1
    Im on my mobile right know but but I'd guess theres a method like 'set.add(0, "test 1");' set.add(1, "test 2"); etc with a key for each value – A Honey Bustard Mar 22 '15 at 17:48
  • Difference between apply and commit :http://stackoverflow.com/questions/5960678/whats-the-difference-between-commit-and-apply-in-shared-preference – A Honey Bustard Mar 22 '15 at 17:53
  • Probably the order is wrong because `HashSet` doesn't preserve order. If you use `LinkedHashSet` it may work. – nasch Mar 23 '15 at 14:27
  • One should observe that hir should not modify the returned Set. One could create a new object of the returned object in order to modify it and apply it to the preferences again. https://developer.android.com/reference/android/content/SharedPreferences.html#getStringSet(java.lang.String,%20java.util.Set%3Cjava.lang.String%3E) – Atte Backenhof Jul 11 '18 at 06:26
  • @Denny because he did not create the Object : SharedPreferences.Editor editor = prefs.edit(); – A Honey Bustard Jan 05 '19 at 09:23
  • @Denny When the Object does not exist, there is nowhere to put something... – A Honey Bustard Jan 05 '19 at 15:24
  • I still don't see what's different between assigning to a variable first or using it directly without variable assignment. `SharedPreferences.Editor editor = prefs.edit(); editor.put();` shouldn't be different from `prefs.edit().put()` – Denny Jan 05 '19 at 18:54
2

You could write your results to a JSON String and store them in Shared Preferences like this: https://stackoverflow.com/a/5968562/617044

But if you choose to go down the route you're currently on then you're going to have to store a parcelable.

As noted in another answer; you can use putStringSet(), getStringSet() if you're building for API 11+.

Community
  • 1
  • 1
Bill Mote
  • 12,644
  • 7
  • 58
  • 82