Detect when application is idle in Android - android

I am developing an application that will be running in Kiosk Mode. In this application, if the user didn't do anything in the application within 5 minutes, the application will show a screen saver that is the logo of the application.
My question is, how can I code on detecting IDLE within 5 minutes?

A BETTER SOLUTION HERE...... VERY SIMPLE
I used countdown timer as bellow:
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) {
}
}
CHEERS..........:)

You should try this, It will Notify with a toast on detecting IDLE 5 minutes.
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);
}

I think you could use http://developer.android.com/reference/android/app/Activity.html#dispatchTouchEvent(android.view.MotionEvent) and http://developer.android.com/reference/android/app/Activity.html#dispatchKeyEvent(android.view.KeyEvent) in your App to set a timestamp everytime a userinteraction takes place (simply override the methods and return false at the end so that the events will be propagated to underlying views) - then you can use some kind of timer which checks for the last timestamp of interaction recurringly and trigger your screen saver if your 5 minutes IDLE time are reached.
So in an Activity you simply override the before mentioned Methods like this:
#Override
public boolean dispatchTouchEvent (MotionEvent ev) {
timestamp = System.getCurrentTimeMilis();
return false; // return false to indicate that the event hasn't been handled yet
}
The dispatchKeyEvent and the other methods which you can override to determine user-activity should work fairly similar.
If you're using more than one Activity you may want to create a base class which extends Activity and Override all the dispatchXXXEvent you want to handle and which you than use as base class of all your Activities. But I guess the details of your implementation may be a little bit out of scope for the actual question :)
For the different possibilities of timers you may find useful info here: Scheduling recurring task in Android

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);
}
then, whenever you want to start the count you should add:
startCount(time); // Replace time with 60*5*1000 for 5 mins
if you want to start the count when the app got minimized, then use this:
#Override
public void onPause() {
super.onPause();
startCount(time);
}

Related

Lifecycle activity stopwatch

I am new to android.
Learning about the lifecycle of the activity.
I am having difficulty understanding the logic here.
There are three variables:
boolean running, wasRunning, and int seconds.
I am not able to understand the code inside onStop and onStart. Can someone please explain the logic of the code shared below that why are we using wasRunning?
public void runTimer()
{
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
running = true;
}
});
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
running = false;
}
});
reset.setOnClickListener(newView.OnClickListener() {
#Override
public void onClick(View v) {
running = false;
seconds = 0;
}
});
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
int hours = seconds / 3600;
int min = (seconds % 3600) / 60;
int sec = seconds % 60;
String time = String.format("%d:%02d:%02d", hours, min, sec);
text.setText(time);
if (running) {
seconds++;
}
handler.postDelayed(this, 1000);
}
});
}
#Override
protected void onStop() {
super.onStop();
wasRunning=running;
running=false;
}
#Override
protected void onStart() {
super.onStart();
if(wasRunning);
running=true;
}
This is actually very poor code. It keeps a continually running timer, and uses a flag to ignore it when not running. Instead, when the activity is stopped it should stop the timer to use fewer CPU resources. But here's what it does:
OnStop- when the activity is backgrounded, start ignoring timer events, and set a flag (wasRunning) to know whether it was running when it was last active.
onStart- if the timer was running last time the app was foregrounded, stop ignoring timer events.
So the combo of these two functions will ignore all timer events when in the background, but start listening to them again when it regains the foreground.

How to start auto time out timer when my screen goes off and app goes to background cases and Need to stop timer when i click logout

i'm working with bunch of activities, i need to implement auto time out when my app is in inactivity state. my scenario is when i login my timer need to start if i didn't do anything after i logged in.
my timer need to start with last interaction with application,
my timer need to start when my app goes to background and screen off cases, and also
my timer need to stop when i log out from application.
i tried with below code from Here only:
public class MyBaseActivity extends Activity {
public static final long DISCONNECT_TIMEOUT = 300000; // 5 min = 5 * 60 * 1000 ms
private Handler disconnectHandler = new Handler(){
public void handleMessage(Message msg) {
}
};
private Runnable disconnectCallback = new Runnable() {
#Override
public void run() {
// Perform any required operation on disconnect
}
};
public void resetDisconnectTimer(){
disconnectHandler.removeCallbacks(disconnectCallback);
disconnectHandler.postDelayed(disconnectCallback, DISCONNECT_TIMEOUT);
}
public void stopDisconnectTimer(){
disconnectHandler.removeCallbacks(disconnectCallback);
}
#Override
public void onUserInteraction(){
resetDisconnectTimer();
}
#Override
public void onResume() {
super.onResume();
resetDisconnectTimer();
}
#Override
public void onStop() {
super.onStop();
stopDisconnectTimer();
}
}
But this code doesn't starts my timer when my app goes background or app screen offs, in those cases timer stopped.
Please give me ur valuable suggestions and help me for saving my time on things.Thanks all.
Need to detect whether the app is in background state or not
#Override
public void onStop() {
if (Constant.isAppIsInBackground(this)) {
stopDisconnectTimer();
resetDisconnectTimer();
}else {
stopDisconnectTimer();
}
super.onStop();
//stopDisconnectTimer();
}
Here isAppisBackground() is the method for detecting background state

Android OnChronometerTickListener not being called

I'm creating a simple application that uses a timer in a service. The service will then publish its time updates to the main activity.
I've decided to use a Chronometer to implement the stopwatch functionality, however when I try to get the onChronometerTick updates to update the activity, no ticks are being caught. The OnChronometerTick function is only being called once at initialisation, never again there after.
Method to init Chronometer:
Chronometer timer;
#Override
public void onCreate() {
super.onCreate();
Log.d(LOG_TAG, "TimerService created");
// Initialise timer but don't start it
timer = new Chronometer(this);
}
public void startTimer() {
Log.d(LOG_TAG, "Timer started");
timer.setOnChronometerTickListener(listener);
timer.setBase(SystemClock.elapsedRealtime());
timer.start();
}
where listener is:
Chronometer.OnChronometerTickListener listener = new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
Log.d(LOG_TAG, "TICK");
//final long time = SystemClock.elapsedRealtime() - timer.getBase();
//i.putExtra(INTENT_KEY, time);
//sendBroadcast(i);
}
};
"TICK" only gets logged once when I call startTimer(). I have another function getElapsedTime() which calculates the elapsed time, which seems to be working fine. There are no errors or anything unusual being logged, unfortunately.
Thanks for your time! :)
The Chronometer is a View, that is, a UI element. You never add your Chronometer to any layout, I guess that's why it's never updating.
From this Log.d(LOG_TAG, "TimerService created"); I'm guessing you're working on a Service rather than an Activity and services don't usually have a UI, so a Chronometer is probably not what you want.
You could try using a CountDownTimer or a Handler / Runnable combination.
http://developer.android.com/reference/android/os/CountDownTimer.html
http://developer.android.com/reference/android/os/Handler.html
Here's an example using Handler / Runnable, I've even thrown in a stopTimer() method for good measure:
private Handler timerHandler;
private Runnable timerRunnable;
// ...
#Override
public void onCreate() {
super.onCreate();
Log.d(LOG_TAG, "TimerService created");
timerHandler = new Handler();
timerRunnable = new Runnable() {
#Override
public void run() {
Log.d(LOG_TAG, "TICK");
timerHandler.postDelayed(timerRunnable, 1000);
}
};
}
public void startTimer() {
Log.d(LOG_TAG, "Timer started");
timerHandler.post(timerRunnable);
}
public void stopTimer() {
Log.d(LOG_TAG, "Timer stopped");
timerHandler.removeCallbacks(timerRunnable);
}

Periodically refresh/reload activity

I have one activity. OnCreate the activity gets the source (html) of a web page to a string and presents the result (after parsing it a bit) in a textview.
I would like the activity to reload/refresh periodically to always present the latest information.
What is the best solution for this?
First of all... separate the updating logic from your onCreate method. So, for instance, you can create an updateHTML().
Then, you can use a Timer in order to update the page periodically:
public class YourActivity extends Activity {
private Timer autoUpdate;
public void onCreate(Bundle b){
super.onCreate(b);
// whatever you have here
}
#Override
public void onResume() {
super.onResume();
autoUpdate = new Timer();
autoUpdate.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
updateHTML();
}
});
}
}, 0, 40000); // updates each 40 secs
}
private void updateHTML(){
// your logic here
}
#Override
public void onPause() {
autoUpdate.cancel();
super.onPause();
}
}
Notice that I'm canceling the updating task on onPause, and that in this case the updateHTML method is executed each 40 secs (40000 milliseconds). Also, make sure you import these two classes: java.util.Timer and java.util.TimerTask.

How to set a timer in android

What is the proper way to set a timer in android in order to kick off a task (a function that I create which does not change the UI)?
Use this the Java way:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html
Or there is a better way in android (android's handler)?
yes java's timer can be used, but as the question asks for better way (for mobile). Which is explained Here.
For the sake of StackOverflow:
Since Timer creates a new thread it may be considered heavy,
if all you need is to get is a call back while the activity is running a Handler can be used in conjunction with a
Runnable:
private final int interval = 1000; // 1 Second
private Handler handler = new Handler();
private Runnable runnable = new Runnable(){
public void run() {
Toast.makeText(MyActivity.this, "C'Mom no hands!", Toast.LENGTH_SHORT).show();
}
};
...
handler.postAtTime(runnable, System.currentTimeMillis()+interval);
handler.postDelayed(runnable, interval);
or a Message
private final int EVENT1 = 1;
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Event1:
Toast.makeText(MyActivity.this, "Event 1", Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(MyActivity.this, "Unhandled", Toast.LENGTH_SHORT).show();
break;
}
}
};
...
Message msg = handler.obtainMessage(EVENT1);
handler.sendMessageAtTime(msg, System.currentTimeMillis()+interval);
handler.sendMessageDelayed(msg, interval);
on a side note this approach can be used, if you want to run a piece of code in the UI thread from an another thread.
WARNING: Handler's timer (or whatever controls delays) gets paused whenever the CPU goes to deep-sleep, but will continue once CPU wakes up (from where it was paused).
if you need to get a call back even if your activity is not running then, you can use an AlarmManager.
Standard Java way to use timers via java.util.Timer and java.util.TimerTask works fine in Android, but you should be aware that this method creates a new thread.
You may consider using the very convenient Handler class (android.os.Handler) and send messages to the handler via sendMessageAtTime(android.os.Message, long) or sendMessageDelayed(android.os.Message, long). Once you receive a message, you can run desired tasks. Second option would be to create a Runnable object and schedule it via Handler's functions postAtTime(java.lang.Runnable, long) or postDelayed(java.lang.Runnable, long).
As I have seen it, java.util.Timer is the most used for implementing a timer.
For a repeating task:
new Timer().scheduleAtFixedRate(task, after, interval);
For a single run of a task:
new Timer().schedule(task, after);
task being the method to be executed
after the time to initial execution
(interval the time for repeating the execution)
I hope this one is helpful and may take less efforts to implement,
Android CountDownTimer class
e.g.
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Probably Timerconcept
new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
}
}.start();
or
Method 2 ::
Program the timer
Add a new variable of int named time. Set it to 0.
Add the following code to onCreate function in MainActivity.java.
//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);
Go into the run method and add the following code.
//We must use this function in order to change the text view text
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView tv = (TextView) findViewById(R.id.main_timer_text);
tv.setText(String.valueOf(time));
time += 1;
}
});
It is situational.
The Android documentation suggests that you should use AlarmManager to register an Intent that will fire at the specified time if your application may not be running.
Otherwise, you should use Handler.
Note: The Alarm Manager is intended
for cases where you want to have your
application code run at a specific
time, even if your application is not
currently running. For normal timing
operations (ticks, timeouts, etc) it
is easier and much more efficient to
use Handler.
Here we go.. We will need two classes. I am posting a code which changes mobile audio profile after each 5 seconds (5000 mili seconds) ...
Our 1st Class
public class ChangeProfileActivityMain extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Timer timer = new Timer();
TimerTask updateProfile = new CustomTimerTask(ChangeProfileActivityMain.this);
timer.scheduleAtFixedRate(updateProfile, 0, 5000);
}
}
Our 2nd Class
public class CustomTimerTask extends TimerTask {
private AudioManager audioManager;
private Context context;
private Handler mHandler = new Handler();
// Write Custom Constructor to pass Context
public CustomTimerTask(Context con) {
this.context = con;
}
#Override
public void run() {
// TODO Auto-generated method stub
// your code starts here.
// I have used Thread and Handler as we can not show Toast without starting new thread when we are inside a thread.
// As TimePicker has run() thread running., So We must show Toast through Handler.post in a new Thread. Thats how it works in Android..
new Thread(new Runnable() {
#Override
public void run() {
audioManager = (AudioManager) context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
mHandler.post(new Runnable() {
#Override
public void run() {
if(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Toast.makeText(context, "Ringer Mode set to Normal", Toast.LENGTH_SHORT).show();
} else {
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Toast.makeText(context, "Ringer Mode set to Silent", Toast.LENGTH_SHORT).show();
}
}
});
}
}).start();
}
}
I'm an Android newbie but here is the timer class I created based on the answers above. It works for my app but I welcome any suggestions.
Usage example:
...{
public Handler uiHandler = new Handler();
private Runnable runMethod = new Runnable()
{
public void run()
{
// do something
}
};
timer = new UITimer(handler, runMethod, timeoutSeconds*1000);
timer.start();
}...
public class UITimer
{
private Handler handler;
private Runnable runMethod;
private int intervalMs;
private boolean enabled = false;
private boolean oneTime = false;
public UITimer(Handler handler, Runnable runMethod, int intervalMs)
{
this.handler = handler;
this.runMethod = runMethod;
this.intervalMs = intervalMs;
}
public UITimer(Handler handler, Runnable runMethod, int intervalMs, boolean oneTime)
{
this(handler, runMethod, intervalMs);
this.oneTime = oneTime;
}
public void start()
{
if (enabled)
return;
if (intervalMs < 1)
{
Log.e("timer start", "Invalid interval:" + intervalMs);
return;
}
enabled = true;
handler.postDelayed(timer_tick, intervalMs);
}
public void stop()
{
if (!enabled)
return;
enabled = false;
handler.removeCallbacks(runMethod);
handler.removeCallbacks(timer_tick);
}
public boolean isEnabled()
{
return enabled;
}
private Runnable timer_tick = new Runnable()
{
public void run()
{
if (!enabled)
return;
handler.post(runMethod);
if (oneTime)
{
enabled = false;
return;
}
handler.postDelayed(timer_tick, intervalMs);
}
};
}
I am using a handler and runnable to create a timer. I wrapper this in an abstract class. Just derive/implement it and you are good to go:
public static abstract class SimpleTimer {
abstract void onTimer();
private Runnable runnableCode = null;
private Handler handler = new Handler();
void startDelayed(final int intervalMS, int delayMS) {
runnableCode = new Runnable() {
#Override
public void run() {
handler.postDelayed(runnableCode, intervalMS);
onTimer();
}
};
handler.postDelayed(runnableCode, delayMS);
}
void start(final int intervalMS) {
startDelayed(intervalMS, 0);
}
void stop() {
handler.removeCallbacks(runnableCode);
}
}
Note that the handler.postDelayed is called before the code to be executed - this will make the timer more closed timed as "expected". However in cases were the timer runs to frequently and the task (onTimer()) is long - there might be overlaps. If you want to start counting intervalMS after the task is done, move the onTimer() call a line above.
I believe the way to do this on the android is that you need a background service to be running. In that background application, create the timer. When the timer "ticks" (set the interval for how long you want to wait), launch your activity which you want to start.
http://developer.android.com/guide/topics/fundamentals.html (<-- this article explains the relationship between activities, services, intents and other core fundamentals of Android development)
I used to use (Timer, TimerTask) as well as Handler to kick off (time-consuming) tasks periodically. Now I've switched the whole to RxJava. RxJava provides Observable.timer which is simpler, less error-prone, hassle-free to use.
public class BetterTimerFragment extends Fragment {
public static final String TAG = "BetterTimer";
private TextView timeView;
private Subscription timerSubscription;
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_timer, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
timeView = (TextView) view.findViewById(R.id.timeView);
}
#Override
public void onResume() {
super.onResume();
// Right after the app is visible to users, delay 2 seconds
// then kick off a (heavy) task every 10 seconds.
timerSubscription = Observable.timer(2, 10, TimeUnit.SECONDS)
.map(new Func1<Long, String>() {
#Override
public String call(Long unused) {
// TODO: Probably do time-consuming work here.
// This runs on a different thread than the main thread.
return "Time: " + System.currentTimeMillis();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
#Override
public void call(String timeText) {
// The result will then be propagated back to the main thread.
timeView.setText(timeText);
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
Log.e(TAG, throwable.getMessage(), throwable);
}
});
}
#Override
public void onPause() {
super.onPause();
// Don't kick off tasks when the app gets invisible.
timerSubscription.unsubscribe();
}
}
For timing operation you should use Handler.
If you need to run a background service the AlarmManager is the way to go.
this example start the timer unitl destroyed in Kotlin
private lateinit var timerTask: TimerTask
timerTask = object : TimerTask() {
override fun run() {
Log.d("KTZ", "$minutes:$seconds");
timeRecordingLiveData.postValue("$minutes:$seconds")
seconds += 1;
if (seconds == 60) {
Log.d("KTZ", "$minutes:$seconds");
timeRecordingLiveData.postValue("$minutes:$seconds")
seconds = 0;
minutes += 1;
}
}
}
Cancel the timertask in onDestroy()
timerTask.cancel()

Categories

Resources