Приложение простое

В моем приложении есть три действия A -> B -> C -> A. Я хочу определить время простоя приложения, чтобы через 15 минут оно отображало сообщение независимо от активности. Каков наилучший метод для реализации этого.

2 ответа

Решение

Я бы сделал это следующим образом:

  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;
    }

}

Так что я бы лично использовал AlarmService. Вы можете указать PendingIntent, который запустит действие, которое отображает диалог. После любого события, которое должно перезапустить таймер, вы просто отменяете pendingIntent и перерегистрируете его.

Я думаю, что 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;
}
Другие вопросы по тегам