问题
I'm trying to create an app which uses username and password to login, then stay logged in as long as user didn't logout -or didn't delete app data of course-, and as far as I know that SharedPreferences is the best to do so. How do I implement it correctly?
I've tried to create SharedPreferences object then Editor object to check at launching app if there are data stored for username and password, and if so then login automatically. Then for logging out, once is logout button is clicked, username and password keys are deleted from SharedPreferences. But I'm not sure, I guess I've done it in a wrong way so the app doesn't work.
Here is a simple example of what I want to make(assume all XML files and IDs are right because the app was working fine before adding SharedPreferences):
LoginActivity.java:
public class LoginActivity extends AppCompatActivity {
private Button button_login;
private EditText editText_username;
private EditText editText_password;
private SharedPreferences pref;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
perf = getApplicationContext().getSharedPreferences("user_pref", 0);
SharedPreferences.Editor editor = perf.edit();
if(!(sharedPref.getString("username", null)).isEmpty() && !(sharedPref.getString("password", null)).isEmpty()){
doLogin(sharedPref.getString("username", null), sharedPref.getString("password", null));
}
//define editText_username, editText_password and button_login
button_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!TextUtils.isEmpty(editText_username.getText()) && !TextUtils.isEmpty(editText_password.getText())){
doLogin(editText_username.getText().toString().trim(), editText_password.getText().toString().trim());
}
}
});
}
public void doLogin(String username, String password) {
Intent loginIntent = new Intent(LoginActivity.this, HomeActivity.class);
SharedPreferences.Editor editor = perf.edit();
editor.putString("username", username);
editor.putString("password", password);
startActivity(loginIntent);
finish();
}
}
HomeActivity.java:
public class HomeActivity extends AppCompatActivity {
private SharedPreferences perf;
private Button button_logout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
perf = getApplicationContext().getSharedPreferences("user_pref", 0);
//button_logout define
button_logout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = perf.edit();
editor.remove("username");
editor.remove("password");
Intent logoutIntent = new Intent(HomeActivity.this, LoginActivity.this);
startActivity(logoutIntent);
finish();
}
});
}
I don't get any results, it crashes. So I'm not sure if I did it correctly or not.
回答1:
create an AppPreference class :-
public class AppPrefrences {
private static SharedPreferences mPrefs;
private static SharedPreferences.Editor mPrefsEditor;
public static boolean isUserLoggedOut(Context ctx) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return mPrefs.getBoolean("id_logged_in", true);
}
public static void setUserLoggedOut(Context ctx, Boolean value) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
mPrefsEditor = mPrefs.edit();
mPrefsEditor.putBoolean("id_logged_in", value);
mPrefsEditor.commit();
}
public static String getUserName(Context ctx) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return mPrefs.getString("name", "");
}
public static void setUserName(Context ctx, String value) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
mPrefsEditor = mPrefs.edit();
mPrefsEditor.putString("name", value);
mPrefsEditor.commit();
}
}
and now set details in AppPreference Class:-
AppPreference.setUserLoggedOut(this, false);
AppPreference.setUserName(this, "pass username here");
and get username like this:-
AppPreference.getUserName(this);
or check user is logged or not on splash screen :-
if (isUserLoggedOut(StartActivity.this)) {
//user not logged in
} else {
//User is logged in
}
回答2:
You have to commit or apply changes made in editor. So after
editor.putString("username", username);
editor.putString("password", password);
editor.apply(); // or editor.commit()
回答3:
What you have done is the right, the only thing is you have not committed your preference values.
So your function will look like this
public void doLogin(String username, String password) {
Intent loginIntent = new Intent(LoginActivity.this, HomeActivity.class);
SharedPreferences.Editor editor = perf.edit();
editor.putString("username", username);
editor.putString("password", password);
editor.apply(); //This line will make necessary changes in SharedPreferences file
startActivity(loginIntent);
finish();
}
add the same line on button_logout
click
Moreover, I will recommend you to create a utility class for SharedPreference operations.
回答4:
Make it simple using PowerPreference
so you can store the User as an Object
Create a User
class
class User{
String userName;
String password;
}
When user clicks on the login button:
String userName = editText_username.getText().toString().trim();
String password = editText_username.getText().toString().trim();
doLogin(new User(userName,password);
Then using PowerPreference
you can store the user object in shared preference
public void doLogin(User user) {
PowerPreference.getDefaultFile().putObject("key",user);
Intent loginIntent = new Intent(LoginActivity.this, HomeActivity.class);
startActivity(loginIntent);
finish();
}
Next time the user enters login screen onCreate() use
User user = PowerPreference.getDefaultFile().getObject("key",User.class)
if (user!=null){
doLogin(user.userName,user.password)
}
To be able using PowerPreference
add this to you gradle
implementation 'com.aliassadi:power-preference-lib:1.4.1'
来源:https://stackoverflow.com/questions/55792257/how-to-control-storing-user-data-using-sharedpreferences-when-logging-in-and-out