11

I'm developing an application in which I'm storing username and password in SharedPreferences. All things are working fine for me, storing as well as retrieving the values. But I discovered that when I restart the device or the app is force closed the value stored in SharedPreferences is reset. And when I again launch my app I get null values in SharedPreferences key. Here, is what I'm doing for storing the values:

SharedPreferences emailLoginSP;

emailLoginSP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
emailLoginSP.edit().putString("prefEmailId", email_text).commit();
emailLoginSP.edit().putString("prefUserId", userIDToken).commit();
emailLoginSP.edit().putString("prefAccess_token", accessToken).commit();

Intent i = new Intent(LoginWithEmail.this,UserInfoActivity.class);
i.putExtra("acess_token", accessToken);
i.putExtra("user_id", userIDToken);
i.putExtra("emailID", email_text);
startActivity(i);

And, this is how I'm retriving it:

SharedPreferences emailLoginSP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

loginEmail = emailLoginSP.getString("prefEmailId", null);
loginUserId = emailLoginSP.getString("prefUserId", null);
loginAccessToken = emailLoginSP.getString("prefAccess_token", null);

All things are working fine till now. Again I'm stating my problem that I get null values when I force close or restart my device. Can we store it permanently in the app memory? Or, I'm doing something wrong here?

Any help will be appreciated.

Anupam
  • 3,742
  • 18
  • 55
  • 87
  • Its not return `NULL` when you restart your device once value store in SP, seem you have any other issue. can tell us where you getting force close? – RobinHood Mar 12 '13 at 05:52
  • I'm not getting force close. I have forced stopped the app via settings->apps and forcestop it from there. When I do both either restart my phone or forcestop it my values becomes null then. – Anupam Mar 12 '13 at 06:03
  • @Anupam My solution below will retain values in Force stop, when you restart your device etc. `SharedPreferences` stores the values to XML so it doesn't matter how the app is destroyed they will always be retained http://stackoverflow.com/questions/6146106/where-are-shared-preferences-stored There must be something wrong with the store or retrieve code your using – wired00 Mar 12 '13 at 06:53
  • It turns out this can also be caused by invalid preference keys, such as keys containing newlines: http://stackoverflow.com/questions/28385132/sharedpreferences-in-android-not-persisted-to-disk-when-key-contains-newline – caw Feb 07 '15 at 17:28
  • Just looking at your code it seems you missed editor.commit() as that is going to put back the values to the shared preferences. This is mentioned in the android documentation. Interface used for modifying values in a SharedPreferences object. All changes you make in an editor are batched, and not copied back to the original SharedPreferences until you call commit() or apply() Link : https://developer.android.com/reference/android/content/SharedPreferences.Editor#apply() – skarfa May 20 '22 at 09:57

6 Answers6

10

I have a login screen and wanted the app to appear as if it's remained "logged in" at the internal screen after the app is closed/destroyed/phone call/etc.

I have a Preferences Object to save values following Login or Register. I read preference values in all the key screen onResume() methods.

After login (for example):

SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor editor = app_preferences.edit();
editor.putString("sessionId", application.currentSessionId);
editor.putString("userId", application.currentUserId);
editor.putString("userEmail", application.currentUserEmail);
editor.putString("siteUserId", application.currentSiteUserId);
editor.commit();

Within onResume() of Activities: (ie, within internal screens)

SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(activity);
application.currentSessionId = app_preferences.getString("sessionId", "");
application.currentUserId = app_preferences.getString("userId", "");
application.currentUserEmail = app_preferences.getString("userEmail", "");
application.currentSiteUserId = app_preferences.getString("siteUserId", "");

Note. I have application "global" variables, ie, application.currentSessionId, you can just substitute your variables

Try something similar maybe your not saving or retrieving the values correctly because SharePreferences should work

wired00
  • 13,930
  • 7
  • 70
  • 73
  • 3
    For future readers, SharedPreferences.Editor uses the Builder Pattern to build a commit transaction. editor.putString(k,v).putLong(k2,n).commit(); After commit() you should use a new Editor or call editor.clear() before reuse. – CodeShane Jul 10 '13 at 16:13
  • I am getting same problem. and my code is same as above you mentioned, only one difference is that u = URLDecoder.decode(u,"UTF-8"); u is the use's email id. because of this code am I getting same problem ? – Mohini Jul 02 '15 at 11:24
8

Hi ! Solution that worked for me!

Solution 1 Solution 2

Solution 1:

  SharedPreferences sharedPreferences = getSharedPreferences("namefile",               
    Context.MODE_PRIVATE);//store or retrieved file "namefile.xml".
    /*or 
   SharedPreferences sharedPreferences    
   =getActivity().getSharedPreferences("namefile", Context.MODE_PRIVATE); 
   (use Shared Preferences in Fragment)*/
   String getValueFromKey = sharedPreferences.getString("yourKey",new   
   String());
   //Log.d("printf:",getValueFromKey );
   getValueFromKey ="Hahaha"; /*  Edit value    
   or Do nothing …… */
   SharedPreferences.Editor editor = sharedPreferences.edit();
   editor.clear(); //[important] Clearing your editor before using it.
   editor.putString("yourKey", getValueFromKey);
   editor.commit();

Solution 2:

SharedPreferences sharedPreferences = getSharedPreferences("namefile",     
  Context.MODE_PRIVATE);//store or retrieved file "namefile.xml".
/*or 
SharedPreferences sharedPreferences = 
getActivity().getSharedPreferences("namefile", Context.MODE_PRIVATE); 
(use Shared Preferences in Fragment)
*/
Set<String> getListValueFromKey =
sharedPreferences.getStringSet("yourKey",new HashSet<String>());
getListValueFromKey.add("Hahaha");
getListValueFromKey.add("Kakaka");
getListValueFromKey.add("Hohoho");
/*  Add value or Do nothing …… */
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.clear(); //[important] Clearing your editor before using it.
editor.putStringSet("yourKey", getListValueFromKey);
editor.commit();

I have had exactly same problem like yours and this worked for me. For my whole code sample see

  • 1
    The code in Solution 2 is bad; you're not allowed to modify and re-save the value obtained from `getStringSet`. Set [the documentation](https://developer.android.com/reference/android/content/SharedPreferences.html#getStringSet%28java.lang.String,%20java.util.Set%3Cjava.lang.String%3E%29). – Sam Oct 15 '17 at 05:13
1

Change to:

SharedPreferences emailLoginSP;
SharedPreferences.Editor SPEdit;

emailLoginSP = getSharedPreferences("pref_file_name",MODE_PRIVATE);
SPEdit = emailLoginSP.edit();

SPEdit.putString("prefEmailId", email_text);
SPEdit.putString("prefUserId", userIDToken);
SPEdit.putString("prefAccess_token", accessToken);
SPEdit.commit();

NOTE: This is untested and from memory, so there may be an error.

You want to minimise the .commit() calls, which is why there is only one at the end.

pref_file_name can be whatever you want, with lower case letters, no numbers at start, etc.

Tigger
  • 8,980
  • 5
  • 36
  • 40
0

Make sure that you are using the same file to save and retrieve. This made me look really dumb :(

// When saving
public SharedPreferences.Editor getEditor(Activity activity, int mode) {
    SharedPreferences sharedPref = activity.getApplicationContext().getSharedPreferences(PreferenceConstants.SWAGGER_USER_PREFS, mode);
    SharedPreferences.Editor editor = sharedPref.edit();
    return editor;
}


// When getting it
    public SharedPreferences getSharedPref(Activity activity, int mode) {
            SharedPreferences sharedPref = activity.getSharedPreferences(PreferenceConstants.SWAGGER_USER_PREFS, mode);
            return sharedPref;
        }
Elawry kip
  • 11
  • 4
-1

See I have done like below.

        sharedPreferences = PreferenceManager
                .getDefaultSharedPreferences(getApplicationContext());
        editor = sharedPreferences.edit();
        isPaidVerison = sharedPreferences.getInt("isPaidVerison", 0);


        editor.putInt("isPaidVerison", 1);
        editor.commit();

And this works fine. Data will remain in Sharedprefrences till will do not reinstall the app or till will d'not clear data.

And I retrive data this way.

       isPaidVerison = sharedPreferences.getInt("isPaidVerison", 0);
Nirali
  • 13,571
  • 6
  • 40
  • 53
-2

If you want to try an approach other than shared preferences then you can use a file to write the values and then retrieve the values from it. Declare a text file emailLogin.txt and use it as follows to write the data.

           try {
                Context context = MainActivity.this;
                OutputStreamWriter out=
                        new OutputStreamWriter(context.openFileOutput(EMAILLOGIN, 0));

                out.write(email_text);                   
                out.write("\r\n");
                out.write(userIDToken);                   
                out.write("\r\n");
                out.write(accessToken);                   
                out.write("\r\n");

                out.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 

After writing to the file, you can do the following to read from it.

   File file = this.getFileStreamPath(EMAILLOGIN);

            if(file.exists())
            {
                try {
                    InputStream in=openFileInput(NUMBERS);

                    if (in!=null) {
                        InputStreamReader tmp=new InputStreamReader(in);
                        BufferedReader reader=new BufferedReader(tmp);
                        String str;
                        String strcount[]= new String[20];                                                        

                        java.util.Arrays.fill(strcount, 0, 10, "");
                        while ((str = reader.readLine()) != null) {                       
                            strcount[linecount]=str;                              
                        }

                        loginEmail = strcount[0];
                        loginUserId = strcount[1];
                        loginAccessToken = strcount[2];

                        in.close();              
                    }
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

This will ensure that even when your app force closes or if your device reboots, you can still read the required values from the file.

user1721904
  • 843
  • 4
  • 13
  • 1
    This is NOT a good solution because `SharePreferences` is already stored to a file, it is stored in XML for you. Even after a 'reboot' as you say it will retain values. This is almost worth voting down. read here: http://stackoverflow.com/questions/6146106/where-are-shared-preferences-stored. I suggest in your own project user1721904 that you implement `SharedPreferences` as your re-inventing the wheel. Hope that helps mate – wired00 Mar 12 '13 at 06:41
  • 1
    LOL .. Just because you wanted your answer to be selected doesn't mean that you should comment like this on someone else's answer .. BTW I have mentioned at the start of my answer that he can try this if he wants to use a different approach and I didn't discourage him from using SharedPreferences .. – user1721904 Mar 12 '13 at 07:11
  • 1
    Nice BM. If your answer is wrong I'm going to tell you. Its for your own good, but ignore if you want doesn't worry me either way – wired00 Mar 12 '13 at 07:51