You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:10:57