Reputation: 2071
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
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
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