【问题标题】:Application idle time应用程序空闲时间
【发布时间】:2010-11-02 05:43:28
【问题描述】:

在我的应用程序中有三个活动 A -> B -> C -> A。我想检测应用程序的空闲时间,以便在 15 分钟后无论活动如何都会弹出一条消息。实现这一点的最佳方法是什么。

【问题讨论】:

    标签: android


    【解决方案1】:

    我会这样做:

    1. 创建将控制空闲活动的线程
    2. 在应用环境中运行这个线程
    3. 在每次用户交互时只需刷新空闲时间

    用于存储控制空闲时间的全局线程的类

    public class ControlApplication extends Application
    {
        private static final String TAG=ControlApplication.class.getName();
        private Waiter waiter;  //Thread which controls idle time
    
        // only lazy initializations here!
        @Override
        public void onCreate()
        {
            super.onCreate();
            Log.d(TAG, "Starting application"+this.toString());
            waiter=new Waiter(15*60*1000); //15 mins
            waiter.start();
        }
    
        public void touch()
        {
            waiter.touch();
        }
    }
    

    将成为您所有活动的父级的类

    public class ControlActivity extends Activity
    {
        private static final String TAG=ControlActivity.class.getName();
    
        /**
         * Gets reference to global Application
         * @return must always be type of ControlApplication! See AndroidManifest.xml
         */
        public ControlApplication getApp()
        {
            return (ControlApplication )this.getApplication();
        }
    
        @Override
        public void onUserInteraction()
        {
            super.onUserInteraction();
            getApp().touch();
            Log.d(TAG, "User interaction to "+this.toString());
        }
    
    }
    

    最后是线程本身

    public class Waiter extends Thread
    {
        private static final String TAG=Waiter.class.getName();
        private long lastUsed;
        private long period;
        private boolean stop;
    
        public Waiter(long period)
        {
            this.period=period;
            stop=false;
        }
    
        public void run()
        {
            long idle=0;
            this.touch();
            do
            {
                idle=System.currentTimeMillis()-lastUsed;
                Log.d(TAG, "Application is idle for "+idle +" ms");
                try
                {
                    Thread.sleep(5000); //check every 5 seconds
                }
                catch (InterruptedException e)
                {
                    Log.d(TAG, "Waiter interrupted!");
                }
                if(idle > period)
                {
                    idle=0;
                    //do something here - e.g. call popup or so
                }
            }
            while(!stop);
            Log.d(TAG, "Finishing Waiter thread");
        }
    
        public synchronized void touch()
        {
            lastUsed=System.currentTimeMillis();
        }
    
        public synchronized void forceInterrupt()
        {
            this.interrupt();
        }
    
        //soft stopping of thread
        public synchronized void stop()
        {
            stop=true;
        }
    
        public synchronized void setPeriod(long period)
        {
            this.period=period;
        }
    
    }
    

    【讨论】:

    • 非常感谢,我快到了。而不是这个 @Override public void onUserInteraction(){ } ,我使用 OnKeyEvent()。
    • onUserInteraction() 更好:)
    • 在清单文件中使用
    • 我需要做同样的事情,这段代码帮了我很多,但我不知道如何调用注销服务(我实现的服务)并指导用户登录活动
    • 使用广播接收器监听“注销”操作
    【解决方案2】:

    所以我会亲自使用AlarmService。您可以指定一个 PendingIntent 来启动一个显示对话框的活动。在任何应该重新启动计时器的事件之后,您只需取消pendingIntent 并重新注册它。

    【讨论】:

    • 和我一样,它对我有用。重新注册计时器要捕获哪些事件。
    • 这取决于您的应用程序和空闲的定义。最简单的方法是使用广播意图,当您感觉用户不再空闲时触发该意图。在您的接收器中重置计时器。
    • 对于什么事件你重启你的计时器?我们正在尝试在我们的项目中实现这一点,并根据触摸事件对其进行重置,但 Android 的触摸调度系统实际上并不允许这样做。
    • 活动内部有一个名为 onUserInteraction() 的事件,它有点可靠。因此,无论何时调用它,您都可以将其重置。它不仅应该考虑触摸事件,还应该考虑光标事件。我仍然会采用这种方法,因为临时线程通常永远不会很好地结束。如果 AlarmService 对于这种情况来说太重了,我什至会使用 Handler。
    【解决方案3】:

    我认为CountDownTimer 是最好的方法。

        public class IdleCountDownTimer extends CountDownTimer {
            public IdleCountDownTimer(long startTime, long interval) {
                super(startTime, interval);
            }
    
            @Override
            public void onFinish() {
                //Time lapsed 
               Toast.makeText(getApplicationContext(),"The text you want to display",Toast.LENGTH_LONG)
    
            }
    
            @Override
            public void onTick(long millisUntilFinished) {
            }
        } 
    

    现在声明全局对象

    IdleCountDownTimer idleCountDownTimer;
    

    现在初始化并开始倒计时。

    @Override
    public void onCreate()
    {
        super.onCreate();
        idleCountDownTimer = new IdleCountDownTimer(seconds * 60 * 1000, interval_in_seconds * 60 * 1000);
        idleCountDownTimer.start();
    }
    

    现在调用取消并在您想重置倒计时时开始。

    例如 1:用于所有按键、触摸或轨迹球事件

    @Override
    public void onUserInteraction(){
        super.onUserInteraction();
    
        //Reset the count down
        idleCountDownTimer.cancel();             
        idleCountDownTimer.start();
    }
    

    例如 2:仅适用于触摸事件

    @Override
    public boolean onTouchEvent(MotionEvent event) {
            //Reset the count down
            idleCountDownTimer.cancel();             
            idleCountDownTimer.start();
    
            // Let the event flow
            return false;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-03
      • 2013-09-05
      • 2020-09-23
      • 1970-01-01
      • 2022-01-19
      相关资源
      最近更新 更多