I want use onTouch in android.
While ACTION_DOWN I want to make button flash in a pattern [ 3 seconds off 3 seconds on ]
I want to do this for 3 intervals of the pattern.
If either ACTION_UP or ACTION_CANCEL is received before the 3 intervals are complete then cancel and leave button visible.
Otherwise call a function.
How would I accomplish this?
I have done similar using vibrator using a pattern.
long pattern[] = new long[] {0, 500, 500, 500, 500, 500, 500, 2000};
vibrator.vibrate(pattern, -1);
Not all devices have vibrator so I wnt to flash button instead.
Any help would be much appreciated.
This code below works but is not very elegant.
There must be a better way.
public class AndroidAnimButtonsActivity extends Activity
{
CountDownTimer countDownTimerOn;
CountDownTimer countDownTimerOff;
CountDownTimer countDownTimerSOS;
ImageButton SOSButton;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
countDownTimerOn = new CountDownOn(100, 1000);
countDownTimerOff = new CountDownOff(100, 1000);
countDownTimerSOS = new CountDownSOS(3*1000, 1000);
SOSButton = (ImageButton)findViewById(R.id.sosbutton);
SOSButton.setOnTouchListener(new OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN :
SOSButton.setImageResource(R.drawable.panic2);
countDownTimerOff.start();
countDownTimerSOS.start();
break;
case MotionEvent.ACTION_UP :
SOSButton.setImageResource(R.drawable.panic1);
countDownTimerOn.cancel();
countDownTimerOff.cancel();
countDownTimerSOS.cancel();
SOSButton.setVisibility(View.VISIBLE);
break;
case MotionEvent.ACTION_CANCEL :
SOSButton.setImageResource(R.drawable.panic1);
countDownTimerOn.cancel();
countDownTimerOff.cancel();
countDownTimerSOS.cancel();
SOSButton.setVisibility(View.VISIBLE);
break;
}
return false;
}
});
}
public class CountDownOn extends CountDownTimer
{
public CountDownOn(long totalTime, long interval)
{
super(totalTime, interval);
}
#Override
public void onFinish()
{
SOSButton.setVisibility(View.VISIBLE);
countDownTimerOff.start();
}
#Override
public void onTick(long leftTimeInMilliseconds)
{
long seconds = leftTimeInMilliseconds / 1000;
}
}
public class CountDownOff extends CountDownTimer
{
public CountDownOff(long totalTime, long interval)
{
super(totalTime, interval);
}
#Override
public void onFinish()
{
SOSButton.setVisibility(View.INVISIBLE);
countDownTimerOn.start();
}
#Override
public void onTick(long leftTimeInMilliseconds)
{
long seconds = leftTimeInMilliseconds / 1000;
}
}
// CountDownTimer class
public class CountDownSOS extends CountDownTimer
{
public CountDownSOS(long totalTime, long interval)
{
super(totalTime, interval);
}
#Override
public void onFinish()
{
SOSButton.setImageResource(R.drawable.panic2);
SOSButton.setVisibility(View.VISIBLE);
countDownTimerOn.cancel();
countDownTimerOff.cancel();
sendMsg();
}
#Override
public void onTick(long leftTimeInMilliseconds)
{
long seconds = leftTimeInMilliseconds / 1000;
}
}
public void sendMsg()
{
Toast.makeText(getApplicationContext(),"SOS", Toast.LENGTH_SHORT).show();
}
}
Related
I want to make a method (service, alarm, etc.) that can be calculated after x downtime user with the app
Which closes the current activity
and will send the initial activity (login)
Thank you very much
http://androidbite.blogspot.in/2012/11/android-count-down-timer-example.html
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
//here you can have your logic to set text to edittext
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Refer this link and some examples on countdown timer if you want to use this.
I answer
code is
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
// CIERRA LA APP MATANDO EL PROCESO Y VUELVE A ABRIRLO.
android.os.Process.killProcess(android.os.Process.myPid());
}
#Override
public void onTick(long millisUntilFinished) {
}
}
use
act.finishAffinity();
act.startActivity(new Intent(act, actMain.class));
I have a problem with my countdowntimer.
My app has a textview saying "tap to start" then the countdown starts from 3. My problem is when I set textview visibility(View.GONE) the countdown starts from 2 if I delete the line where i set visibility the countdown works fine (starting from 3) but of course the textview remain visible
I use 750 instead of 1000 in countdown because with 1000 the countdown always starts from 2
why this happen ? How can I solve this ?
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="60sp"
android:text="Tap to start"
android:id="#+id/starttext"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"/>
public void countdowntostart(){
TextView timetostart = (TextView) findViewById(R.id.starttext);
timetostart.setVisibility(View.GONE);
CountDownTimer countDownTimer = new CountDownTimer(3000, 750) {
TextView timestart = (TextView) findViewById(R.id.playtimetext);
public void onTick(long millisUntilFinished) {
timestart.setText("" + millisUntilFinished/1000);
}
public void onFinish() {
abcuu();
}
}.start();
}
The TextView's text display 2 is because the system have already calculated one second before it run onTick() method, therefore the 3 seconds countdown is still accurate even though the text view was displaying 2 when the countdown started. If you wish to show countdown value on a TextView, you can set the initial countdown value into TextView before the countdown.
It may be because you are not giving it a specific rounding. Try Math.ceil((double) millisecondsUntilFinished / 1000);
If that doesn't work, you might also try setting your timerstart text to "3" when you start the timer. Otherwise, I created a CustomCountdownTimer class that also has abstract methods for onStarted, onPaused, etc.
public abstract class CustomCountdownTimer {
private long millisInFuture;
private long countDownInterval;
private int secondsRemaining;
private boolean started;
private boolean paused;
public enum State {
RUNNING,
PAUSED,
STOPPED,
RESUMED,
STARTED,
FINISHED,
STATUS
}
public CustomCountdownTimer(long millisInFuture, long countDownInterval) {
this.millisInFuture = millisInFuture;
this.countDownInterval = countDownInterval;
started = false;
paused = false;
initialize();
}
public boolean isPaused(){
return paused && isStarted();
}
public boolean isStarted(){
return started;
}
public void pause() {
paused = true;
timerPaused(secondsRemaining);
}
public void resume(){
paused = false;
timerResumed(secondsRemaining);
}
public CustomCountdownTimer start() {
started = true;
return this;
}
public void stop() {
millisInFuture = 0;
}
public void initialize() {
final Handler handler = new Handler();
Log.v("status", "starting");
final Runnable counter = new Runnable(){
public void run(){
long sec = millisInFuture / 1000;
if(started && !paused) {
if(millisInFuture <= 0) {
Log.v("status", "done");
started = false;
onFinish();
} else {
Log.v("status", Long.toString(sec) + " seconds remain");
millisInFuture -= countDownInterval;
secondsRemaining = (int) Math.ceil(((double) millisInFuture / 1000));
handler.postDelayed(this, countDownInterval);
onTick(secondsRemaining);
}
} else {
Log.v("status", Long.toString(sec) + " seconds remain and timer has stopped!");
handler.postDelayed(this, countDownInterval);
}
}
};
handler.postDelayed(counter, countDownInterval);
}
public void updateTimer(long millisInFuture){
this.millisInFuture = millisInFuture;
}
public abstract void onTick(int secondsRemaining);
public abstract void onFinish();
public abstract void timerPaused(int secondsRemaining);
public abstract void timerResumed(int secondsRemaining);
}
Use it like this:
CustomCountdownTimer customCountdownTimer = new CustomCountdownTimer(totalSeconds * 1000, 1000) {
#Override
public void onTick(int remainingSeconds) {
// Code on each tick
}
#Override
public void onFinish() {
// Code to run when finished
}
#Override
public void timerPaused(int remainingSeconds) {
// Code to run if paused
}
#Override
public void timerResumed(int remainingSeconds) {
// Code to run when resumed from paused
}
};
customCountdownTimer.start();
Note that this is using full seconds rather than milliseconds, and it will show 3 when you start, rather than 2, because it's rounding up like I suggested earlier.
I implemented an app, inside there's a button to start a CountDownTimer and a TextView to display time left. Someone told me that the timer should run on other thread rather than on main thread, but as I start the timer normally, it 's on the main thread :
_timer = new CountDownTimer(min * 60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
tick();
setChanged();
notifyObservers();
clearChanged();
Log.v("THREAD TIMER : ", "" + Looper.myLooper().getThread().getName());
}
#Override
public void onFinish() {
end = true;
setChanged();
notifyObservers();
clearChanged();
}
};
I use an Observer to update the TextView each time the timer tick, and the code which update the TextView, is also run on the main thread (I confirm it with Looper.myLooper().getThread().getName()). But it didn't affect the TextView at all, but it did print out the debugging that I put to test. Anybody have any idea to fix this ?
Now this is even more confused. I extract the timer part, and formed a new project. Now, it worked. But of course it still didn't work on my actual project :
public class MainActivity extends Activity {
long TIME = 60000;
CountDownTimer _timer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b1 = (Button) findViewById(R.id.button_1);
Button b2 = (Button) findViewById(R.id.button_2);
final TextView t1 = (TextView) findViewById(R.id.timer_1);
TextView t2 = (TextView) findViewById(R.id.timer_2);
setUpButton1(b1, t1);
setUpButton2(b2, t2);
}
private void setUpButton2(final Button b2, final TextView t2){
final MyTimer myTimer = new MyTimer();
Observer ob = new Observer() {
#Override
public void update(Observable observable, Object data) {
//t2.setText(myTimer.toString());
t2.post(new Runnable() {
#Override
public void run() {
t2.setText(myTimer.toString());
}
});
Log.v("CLASS TIMER :", Looper.myLooper().getThread().getName() + " thread -- " + myTimer.toString());
}
};
myTimer.addObserver(ob);
b2.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
if(b2.isPressed()){
b2.setPressed(false);
myTimer.stopTimer();
}else{
b2.setPressed(true);
myTimer.startTimer();
}
}
return true;
}
});
}
private void setUpButton1(final Button b1, final TextView t1){
b1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP){
if (b1.isPressed() == true){
b1.setPressed(false);
_timer.cancel();
} else {
b1.setPressed(true);
_timer = new CountDownTimer(TIME, 1000) {
#Override
public void onTick(long millisUntilFinished) {
t1.setText("" + millisUntilFinished/1000);
TIME = millisUntilFinished;
}
#Override
public void onFinish() {
}
};
_timer.start();
}
}
return true;
}
});
}
}
Timer class :
public class MyTimer extends Observable{
CountDownTimer myTimer;
long TIME = 60000;
public MyTimer(){
}
public void startTimer(){
myTimer = new CountDownTimer(TIME, 1000) {
#Override
public void onTick(long millisUntilFinished) {
TIME = millisUntilFinished;
setChanged();
notifyObservers();
clearChanged();
}
#Override
public void onFinish() {
}
};
myTimer.start();
}
public void stopTimer(){
myTimer.cancel();
}
public String toString(){
return "" + TIME/1000;
}
}
Anybody have any idea what happened here ? Why it worked in this case, but not work when it's in the whole project ?
The question is: How can I add or remove time from the CountDownTimer during the count down?
For example: The user does something good: +5sec, the user does something wrong: -5sec.
Can someone help me with some code?
Maybe something like this
abstract class MyTimer {
public MyTimer(long deadline, long interval)
{
mDeadline = deadline;
mInterval = interval;
mTimer = new MyCountDownTimer(mDeadline, mInterval);
}
public synchronized void start() {
mTimer.start();
}
public abstract void onTick(long time);
public abstract void onFinish();
public synchronized void userDidRight()
{
mTimer.cancel();
mTimer = new MyCountDownTimer(mDeadline, mInterval += 5000);
mTimer.start();
}
public synchronized void userDidWrong()
{
mTimer.cancel();
mTimer = new MyCountDownTimer(mDeadline, mInterfval -= 5000);
mTimer.start();
}
private class MyCountDownTimer extends CountDownTimer() {
private abstract void onFinish() {
MyTimer.this.onFinish();
}
private abstract void onTick(long time) {
MyTimer.this.onTick(time);
}
}
private MyCountDownTimer mTimer;
}
You could restart the timer every time the user changes:
class Timer {
private long remainingTime;
private CoundDownTimer timer;
public void addTime(long addedTimeInMillis) {
createNewTimer(remainingTime + addedTimeInMills);
}
public void createNewTimer(long timeInMillis) {
if(timer != null) {
timer.cancel();
}
timer = new CountDownTimer(timeInMillis, 1000) {
#Override
public void onTick(final long millisUntilFinished) {
remainingTime = millisUntilFinished;
}
#Override
public void onFinish() {
// do something here
}
}.start();
}
}
private class startTimer extends CountDownTimer
{
public startTimer(long millisInFuture, long countDownInterval)
{
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
currenttime=millisUntilFinished;
textview.setText("" + currenttime / 1000);
}
#Override
public void onFinish() {
textview.setText("done");
}
}
The above class is a simple derived class of CountDownTimer
CountDownTimer timer = new CountDownTimer(30000,1000);
timer.start();
long currentTime;
For example the above timer starts from 30 secs,decreases by one for each second.
To increase or decrease the timer dynamically you can cancel the old timer and initialize with your new time as shown below
timer.cancel();
timer = new CountDownTimer(currentTime+5000,1000);// +5000 to increase by 5 secs
timer.start();
you can make timer,currentTime variables as global then you can use the two different parts of code at different location.
I want to do countdown timer with pause and restart.Now i am displaying countdown timer By implenting ontick() and onfinish().please help me out.HEre is th code for countdown timer
final CountDownTimer Counter1 = new CountDownTimer(timervalue1 , 1000)
{
public void onTick(long millisUntilFinished)
{
System.out.println("onTick method!"(String.valueOf(millisUntilFinished/1000)));long s1=millisUntilFinished;
}
public void onFinish()
{
System.out.println("Finished!");
}
}
in onTick method..save the milliseconds left
long s1=millisUntilFinished;
when you want to pause the timer use..
Counter.cancel();
when you want to resume create a new countdowntimer with left milliseconds..
timervalue=s1
counter= new Counter1();
counter.start();
See this link
I would add something to the onTick handler to save the progress of the timer in your class (number of milliseconds left).
In the onPause() method for the activity call cancel() on the timer.
In the onResume() method for the activity create a new timer with the saved number of milliseconds left.
Refer the below links
LINK
LINK
My first answer on stackOverFlow, hope it should help :) ...
This is how I solved the problem, control timer from Fragment, Bottomsheet, Service, Dialog as per your requirement, keep a static boolean variable to control.
declare in your Activity:
long presetTime, runningTime;
Handler mHandler =new Handler();
Runnable countDownRunnable;
Toast toastObj;
public static boolean shouldTimerRun = true;
TextView counterTv;
In onCreate:
presetTime =60000L;
runningTime= presetTime;
//setting up Timer
countDownRunnable=new Runnable() {
#Override
public void run() {
if (shouldTimerRun) //if false, it runs but skips counting
{
counterTv.setText(simplifyTimeInMillis(runningTime));
if (runningTime==0) {
deployToast("Task Completed"); //show toast on task completion
}
runningTime -= 1000;
presetTime = runningTime; //to resume the timer from last position
}
mHandler.postDelayed(countDownRunnable,1000); //simulating on-tick
}
};
mHandler.post(countDownRunnable); // Start our CountdownTimer
Now, whenever you want to pause the timer change the value of shouldTimerRun false and to resume make it true.
#Override
public void onResume() {
super.onResume();
shouldTimerRun=true;
}
#Override
public void onPause() {
super.onPause();
shouldTimerRun=false;
deployToast("Timer is paused !!");
}
Helping methods: (can be skipped)
public static String simplifyTimeInMillis(long time) {
String result="";
long difference = time;
long secondsInMilli = 1000;
long minutesInMilli = secondsInMilli * 60;
long hoursInMilli = minutesInMilli * 60;
if (difference<1000){
return "0";
}
if (difference>=3600000) {
result = result + String.valueOf(difference / hoursInMilli) + "hr ";
difference = difference % hoursInMilli;
}
if (difference>=60000) {
result = result + String.valueOf(difference / minutesInMilli) + "m ";
difference = difference % minutesInMilli;
}
if (difference>=1000){
result = result + String.valueOf(difference / secondsInMilli) + "s";
}
return result;
}
public void deployToast(String msg){
if (toastObj!=null)
toastObj.cancel();
toastObj = Toast.makeText(mContext,msg,Toast.LENGTH_SHORT);
toastObj.show();
}
I'm using two private vars in this case:
private long startPauseTime;
private long pauseTime = 0L;
public void pause() {
startPauseTime = System.currentTimeMillis();
}
public void resumen(){
pauseTime += System.currentTimeMillis() - startPauseTime;
}
I am afraid that it is not possible to pause or stop CountDownTimer and pausing or stopping in onTick has no effect whatsoever user TimerTask instead.
Set up the TimerTask
class UpdateTimeTask extends TimerTask {
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
timeLabel.setText(String.format("%d:%02d", minutes, seconds));
}
}
if(startTime == 0L) {
startTime = evt.getWhen();
timer = new Timer();
timer.schedule(new UpdateTimeTask(), 100, 200);
}
You can add event listener's like this..
private Handler mHandler = new Handler();
...
OnClickListener mStartListener = new OnClickListener() {
public void onClick(View v) {
if (mStartTime == 0L) {
mStartTime = System.currentTimeMillis();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 100);
}
}
};
OnClickListener mStopListener = new OnClickListener() {
public void onClick(View v) {
mHandler.removeCallbacks(mUpdateTimeTask);
}
};
For more refer to Android Documentation.
//This timer will show min:sec format and can be paused and resumed
public class YourClass extends Activity{
TextView timer;
CountDownTimer ct;
long c = 150000; // 2min:30sec Timer
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.YourXmlLayout);
timer = (TextView)findViewById(R.id.Yourtimer)
startTimer(); // it will start the timer
}
public void startTimer(){
ct = new CountDownTimer(c,1000) {
#Override
public void onTick(long millisUntilFinished) {
// Code to show the timer in min:sec form
// Here timer is a TextView so
timer.setText(""+String.format("%02d:%02d",millisUntilFinished/60000,(millisUntilFinished/1000)%60));
c = millisUntilFinished; // it will store millisLeft
}
#Override
public void onFinish() {
//your code here
}
};
ct.start();
}
/*===========================================================
*after creating this you can pause this by typing ct.cancel()
*and resume by typing startTimer()*/
public class MainActivity extends AppCompatActivity {
TextView textView;
CountDownTimer ctimer;
boolean runCountDown;
private long leftTime;
private static final long MILL_IN_FUTURE = 6000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text_view);
textView.setText("Click to start");
textView.setOnClickListener(this::clickStartAndPauseAndResume);
leftTime = MILL_IN_FUTURE;
}
public void clickStartAndPauseAndResume(View view) {
if (!runCountDown) {
long time = (leftTime == 0 || leftTime == MILL_IN_FUTURE) ? MILL_IN_FUTURE : leftTime;
ctimer = new CountDownTimer(time, 1) {
#Override
public void onTick(long l) {
leftTime = l;
textView.setText(l + "ms");
}
#Override
public void onFinish() {
textView.setText("Done");
leftTime = 0;
runCountDown = false;
textView.postDelayed(new Runnable() {
#Override
public void run() {
textView.setText("Click to start");
}
}, 1000);
}
}.start();
runCountDown = true;
} else {
ctimer.cancel();
textView.setText(textView.getText() + "\n Click to resume");
runCountDown = false;
}
}
}
A nice and simple way to create a Pause/Resume for your CountDownTimer is to create a separate method for your timer start, pause and resume as follows:
public void timerStart(long timeLengthMilli) {
timer = new CountDownTimer(timeLengthMilli, 1000) {
#Override
public void onTick(long milliTillFinish) {
milliLeft=milliTillFinish;
min = (milliTillFinish/(1000*60));
sec = ((milliTillFinish/1000)-min*60);
clock.setText(Long.toString(min)+":"+Long.toString(sec));
Log.i("Tick", "Tock");
}
The timerStart has a long parameter as it will be reused by the resume() method below. Remember to store your milliTillFinished (above as milliLeft) so that you may send it through in your resume() method. Pause and resume methods below respectively:
public void timerPause() {
timer.cancel();
}
private void timerResume() {
Log.i("min", Long.toString(min));
Log.i("Sec", Long.toString(sec));
timerStart(milliLeft);
}
Here is the code for the button FYI:
startPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(startPause.getText().equals("Start")){
Log.i("Started", startPause.getText().toString());
startPause.setText("Pause");
timerStart(15*1000);
} else if (startPause.getText().equals("Pause")){
Log.i("Paused", startPause.getText().toString());
startPause.setText("Resume");
timerPause();
} else if (startPause.getText().equals("Resume")){
startPause.setText("Pause");
timerResume();
}