【问题标题】:Android: Keep username in session until logoutAndroid:将用户名保持在会话中,直到注销
【发布时间】:2011-09-01 00:29:40
【问题描述】:

我很难弄清楚如何使用 SharedPreferences 将用户名存储在手机中并保持会话直到注销。我还需要知道它在会话中如何将用户名与用户在列表视图中单击的数据一起发送出去。以下是我正在使用的代码,并且想知道为了实现这一目标而放置的位置和代码。登录时它会进入菜单并停留在菜单上(避免返回按钮返回登录屏幕)每个菜单都有一个注销项,它将返回登录屏幕。

我之前看过的问题是thisthis

Logcat 详细信息

05-26 10:42:19.146: WARN/KeyCharacterMap(26071): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
05-26 10:42:23.926: DEBUG/AndroidRuntime(26071): Shutting down VM
05-26 10:42:23.926: WARN/dalvikvm(26071): threadid=3: thread exiting with uncaught exception (group=0x40013140)
05-26 10:42:23.926: ERROR/AndroidRuntime(26071): Uncaught handler: thread main exiting due to uncaught exception
05-26 10:42:23.936: ERROR/AndroidRuntime(26071): java.lang.NullPointerException
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at com.merrill2.Login$1.onClick(Login.java:42)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.view.View.performClick(View.java:2232)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.view.View.onTouchEvent(View.java:3905)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.widget.TextView.onTouchEvent(TextView.java:6414)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.view.View.dispatchTouchEvent(View.java:3421)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1707)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1197)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.app.Activity.dispatchTouchEvent(Activity.java:1993)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1691)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1533)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.os.Looper.loop(Looper.java:123)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at android.app.ActivityThread.main(ActivityThread.java:3992)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at java.lang.reflect.Method.invokeNative(Native Method)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at java.lang.reflect.Method.invoke(Method.java:521)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
05-26 10:42:23.936: ERROR/AndroidRuntime(26071):     at dalvik.system.NativeStart.main(Native Method)
05-26 10:42:23.946: INFO/Process(899): Sending signal. PID: 26071 SIG: 3
05-26 10:42:23.956: INFO/dalvikvm(26071): threadid=7: reacting to signal 3
05-26 10:42:23.966: INFO/dalvikvm(26071): Wrote stack trace to '/data/anr/traces.txt'
05-26 10:42:25.646: DEBUG/dalvikvm(25722): GC freed 973 objects / 63040 bytes in 93ms
05-26 10:42:27.777: DEBUG/DispatchService(945): Handled message = TIMED_SERVICE_UNMASK
05-26 10:42:29.856: DEBUG/DispatchService(945): DISPATCH SERVICE getIdenPacketDataState: returning: 4
05-26 10:42:29.876: INFO/iDENWAPReceiver(953): Received a android.intent.action.ANY_DATA_STATE

登录.java

public class Login extends Activity {
    protected static final SharedPreferences settings = null;
    private EditText etUsername;
    private Button btnLogin;
    private Button btnCancel;
    private TextView lblResult;
    /** Called when the activity is first created. */
    //@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);

        etUsername = (EditText)findViewById(R.id.username);
        btnLogin = (Button)findViewById(R.id.login_button);
        btnCancel = (Button)findViewById(R.id.cancel_button);
        lblResult = (TextView)findViewById(R.id.result);

        btnLogin.setOnClickListener(new OnClickListener() {
            //@Override
            public void onClick(View v) {
            // Check Login
            String username = etUsername.getText().toString();

            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
            SharedPreferences.Editor editor = settings.edit();
            editor.putString("username", username);

            if(username.equals("1111")){
                lblResult.setText("Login successful.");

                //startActivity(new Intent(this, Activity2.class));


                Intent i = new Intent(getApplicationContext(), Customer.class);
                startActivity(i);

如果我取出下面的行:

protected static final SharedPreferences settings = null;

我把这个:

btnLogin.setOnClickListener(new OnClickListener() {
            private SharedPreferences settings;

'settings' 给出错误,所以我不得不使用上面提到的那些行之一

【问题讨论】:

    标签: android session android-activity sharedpreferences


    【解决方案1】:

    添加用户只需:

    import android.preference.PreferenceManager;
    ....
    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    SharedPreferences.Editor editor = settings.edit();
    editor.putString("username", username);
    

    然后在注销中删除它:

    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    SharedPreferences.Editor editor = settings.edit();
    editor.remove("username");
    

    这样可以确保用户只持续一个会话,直到它注销。当你打开你的应用程序时,你应该检查一下(以防万一),如果发生错误,看看是否已经在之前的会话中设置了用户名。

    至于在 ListView 中传递数据,您必须手动完成。 SharedPreference 框架负责处理其他所有事情。

    【讨论】:

    • 我可以获取一个样本来获取该用户名以与数据一起发送吗?我将 SharedPreferences 放在代码中的确切位置?
    • 我更新了上面的代码。首先我得到 getDefaultSharePreferences 错误,修复选项是 getPreferences(),另一个是修复选项是创建方法 'getDefaultSharePreferences(context)。另一个错误是创建用户名字段或更改为 etUsername 的用户名(不带引号的第二个用户名),但如果我更改为 etUsername,则新错误是 putString 并且必须创建私有字符串 etUsername 但它会与 EditText etUsername 冲突.从那里怎么走?
    • 顺便说一句,一旦登录,用户可以“返回”到登录屏幕吗?我想避免登录屏幕(一旦登录)整个会话直到注销。
    • 刚刚更新了我的答案,为了让它工作,你需要导入 PreferenceManager,它有方法 getDefault... 这将是正确的方法。您在这里又提出了两个问题……至于用户名,将数据作为 etUsername.getText().toString() 传递,首先检查不为空。至于用户无法返回登录屏幕,有几种方法可以做到这一点,首先尝试在 Manifest 中设置活动 no_history="true" (您也可以在加载后完成()活动下一个屏幕)。
    • 对不起,我应该更清楚我的最后评论。这些错误是在我导入之后。随着您添加的更新答案,工作设置是一个新错误(修复选项是为“设置”创建字段(或等)或更改为“设置”(android.provider))......你能给我更多关于用户名我还是听不懂你说的。
    【解决方案2】:

    我认为这个例子应该很有帮助。

    http://www.androidhive.info/2012/08/android-session-management-using-shared-preferences/

    主类在这里:

    public class SessionManager {
        // Shared Preferences
        SharedPreferences pref;
    
        // Editor for Shared preferences
        Editor editor;
    
        // Context
        Context _context;
    
        // Shared pref mode
        int PRIVATE_MODE = 0;
    
        // Sharedpref file name
        private static final String PREF_NAME = "AndroidHivePref";
    
        // All Shared Preferences Keys
        private static final String IS_LOGIN = "IsLoggedIn";
    
        // User name (make variable public to access from outside)
        public static final String KEY_NAME = "name";
    
        // Email address (make variable public to access from outside)
        public static final String KEY_EMAIL = "email";
    
        // Constructor
        public SessionManager(Context context){
            this._context = context;
            pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
            editor = pref.edit();
        }
    
        /**
         * Create login session
         * */
        public void createLoginSession(String name, String email){
            // Storing login value as TRUE
            editor.putBoolean(IS_LOGIN, true);
    
            // Storing name in pref
            editor.putString(KEY_NAME, name);
    
            // Storing email in pref
            editor.putString(KEY_EMAIL, email);
    
            // commit changes
            editor.commit();
        }   
    
        /**
         * Check login method wil check user login status
         * If false it will redirect user to login page
         * Else won't do anything
         * */
        public void checkLogin(){
            // Check login status
            if(!this.isLoggedIn()){
                // user is not logged in redirect him to Login Activity
                Intent i = new Intent(_context, LoginActivity.class);
                // Closing all the Activities
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    
                // Add new Flag to start new Activity
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
                // Staring Login Activity
                _context.startActivity(i);
            }
    
        }
    
    
    
        /**
         * Get stored session data
         * */
        public HashMap<String, String> getUserDetails(){
            HashMap<String, String> user = new HashMap<String, String>();
            // user name
            user.put(KEY_NAME, pref.getString(KEY_NAME, null));
    
            // user email id
            user.put(KEY_EMAIL, pref.getString(KEY_EMAIL, null));
    
            // return user
            return user;
        }
    
        /**
         * Clear session details
         * */
        public void logoutUser(){
            // Clearing all data from Shared Preferences
            editor.clear();
            editor.commit();
    
            // After logout redirect user to Loing Activity
            Intent i = new Intent(_context, LoginActivity.class);
            // Closing all the Activities
            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    
            // Add new Flag to start new Activity
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
            // Staring Login Activity
            _context.startActivity(i);
        }
    
        /**
         * Quick check for login
         * **/
        // Get Login State
        public boolean isLoggedIn(){
            return pref.getBoolean(IS_LOGIN, false);
        }
    }
    

    【讨论】:

    • 这是一个非常好的例子……非常非常……它非常结构化、可重复使用且易于理解
    【解决方案3】:

    当用户登录成功后,将用户的username添加到您的应用程序的SharedPreference中。

    SharedPreferences settings = getSharedPreferences("MyPrefsFile", 0);
    SharedPreferences.Editor editor = settings.edit();
    editor.putString("username", username);
    

    每次用户打开应用时,检查是否设置了“userID”首选项。如果是,则他已登录。否则显示登录屏幕。当用户注销时,从共享首选项中删除“用户名”条目。

    我还需要知道它在会话中如何将用户名与用户在列表视图中单击的数据一起发送出去

    您将可以通过该共享首选项访问用户 ID,以便您可以在需要时使用它。 Android 框架不会为您执行此操作,但您可以轻松完成。

    【讨论】:

    • 我可以获取一个样本来获取该用户名以与数据一起发送吗?我将 SharedPreferences 放在代码中的确切位置?
    • SharedPreferences settings = getSharedPreferences("MyPrefsFile", 0); String username = settings.getString("username", null); 我无法告诉您如何将该信息传达给您的服务器,因为我对您使用的协议和架构一无所知。您可以将该代码放在需要访问用户名的任何位置。
    • 我有 http 的代码并且已经成功发送数据到服务器。我试图弄清楚如何获取该用户名信息以与数据一起使用。至于sharedpref,它能否让用户在整个会话期间远离登录屏幕,除非注销?
    • 您可以使用它来查看是否有人登录:如果settings.getString("username", null); 返回null 则该用户未登录。如果您使用URI/URLs 传递数据,只需抛出一些东西喜欢"site.com/path?user="+username
    • 我更新了上面的代码。首先我得到 getDefaultSharePreferences 错误,修复选项是 getPreferences(),另一个是修复选项是创建方法 'getDefaultSharePreferences(context)。另一个错误是创建用户名字段或更改为 etUsername 的用户名(不带引号的第二个用户名),但如果我更改为 etUsername,则新错误是 putString 并且必须创建私有字符串 etUsername 但它会与 EditText etUsername 冲突.从那里怎么走?
    【解决方案4】:

    要存储在存储的首选项中,请使用此

     SharedPreferences.Editor editor = getSharedPreferences("DeviceToken",MODE_PRIVATE).edit();
                            editor.putString("DeviceToken","ABABABABABABABB12345");
    editor.apply();
    

    用于检索相同用途

        SharedPreferences prefs = getSharedPreferences("DeviceToken", 
     MODE_PRIVATE);
        String deviceToken = prefs.getString("DeviceToken", null);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-13
      • 2011-08-28
      • 2012-12-09
      • 2018-03-03
      • 1970-01-01
      • 2017-04-07
      • 1970-01-01
      • 2017-11-20
      相关资源
      最近更新 更多