Android Kotlin实现用户10天自动登出并强制重新登录方案
实现每10天自动登出的登录会话管理方案
问题背景
现有Android Kotlin项目通过LoginPref.kt(基于SharedPreferences)实现登录会话管理,MainActivity作为登录页,登录成功后进入dashboard页面。当前用户登录后每次打开APP都会直接进入dashboard,缺少强制重新登录机制,需要实现每10天自动登出用户,强制回到登录页重新验证。
现有核心代码
LoginPref.kt
package com.example.sepehr1.Session import android.content.Context import android.content.Intent import android.content.SharedPreferences import com.example.sepehr1.MainActivity class LoginPref { lateinit var pref:SharedPreferences lateinit var editor:SharedPreferences.Editor lateinit var con: Context var PRIVATEMODE : Int = 0 constructor(con: Context){ this.con = con pref = con.getSharedPreferences(PREF_NAME, PRIVATEMODE) editor = pref.edit() } companion object{ val PREF_NAME = "Login_Preference" val IS_LOGIN = "isLoggedin" val KEY_PHONE = "phonenumber" val KEY_PASSWORD = "password" } fun createLoginSession(phoneNumber: String, password: String){ editor.putBoolean(IS_LOGIN, true) editor.putString(KEY_PHONE, phoneNumber) editor.putString(KEY_PASSWORD, password) editor.commit() } fun checkLogin(){ if(!this.isLoggedIn()){ var i : Intent = Intent(con, MainActivity::class.java) i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) con.startActivity(i) } } fun getUserDetails(): HashMap<String, String>{ var user: Map<String, String> = HashMap<String, String>() (user as HashMap).put(KEY_PHONE, pref.getString(KEY_PHONE, null)!!) (user as HashMap).put(KEY_PASSWORD, pref.getString(KEY_PASSWORD, null)!!) return user } fun LogoutUser(){ editor.clear() editor.commit() var i = Intent(con, MainActivity::class.java) i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) con.startActivity(i) } fun isLoggedIn(): Boolean{ return pref.getBoolean(IS_LOGIN, false) } }
MainActivity.kt(登录页)
class MainActivity : AppCompatActivity() { lateinit var session: LoginPref override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) session = LoginPref(this) var username = findViewById<EditText>(R.id.phoneNumber) var password = findViewById<EditText>(R.id.passwords) if(session.isLoggedIn()){ var i : Intent = Intent(applicationContext, dashboard::class.java) i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(i) finish() } signIn.setOnClickListener { var phone = username.text.toString().trim() var pass = password.text.toString().trim() if(phone.isEmpty() && pass.isEmpty()){ Toast.makeText(this,"Failed",Toast.LENGTH_SHORT).show() } else{ session.createLoginSession(phone, pass) var i : Intent = Intent(applicationContext, dashboard::class.java) startActivity(i) finish() } }
解决方案
通过记录登录时间戳、添加过期校验逻辑实现自动登出,具体修改如下:
1. 改造LoginPref.kt,添加会话过期逻辑
在原有代码基础上新增登录时间记录、过期检查逻辑:
package com.example.sepehr1.Session import android.content.Context import android.content.Intent import android.content.SharedPreferences import com.example.sepehr1.MainActivity class LoginPref { lateinit var pref:SharedPreferences lateinit var editor:SharedPreferences.Editor lateinit var con: Context var PRIVATEMODE : Int = 0 // 定义10天的毫秒数:10天*24小时*60分钟*60秒*1000毫秒 private val SESSION_EXPIRY_DURATION = 10 * 24 * 60 * 60 * 1000L constructor(con: Context){ this.con = con pref = con.getSharedPreferences(PREF_NAME, PRIVATEMODE) editor = pref.edit() } companion object{ val PREF_NAME = "Login_Preference" val IS_LOGIN = "isLoggedin" val KEY_PHONE = "phonenumber" val KEY_PASSWORD = "password" // 新增登录时间戳的key val KEY_LOGIN_TIMESTAMP = "login_timestamp" } fun createLoginSession(phoneNumber: String, password: String){ editor.putBoolean(IS_LOGIN, true) editor.putString(KEY_PHONE, phoneNumber) editor.putString(KEY_PASSWORD, password) // 记录当前登录的时间戳 editor.putLong(KEY_LOGIN_TIMESTAMP, System.currentTimeMillis()) editor.commit() } fun checkLogin(){ if(!this.isLoggedIn()){ val i = Intent(con, MainActivity::class.java) i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) con.startActivity(i) } } fun getUserDetails(): HashMap<String, String>{ val user = HashMap<String, String>() user.put(KEY_PHONE, pref.getString(KEY_PHONE, null)!!) user.put(KEY_PASSWORD, pref.getString(KEY_PASSWORD, null)!!) return user } fun logoutUser(){ editor.clear() editor.commit() val i = Intent(con, MainActivity::class.java) i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) con.startActivity(i) } // 检查会话是否过期 private fun isSessionExpired(): Boolean { val loginTimestamp = pref.getLong(KEY_LOGIN_TIMESTAMP, 0) if (loginTimestamp == 0L) return true // 无登录记录视为过期 // 计算当前时间与登录时间的差值 val currentTime = System.currentTimeMillis() return (currentTime - loginTimestamp) > SESSION_EXPIRY_DURATION } fun isLoggedIn(): Boolean{ val isLoggedin = pref.getBoolean(IS_LOGIN, false) if (isLoggedin && isSessionExpired()) { // 会话过期,自动登出 logoutUser() return false } return isLoggedin } }
关键修改点:
- 新增
KEY_LOGIN_TIMESTAMP用于存储登录时间戳 createLoginSession方法中添加当前时间戳记录- 新增
isSessionExpired方法,计算时间差判断是否超过10天 - 修改
isLoggedIn方法,若会话过期则自动调用登出,并返回false
2. 优化MainActivity.kt的跳转逻辑
原有逻辑无需大幅修改,isLoggedIn()已包含过期校验,若会话过期会自动跳转登录页。可调整Intent的Flags写法更简洁:
if(session.isLoggedIn()){ val i = Intent(applicationContext, dashboard::class.java) i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK startActivity(i) finish() }
3. 在Dashboard页面添加会话检查
为避免用户后台切回APP时会话已过期,在Dashboard的onResume方法中添加会话检查:
class dashboard : AppCompatActivity() { lateinit var session: LoginPref override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_dashboard) session = LoginPref(this) } override fun onResume() { super.onResume() // 每次回到前台都检查会话状态 session.checkLogin() } }
内容的提问来源于stack exchange,提问作者Amir Elahi
相关产品推荐
相关产品推荐

