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

如何在用户闲置X时长后锁定账户?附CountDownTimer实现疑问

Android 闲置时长触发操作(锁定账户/显示指定Activity)

针对你提到的两个需求,我来帮你梳理下正确的实现思路,先解决你当前代码里的问题,再给出完整可行的方案:

首先要指出你代码里的一个关键错误:BaseActivity baseActivity = new BaseActivity(); —— Android里绝对不能直接new一个Activity实例,Activity的启动必须通过Intent结合上下文来完成,直接实例化会导致各种生命周期异常。

一、基础实现:基于BaseActivity的闲置监听

如果你的所有页面都需要监听闲置状态,最简洁的方式是封装一个BaseActivity,让其他页面继承它,核心逻辑如下:

public class BaseActivity extends AppCompatActivity {
    private CountDownTimer inactivityTimer;
    // 自定义闲置时长,比如5分钟=300000毫秒
    private static final long INACTIVITY_TIMEOUT = 300000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initInactivityTimer();
    }

    // 初始化/重置闲置计时器
    private void initInactivityTimer() {
        if (inactivityTimer != null) {
            inactivityTimer.cancel();
        }
        inactivityTimer = new CountDownTimer(INACTIVITY_TIMEOUT, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                // 可选:这里可以添加倒计时提示(比如状态栏显示剩余时间)
            }

            @Override
            public void onFinish() {
                // 闲置时间到,执行锁定账户+启动指定页面逻辑
                handleInactiveState();
            }
        };
        inactivityTimer.start();
    }

    // 用户有交互(触摸、按键等)时重置计时器
    @Override
    public void onUserInteraction() {
        super.onUserInteraction();
        initInactivityTimer();
    }

    // 处理闲置状态的核心逻辑
    private void handleInactiveState() {
        // 1. 锁定账户:清除用户登录状态、缓存、Token等
        clearUserSession();

        // 2. 启动指定的锁定/登录页面
        Intent lockIntent = new Intent(this, LockScreenActivity.class);
        // 设置Flag避免栈混乱,清空当前页面栈,直接跳转到锁定页
        lockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(lockIntent);
        finish();
    }

    // 示例:清除用户会话信息
    private void clearUserSession() {
        SharedPreferences sp = getSharedPreferences("user_info", MODE_PRIVATE);
        sp.edit().clear().apply();
        // 额外:清除内存中的用户对象、取消网络请求等
    }

    // 页面销毁时及时取消计时器,避免内存泄漏
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (inactivityTimer != null) {
            inactivityTimer.cancel();
            inactivityTimer = null;
        }
    }
}

二、进阶优化:全局监听App前后台状态

上面的基础实现只在页面前台时生效,如果需要监听App在前台的所有状态(包括切换页面时的闲置),可以结合Application的生命周期回调,实现全局闲置监听:

public class MyApp extends Application {
    private CountDownTimer globalInactivityTimer;
    private static final long INACTIVITY_TIMEOUT = 300000;
    private boolean isAppForeground = false;

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {}

            @Override
            public void onActivityStarted(@NonNull Activity activity) {
                isAppForeground = true;
                // App回到前台,重启计时器
                restartGlobalTimer();
            }

            @Override
            public void onActivityResumed(@NonNull Activity activity) {}

            @Override
            public void onActivityPaused(@NonNull Activity activity) {}

            @Override
            public void onActivityStopped(@NonNull Activity activity) {
                isAppForeground = false;
                // App进入后台,暂停计时器
                if (globalInactivityTimer != null) {
                    globalInactivityTimer.cancel();
                }
            }

            @Override
            public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {}

            @Override
            public void onActivityDestroyed(@NonNull Activity activity) {}
        });
    }

    // 重置全局计时器
    private void restartGlobalTimer() {
        if (globalInactivityTimer != null) {
            globalInactivityTimer.cancel();
        }
        globalInactivityTimer = new CountDownTimer(INACTIVITY_TIMEOUT, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {}

            @Override
            public void onFinish() {
                if (isAppForeground) {
                    // 仅在前台时触发闲置操作
                    Intent lockIntent = new Intent(getApplicationContext(), LockScreenActivity.class);
                    lockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(lockIntent);
                }
            }
        };
        globalInactivityTimer.start();
    }

    // 提供给BaseActivity调用,用户交互时重置全局计时器
    public void resetGlobalTimer() {
        if (isAppForeground) {
            restartGlobalTimer();
        }
    }
}

然后在BaseActivity的onUserInteraction里调用全局重置方法:

@Override
public void onUserInteraction() {
    super.onUserInteraction();
    ((MyApp) getApplication()).resetGlobalTimer();
}

三、注意事项

  • 所有需要监听闲置的页面都要继承BaseActivity
  • onUserInteraction会响应用户的触摸、按键等操作,但弹窗(Dialog)、Toast等系统控件弹出时不会触发,若需要监听这类场景,要在弹窗的onShow/onDismiss方法里手动重置计时器
  • 闲置时长根据业务需求调整,单位为毫秒
  • 启动锁定页面时的Flag要根据栈管理需求设置,避免出现页面叠加的问题

内容的提问来源于stack exchange,提问作者Noterezeck

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:45:43