Nxt3
Nxt3

Reputation: 2071

Using data between activities with SharedPrefs helper

I have a class called SessionManager that is supposed to handle logged in sessions using SharedPrefs. It works for the most part. I'm running into an issue where if I logged out (nothing in SharedPrefs) then logged back in--then the data is null. However, it isn't null on the Login activity--but the moment I leave the Login activity to go to the Main activity, that's when it is then null. Obviously, there is an issue with using the SharedPrefs between activities--but I'm not sure I understand why/how.

Another thing--if I close the app and then open it again--the SharedPref data is correct in the Main Activity (since we start here after we've logged in once). The issue I'm describing above only happens on the initial login.

For the sake of brevity, I've removed the getter methods as they aren't the issue.

public class SessionManager {

    Context context;
    SharedPreferences pref;
    //Editor for Shared preferences
    SharedPreferences.Editor editor;

    //SharedPref file name
    private static final String PREF_NAME = "current.user";

    //All Shared Preferences Keys
    private static final String IS_LOGIN = "IsLoggedIn";

    //Username
    public static final String KEY_USERNAME = "username";

    //Name
    public static final String KEY_NAME = "name";

    //Email
    public static final String KEY_EMAIL = "email";

    //Constructor for SessionManager
    public SessionManager(Context context) {
        this.context = context;
        pref = this.context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        editor = pref.edit();
    }

    /**
     * Create login session
     * @param username to store in SharedPrefs
     * @param email to store in SharedPrefs
     */
    public void createLoginSession(String username, String name, String email) {
        /*Store each value into SharedPrefs*/
        editor.putBoolean(IS_LOGIN, true);
        editor.putString(KEY_USERNAME, username);
        editor.putString(KEY_NAME, name);
        editor.putString(KEY_EMAIL, email);

        //Commit changes to SharedPrefs
        editor.commit();
    }
}

I am calling the above in whatever Activity by doing this:

SessionManager mSession;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_welcome);
    ButterKnife.bind(this);

    mSession = new SessionManager(getApplicationContext());
}

I do the above for every activity.

What am I doing wrong?

Edit: Here is how I am accessing it and setting the values

Accessing it on LoginActivity:

// Create a session with values from Firebase--logging shows me these values are correct
mSession.createLoginSession(USERNAME, NAME, EMAIL);

HashMap<String, String> user = mSession.getUserDetails();
String name = user.get(SessionManager.KEY_NAME);
String username = user.get(SessionManager.KEY_USERNAME);
String email = user.get(SessionManager.KEY_EMAIL);
// Logging shows me that the name, username, and email are set properly

Then using that data to set the title in a navdrawer in MainActivity:

mSession = new SessionManager(getApplicationContext());

HashMap<String, String> user = mSession.getUserDetails();
String namey = user.get(SessionManager.KEY_NAME);
String emaily = user.get(SessionManager.KEY_EMAIL);
String usernamey = user.get(SessionManager.KEY_USERNAME);

Upvotes: 0

Views: 93

Answers (2)

OneCricketeer
OneCricketeer

Reputation: 191758

I would strongly consider using a singleton pattern here. That way you are guaranteed to use the same instance across multiple classes.

Not sure why this seems to be the go-to implementation of session management.

Example usage

public class MainActivity extends AppCompatActivity {

    private SessionManager mSessionManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.mSessionManager = SessionManager.getInstance(getApplicationContext());

        mSessionManager.createLoginSession("tester", "Joe", "[email protected]");
        boolean isLoggedIn = mSessionManager.getPref().getBoolean(SessionManager.IS_LOGIN, false);
        Log.d("MyTag", String.valueOf(isLoggedIn)); // true

        mSessionManager.logout();
        isLoggedIn = mSessionManager.getPref().getBoolean(SessionManager.IS_LOGIN, false);
        Log.d("MyTag", String.valueOf(isLoggedIn)); // false
    }

}

SessionManager class

public class SessionManager {

    private static SessionManager sInstance;

    private final SharedPreferences pref;
    private final SharedPreferences.Editor editor;

    public static final String PREF_NAME = "current.user";

    public static final String IS_LOGIN = "IsLoggedIn";
    public static final String KEY_USERNAME = "username";
    public static final String KEY_NAME = "name";
    public static final String KEY_EMAIL = "email";

    public static SessionManager getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new SessionManager(context);
        }
        return sInstance;
    }

    private SessionManager(Context context) {
        pref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        editor = pref.edit();
    }

    public void createLoginSession(String username, String name, String email) {
        editor.putBoolean(IS_LOGIN, true);
        editor.putString(KEY_USERNAME, username);
        editor.putString(KEY_NAME, name);
        editor.putString(KEY_EMAIL, email);

        editor.commit();
    }

    public void logout() {
        editor.clear();
        editor.putBoolean(IS_LOGIN, false);
        editor.commit();
    }

    public String getLoggedInUsername() {
        String username = null;
        if (pref.contains(KEY_USERNAME) && pref.getBoolean(IS_LOGIN, false)) {
            username = pref.getString(KEY_USERNAME, null);
        }
        return username;
    }

    public SharedPreferences getPref() {
        return pref;
    }
}

Upvotes: 1

Marcin Orlowski
Marcin Orlowski

Reputation: 75629

What am I doing wrong?

I guess you are using differnt context in other activities. You must use the same (getApplicagtionContext() is fine) everywhere, otherwise your SessionManager will be accessing different shared preference storage (XML files if you are curious :)

Upvotes: 1

Related Questions