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

如何在Ionic 3中开发应用使用时长限制功能并防卸载重装?

实现3小时试用+防卸载重装的最佳方案

嘿,这个需求我之前帮朋友做过类似的,咱们一步步拆解清楚:

一、基础超时功能的实现(无防卸载)

如果只是做最基础的3小时试用,逻辑很简单:

  • 首次启动App时,记录首次使用时间戳,存在SharedPreferences或本地数据库里
  • 每次启动App时,读取这个时间戳,和当前时间做差值对比
  • 如果时间差超过3小时(10800秒),就触发限制使用的逻辑

代码示例(Kotlin):

// 首次启动时记录时间
val sharedPref = getSharedPreferences("TrialPrefs", Context.MODE_PRIVATE)
if (!sharedPref.contains("firstLaunchTime")) {
    sharedPref.edit().putLong("firstLaunchTime", System.currentTimeMillis()).apply()
}

// 每次启动检查超时
val firstLaunch = sharedPref.getLong("firstLaunchTime", 0)
val currentTime = System.currentTimeMillis()
val timeDiff = currentTime - firstLaunch
if (timeDiff > 3 * 60 * 60 * 1000) {
    // 超时,跳转至限制页面
    startActivity(Intent(this, TrialExpiredActivity::class.java))
    finish()
}

但这个方案有个致命漏洞:用户卸载重装App后,SharedPreferences会被完全清空,相当于重新获得3小时试用,轻松绕开限制。

二、防卸载重装的核心思路:找卸载后不消失的存储点

Android系统中,App卸载时会清除自身所有私有存储(包括SharedPreferences、内部数据库、私有文件),所以我们需要找系统级的、App卸载后仍能保留的存储位置,或结合后端验证。这里给你几个可行方案:

1. 服务器验证(最可靠,业界通用)

这是最稳妥的方案,完全从根源上避免卸载重装绕过:

  • 首次启动时,获取设备的稳定唯一标识(比如OAID,比Android ID兼容性更强;或者IMEI,但需要READ_PHONE_STATE权限,Android 10+限制更严)
  • 将设备标识和首次使用时间发送到你的后端服务器,存储在数据库中
  • 每次启动App时,向服务器发送设备标识,由服务器对比首次时间判断是否超时
  • 卸载重装后,App读取设备标识再次请求服务器,服务器会返回已超时的结果

优势:完全无法通过卸载重装绕过,还能避免用户篡改本地时间(用服务器时间做对比)。
注意:可以给每个设备标识设置一次试用机会,同时处理设备重置、用户更换设备的特殊场景。

2. 利用系统账户(AccountManager)

Android的AccountManager允许App创建系统级账户,卸载App后账户不会自动删除:

  • 首次启动时,创建一个自定义账户,把首次使用时间存在账户的额外数据里
  • 重装App后,检查是否存在这个账户,读取里面的时间戳进行验证

代码示例(Kotlin):

// 创建账户
val accountManager = getSystemService(Context.ACCOUNT_SERVICE) as AccountManager
val account = Account("TrialAccount", "com.your.app.trial.type")
if (accountManager.addAccountExplicitly(account, null, bundleOf("firstLaunchTime" to System.currentTimeMillis()))) {
    // 账户创建成功
}

// 重装后读取账户
val accounts = accountManager.getAccountsByType("com.your.app.trial.type")
if (accounts.isNotEmpty()) {
    val firstLaunch = accountManager.getUserData(accounts[0], "firstLaunchTime")?.toLong() ?: 0
    // 超时检查逻辑和之前一致
}

注意:需要添加GET_ACCOUNTS权限,而且用户可以手动在系统设置里删除这个账户,不过门槛比卸载重装高很多。

3. 外部存储隐藏文件(兼容性稍差)

在外部存储创建一个隐藏文件(文件名开头加.),写入首次使用时间和设备标识:

  • 但Android 10+的Scoped Storage限制,App只能访问自己的私有外部目录,卸载后这个目录会被删除,所以得用MediaStore的公共目录(比如Download),但用户可能会发现并删除这个文件,可靠性不如前两种方案。

三、关于Android全局变量的疑问

直接说结论:全局变量完全无法解决这个问题。
因为App的全局变量(比如Application类里的静态变量)只存在于App进程的生命周期中,进程被杀就会消失,卸载App后更是彻底清除,根本无法保留任何跨卸载的信息。

额外注意事项

  • 防止篡改本地时间:不要只用本地时间做对比,最好每次检查时请求服务器的当前时间,避免用户手动修改系统时间绕过限制
  • 权限处理:涉及设备标识、账户、外部存储的方案,都需要注意Android不同版本的权限要求,提前做好权限申请和异常处理

内容的提问来源于stack exchange,提问作者Ronald Araújo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:30:58