【问题标题】:Detecting user inactivity and showing a pincode screen检测用户不活动并显示密码屏幕
【发布时间】:2018-05-29 11:04:27
【问题描述】:

当用户闲置超过 1 分钟时,我需要显示 Pincode 屏幕。

我发现 this answer 为我的需求提供了一个很好的解决方案,我在 BaseActivity 上实现了它。

但是现在我遇到了 onUserInteraction() 方法的问题,每次我按下按钮并开始一个新活动时,它都会被调用两次(并触发我的 Runnable 两次),因为当我1 分钟后返回上一屏幕,显示密码屏幕。

我已将 Runnable 更改为静态,但我失去了启动 pincode 活动的上下文。

我可以做些什么来从 runnable 启动 Activity 或确保 onUserInteraction() 仅在屏幕上点击某些东西时才被触发?

我当前的代码:

  public class BaseActivity {
        private static final String TAG = BaseActivity.class.getSimpleName();

    static private Handler disconnectHandler = new Handler() {
        public void handleMessage(Message msg) {
        }
    };

    private Runnable disconnectCallback = new Runnable() {
        @Override
        public void run() {
            Intent intent = new Intent(BaseActivity.this, CustomPinActivity.class);
            startActivity(intent);
        }
    };

    public void resetDisconnectTimer() {
        disconnectHandler.removeCallbacks(disconnectCallback);
        disconnectHandler.postDelayed(disconnectCallback, getResources().getInteger(R.integer.disconnect_timeout));
    }

    public void stopDisconnectTimer() {
        disconnectHandler.removeCallbacks(disconnectCallback);
    }

    @Override
    public void onUserInteraction() {
        resetDisconnectTimer();
    }

    @Override
    protected void onResume() {
        super.onResume();
        resetDisconnectTimer();
    }

    @Override
    public void onStop() {
        super.onStop();
        stopDisconnectTimer();
    }
}

清单:

<activity
        android:name=".CustomPinActivity"
        android:launchMode="singleTop"
        android:label="@string/title_activity_pincode" />

<activity android:name=".base.BaseActivity"
        android:launchMode="singleTop" />

【问题讨论】:

  • 您应该在启动 Activity 时使用标志 FLAG_ACTIVITY_SINGLE_TOP。
  • 我是。但是,当我通过单击按钮启动活动时,由于用户交互,我应该停止计时器。它确实有效,但仅适用于第一个 onUserInteraction()。第二个又开始了。日志:D/BaseActivity: onUserInteraction: reset timer resetDisconnectTimer D/BaseActivity: onUserInteraction: reset timer resetDisconnectTimer D/BaseActivity: onStop: .MainActivity stopDisconnectTimer
  • 我建议您发布启动 BaseActivity 的意图或其清单,以检查您是否使用 single_top 选项。无论如何,作为一般规则,我使用 onPause() 方法与 onResume() 方法相反。
  • 谢谢你,@NoMoreHelloWorld。我用 Manifest sn-p 编辑了我的帖子。使用 onPause 或 onStop 并没有阻止它运行两次。问题在此之前。用户交互在 onPause 之前被调用了两次,我认为它在那里复制了线程。
  • 好像CustomPinActivity扩展了BaseActivity,两个实例都收到了onUserInteraction的调用,所以都调用了postDelayed。两个类都使用自己的 Runnable 类实例,所以对象不同,所以一个类的 removeCallback 不会删除另一个类的回调,如果使用了它的 Runnable 实例,只会删除它的回调。

标签: android runnable user-inactivity pin-code


【解决方案1】:

嗯,我认为问题在于方法onUserInteraction()。文档说:

对活动的 onUserLeaveHint() 回调的所有调用都将伴随对 onUserInteraction() 的调用。

链接here。 onUserLeaveHint() 的文档说:

这个回调和 onUserInteraction() 旨在帮助活动智能地管理状态栏通知;具体来说,用于帮助活动确定取消通知的适当时间。

第二个链接here.

我了解,onUserInteraction() 方法将在每次暂停活动时以及在暂停之前调用。所以我会使用这样的标志:

    private boolean mStartingActivity;
    private Runnable disconnectCallback = new Runnable() {
            @Override
            public void run() {
                        mStartingActivity = true;
                        Intent intent = new Intent(BaseActivity.this, CustomPinActivity.class);
                        startActivity(intent);
                    }
                };

@Override 
public void onUserInteraction() {
                    if(!mStartingActivity)
                          resetDisconnectTimer();
                }

@Override
protected void onResume() {
                    super.onResume();
                    resetDisconnectTimer();
                    mStartingActivity = false;
                }

我猜,还有更优雅的解决方案。希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 2017-12-05
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多