Android应用如何实现用户连续登录streak统计及sync计数器功能?
Android 端连续登录 sync 计数器实现方案
核心存储设计
你需要在本地持久化存储2个字段,推荐使用 SharedPreferences 或 Jetpack DataStore 实现,无需额外权限:
- 上次登录的自然日标识:格式统一为
yyyy-MM-dd字符串,按用户本地时区生成,避免跨时区判定错误 - 当前 sync 连续登录天数:就是你需要的计数器变量
登录时的计算逻辑
每次用户登录成功后,按以下步骤计算 sync 值:
- 生成当前本地时区的当天日期字符串
currentDate - 读取本地存储的上次登录日期
lastLoginDate、旧的 sync 值oldSync - 分场景处理:
- 首次登录(
lastLoginDate为空):sync 赋值为 1,存储currentDate为新的上次登录日期 - 当日重复登录(
lastLoginDate等于currentDate):sync 值不做修改,无需更新存储 - 连续次日登录(
lastLoginDate刚好是当前日期的前一天):sync 赋值为oldSync + 1,更新上次登录日期为currentDate - 断签后登录(
lastLoginDate早于当前日期的前一天,即间隔1天及以上):sync 先重置为 0,再赋值为 1(本次登录为新连续周期的第一天),更新上次登录日期为currentDate
- 首次登录(
注意:如果业务要求断签后首次登录当天 sync 显示为 0,次日登录再变为1,只需要调整断签场景的赋值逻辑即可。
示例代码(Kotlin)
// 初始化SharedPreferences val sp = getSharedPreferences("login_streak", Context.MODE_PRIVATE) val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).apply { timeZone = TimeZone.getDefault() } // 登录成功后执行 fun calculateSyncAfterLogin() { val currentDate = sdf.format(Date()) val lastLoginDate = sp.getString("key_last_login_date", null) val oldSync = sp.getInt("key_sync", 0) val newSync = when { lastLoginDate == null -> 1 lastLoginDate == currentDate -> oldSync lastLoginDate == getYesterdayDate() -> oldSync + 1 else -> 1 // 断签后重置为0,本次登录为新周期第一天,赋值为1 } // 持久化更新 sp.edit() .putString("key_last_login_date", currentDate) .putInt("key_sync", newSync) .apply() } // 获取昨天的日期字符串 private fun getYesterdayDate(): String { val calendar = Calendar.getInstance() calendar.add(Calendar.DAY_OF_YEAR, -1) return sdf.format(calendar.time) }
优化建议
- 如果需要防止用户修改本地时间刷连续天数,可以把登录时间上传到服务端,由服务端按自然日计算 sync 值后返回给客户端存储
- 如果需要支持卸载重装后保留连续登录数据,需要把两个字段同步存储到服务端的用户账号属性中
内容的提问来源于stack exchange,提问作者Karmesh Duggar
相关产品推荐
相关产品推荐

