在Android中检测应用程序何时处于空闲状态

13

我正在开发一款将在Kiosk模式下运行的应用程序。在这个应用程序中,如果用户在5分钟内没有进行任何操作,应用程序将显示一个屏幕保护程序,即应用程序的标志。

我的问题是,如何编写检测5分钟内无操作的代码?


https://dev59.com/p2855IYBdhLWcg3wq2XL - NigelK
嗨@NigelK,屏幕在空闲时不应该关闭,比如说,15秒后。 - androidBoomer
你好!这个屏幕在这5分钟内还是会一直亮着吗?当然,在6分钟后也是如此,如果是的话,那就很简单了! - iGio90
是的@iGio90,屏幕将在5分钟后保持开启状态,并显示应用程序的标志作为屏幕保护程序。 - androidBoomer
4个回答

26

这里有一个更好的解决方案......非常简单

我使用了以下倒计时计时器:

private long startTime = 15 * 60 * 1000; // 15 MINS IDLE TIME
private final long interval = 1 * 1000;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    countDownTimer = new MyCountDownTimer(startTime, interval);
}

@Override
public void onUserInteraction(){
    super.onUserInteraction();

    //Reset the timer on user interaction...
    countDownTimer.cancel();            
    countDownTimer.start();
}

public class MyCountDownTimer extends CountDownTimer {
    public MyCountDownTimer(long startTime, long interval) {
        super(startTime, interval);
    }

    @Override
    public void onFinish() {
        //DO WHATEVER YOU WANT HERE
    }

    @Override
    public void onTick(long millisUntilFinished) {
    }
}

干杯..........:)


当应用程序退出此活动时,如何取消倒计时?我在onFinish()中使用了一个意图,并且当我startActivity()或者如果我在这个活动中点击一个带我去其他地方的按钮时,它会重新启动计时器,导致计时器仍然处于活动状态。 - silversunhunter
1
为了在活动退出时停止倒计时器,您可以在onStop()中调用countDownTimer.cancel()方法。:) - Melbourne Lopes
解决方案很好。唯一的缺点是发现即使活动正在暂停时也会调用onUserInteraction()。因此,如果在onPause()中调用countdownTimer.cancel(),那么在此之前会进行一个多余的方法调用countdownTimer.start()。 - Akash Dubey

7
你应该试一下这个,它会在检测到5分钟闲置后用一个提示框进行通知。
Handler handler;
Runnable r;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    handler = new Handler();
    r = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            Toast.makeText(MainActivity.this, "user Is Idle from last 5 minutes",
                Toast.LENGTH_SHORT).show();
        }
    };
    startHandler();
}
@Override
public void onUserInteraction() {
     // TODO Auto-generated method stub
     super.onUserInteraction();
     stopHandler();//stop first and then start
     startHandler();
}
public void stopHandler() {
    handler.removeCallbacks(r);
}
public void startHandler() {
    handler.postDelayed(r, 5*60*1000);
}

2
它运行得很完美。但如何将其应用到应用程序层面? - Deepak Borade
在函数中使用处理程序代码,并从任何地方调用它。 - Pradeep Gupta
1
@PradeepGupta 如何在Application类中应用这个? - Gaju Kollur

5
我认为你可以在你的应用程序中使用http://developer.android.com/reference/android/app/Activity.html#dispatchTouchEvent(android.view.MotionEvent)http://developer.android.com/reference/android/app/Activity.html#dispatchKeyEvent(android.view.KeyEvent)来设置时间戳,每当用户交互时记录一次(简单地重写这些方法,在结尾处返回false,以便事件将传播到底层视图)-然后您可以使用某种计时器定期检查交互的最后时间戳,并在达到空闲时间5分钟时触发您的屏幕保护程序。

所以在一个Activity中,你只需要像这样重写前面提到的方法:

@Override
public boolean dispatchTouchEvent (MotionEvent ev) {
   timestamp = System.getCurrentTimeMilis();
   return false; // return false to indicate that the event hasn't been handled yet
}

dispatchKeyEvent和其他可以重写以确定用户活动的方法应该工作得相当类似。

如果您正在使用多个Activity,您可能需要创建一个扩展Activity的基类,并覆盖所有您想要处理的dispatchXXXEvent方法,然后将其用作所有Activity的基类。但是我猜您的实现细节可能有点超出了实际问题的范围 :)

关于不同计时器的可能性,您可以在这里找到有用的信息:在Android中安排定期任务


嗨@Foxtur,你能给我一个使用dispatchTouchEvent()的例子吗? - androidBoomer
1
@TwistedDroid 抱歉,我不小心链接了文档的View类而不是Activity类 - 但现在应该已经修复了。 我还添加了一个示例代码 - 因为我当前不在工作站上,无法测试代码本身,希望它能正常工作。否则,当我回到安装有Android SDK的机器时,我会跟进编辑答案:) - Foxtur

1

try with:

private void startCount(int time) {

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {

            // Add here the code for showing the fullscreenlogo

        }
    }, time);
}

然后,无论何时您想要开始计数,都应该添加:

startCount(time); // Replace time with 60*5*1000 for 5 mins

如果您想在应用程序最小化时开始计数,则使用以下方法:
@Override
public void onPause() {
    super.onPause();
    startCount(time);
}

startCount(time)将在触摸事件之后触发。即使标志显示,当用户触摸屏幕时,它也会返回到最后一个捕获空闲的活动。我应该使用什么代码? - androidBoomer
startCount(time); <-- 将此代码添加到您的 ontouch/onclick 中。如果您希望用户在触摸屏幕时返回应用程序,则需要一个服务! - iGio90

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接