i just started to learn creating android apps. I wanted to create a simple count down timer that takes a value from a edittext but countdown timer does not seem to run.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
countDownTxt = (TextView) findViewById(R.id.countDownView);
intervalTxt = (TextView) findViewById(R.id.intervalText);
findViewById(R.id.startBN).setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
int testInt = 30;
//countDownTxt.setText(intervalTxt.getText());
int interval = Integer.parseInt(intervalTxt.getText().toString());
Log.d("buttonpressed", "interval for countdown is " + interval);
cdt = new CountDownTimer(Integer.parseInt(intervalTxt.getText().toString()), 1000) {
public void onTick(long millisUntilFinished) {
Log.d("counttimer1", "haha1");
countDownTxt.setText(""+ millisUntilFinished / 1000);
}
public void onFinish() {
cancel();
}
}.start();
}
}
);
}
In particular, this program works only if i enter a numerical value such as 30000 in the 1st parameter of the CountDownTimer "cdt = new CountDownTimer(testInt, 1000)"
Can someone enlighten me please? Thank you!
"Doesn't work" how? You should post the error message you're getting or other symptoms of "doesn't work."
What's probably happening is CountDownTimer accepts only long values as the first parameter of its constructor. Not int values.
Change int testInt = 30 to long testLong = 10000.0f and see what happens.
The first parameter means milliseconds, by the way, so "30" isn't really going to get you much in the first place.
onTick() method is called in a separate Thread. But you don't have right to use setText() method outside the GUI Thread.
You must use a Handler object or Activity.postOnUiThread() method to execute something in the GUI Thread :
cdt = new CountDownTimer(Integer.parseInt(intervalTxt.getText().toString()), 1000) {
public void onTick(long millisUntilFinished) {
Log.d("counttimer1", "haha1");
runOnUiThread(new Runnable() {
#Override
public void run() {
countDownTxt.setText("" + millisUntilFinished / 1000);
}
});
countDownTxt.setText(""+ millisUntilFinished / 1000);
}
public void onFinish() {
cancel();
}
}.start();
For more informations, read http://developer.android.com/guide/components/processes-and-threads.html#Threads
Related
i wrote this code and i want when i click on btnGetPincode, a 60 sec count down timer start to run.
but it didnt happen and the result in textview= 00:00 and nothing happen. why?
this is my code:
btnGetPinCode.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
btnGetPinCode.setClickable(false);
btnGetPinCode.setBackgroundResource((R.drawable.button4));
txtShowPinCode.setVisibility(View.VISIBLE);
//initialize timer duration
long duration = TimeUnit.MINUTES.toMillis(1);
//initialize timer countdown timer
new CountDownTimer(duration, 1000) {
#Override
public void onTick(long millisUntilFinished) {
String duration2 = String.format(Locale.ENGLISH, "%02d : %02d"
, TimeUnit.MILLISECONDS.toMinutes(1)
, TimeUnit.MILLISECONDS.toSeconds(1) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(1)));
//set converted time to textView
txtTimer.setVisibility(View.VISIBLE);
txtTimer.setText(duration2+"");
btnOk.setText(duration2);
}
#Override
public void onFinish() {
//when timer finished, hide text view
txtTimer.setVisibility(View.INVISIBLE);
btnGetPinCode.setBackgroundResource(R.drawable.button);
btnGetPinCode.setClickable(true);
}
}.start();
});
}
Issue: You set 1 in each argument in duration2 variable, so the TextView won't ever be changed, you need to set the actual value that is changed on every timer tick which is the parameter of the onTick() method >> millisUntilFinished
Change your timer to:
new CountDownTimer(duration, 1000) {
#Override
public void onTick(long millisUntilFinished) {
String duration2 = String.format(Locale.ENGLISH, "%02d : %02d"
, TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) //<<<<< change here
, TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - //<<<< change here
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))); //<<<<< change here
//set converted time to textView
txtTimer.setVisibility(View.VISIBLE);
txtTimer.setText(duration2+"");
btnOk.setText(duration2);
}
#Override
public void onFinish() {
//when timer finished, hide text view
txtTimer.setVisibility(View.INVISIBLE);
btnGetPinCode.setBackgroundResource(R.drawable.button);
btnGetPinCode.setClickable(true);
}
}.start();
The main problem lies in calculation of time duration2
//Declare timer
CountDownTimer cTimer = null;
cTimer = new CountDownTimer(duration, 1000) {
#Override
public void onTick(long millisUntilFinished) {
String duration2 = String.format(Locale.ENGLISH, "%02d : %02d"
, TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) //Here is the problem
, TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - //Here is the problem
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))); //<<<<< change here
//set converted time to textView
txtTimer.setVisibility(View.VISIBLE);
txtTimer.setText(duration2+"");
btnOk.setText(duration2);
}
#Override
public void onFinish() {
//when timer finished, hide text view
txtTimer.setVisibility(View.INVISIBLE);
btnGetPinCode.setBackgroundResource(R.drawable.button);
btnGetPinCode.setClickable(true);
}
}.start();
You should also need to clean up the references so as to prevent memory leaks. This needs to be called cTtimer.cancel() whenever the onDestroy()/onDestroyView() in the owning Activity/Fragment is called.
void cancelTimer() {
if(cTimer!=null)
cTimer.cancel();
}
I am trying to show a countDownTimer in my activity. the value I am using in the countDowntimer is coming from a recyclerview of another activity using bundle. when I click one of the recyclerview time for the first time, the countDownTimer shows the time running perfectly. but when I select another time, the old instance continues to run. I have implemented the cancel and onFinish() methods to but they are not working as I want. I searched everywhere but everyone suggested about cancel and onFinish() methods. I am unable to find a solution now.
public void getData() {
if(countDownTimer!=null){
countDownTimer.cancel();
}
if (replaceTime != null) {
time = Integer.parseInt(replaceTime);
} else
Toast.makeText(FullTimerActivity.this, "",
Toast.LENGTH_LONG).show();
totalTimeCountInMilliseconds = time;
timeBlinkInMilliseconds = 30 * 1000;
countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
#Override
public void onTick(long leftTimeInMilliseconds) {
long seconds = leftTimeInMilliseconds / 1000;
if (leftTimeInMilliseconds < timeBlinkInMilliseconds) {
if (blink) {
// mTextField.setVisibility(View.VISIBLE);
// if blink is true, textview will be visible
} else {
// mTextField.setVisibility(View.INVISIBLE);
}
blink = !blink;
}
String a = String.format("%02d", seconds / 60) + ":" + String.format("%02d", seconds % 60);
textView.setText(a);
}
#Override
public void onFinish() {
Toast.makeText(FullTimerActivity.this, "Finished", Toast.LENGTH_SHORT).show();
}
}.start();
}
thank you in advance.
In onFinish() also set the text to TextView like below
textView.setText("0");
I am making a repeating countdown timer app.I require the countdown timer to restart with a different time.I am using a global variable in the constructor of the countdown timer.But the problem is that it always restarts from the starting of the first given interval.
public void chance(final int tota, final int cur, final int exercise,int pass,int flag)
{
Log.i("inside value","reached");
a = new CountDownTimer((tempmilliseconds) * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
tempmilliseconds = (int) millisUntilFinished / 1000;
Log.i("inside value",Integer.toString(tempmilliseconds));
updatetimer(millisUntilFinished);
}
#Override
public void onFinish() {
mtext.setText("0:00");
cancel();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
currentcompleted++;
if (on == 0) {
on = 1;
int exercis = MainActivity.restmint * 60 + MainActivity.restsec;
tempmilliseconds=exercis;
chance(tota, curr + 1, exercis, 0, 0);
} else {
on = 0;
int exercis = MainActivity.exermint * 60 + MainActivity.exersec;
tempmilliseconds=exercis;
chance(tota, curr + 1, exercis, 0, 0);
}
}
}, 1000);
}
};
a.start();
}
Below is the code for resume operations:
public void resume(View view) {
Button mytext=(Button) findViewById(R.id.resume);
if( mytext.getText().toString()=="Pause") {
mytext.setText("Play");
a.cancel();
}
else {
mytext.setText("Pause");
Log.i("Value of temp",Integer.toString(tempmilliseconds));
a.start();
}
}
The timer is stopping but when started in the resume function restarts with the original time and not specified by tempmilliseconds.Note tempmilliseconds is updated every seconds.
Any help/snippets/suggestions is appreciated.Thank you!
A CountDownTimer will not allow itself to be disturbed in any case. It will remember the time it was born with till someone kills it.
If you look at its documentation you'd see that it directly inherits from Object class and has only four methods: start(), cancel(), onFinish() (abstract) and onTick() (abstract). Thats pretty much it. So, you basically are left with no choice but to call cancel() and then re-initialise the timer. Or, you can extend the CountDownTimer class and encapsulate this under the hood.
In either case the cost of cancelling ad re-initialising may get tedious.
For a simple Timer App I try to add a TextView to my app that says something like "15 seconds remaining", obviously this changes every seccond until it finally changes to "time up!". My idea was to use a loop like this:
while(now<endTime):
remaining=endTime-now;
text.setText(remaining);
While this could work, I am unsure if this is the right approach or if theres a better option.
You can use a handler to do it as below:
Handler myHandler=new Handler();
myHandler.postDelayed(timer, 1000);
private Runnable timer= new Runnable() {
public void run() {
if(counter==15){
textview.setText("Time Up");
counter=0;
}
else{
counter++;
textview.setText(counter+ " remaining");}
}
};
Use a CountDownTimer, instead.
I use this code snippet to achive a similar result:
final int secs = 5;
new CountDownTimer((secs +1) * 1000, 1000) // Wait 5 secs, tick every 1 sec
{
#Override
public final void onTick(final long millisUntilFinished)
{
txtCount.setText("" + (int) (millisUntilFinished * .001f));
}
#Override
public final void onFinish()
{
txtCount.setText("GO!");
}
}.start();
In the onFinish() handler you can do the "elapsed time" stuff
I'm trying to pass the countdowntimer a variable and use that variable as the amount of milliseconds to count down. If I simply enter the value the countdown works properly, but if I pass it a long variable it just runs the onFinish function.
Here's the actual code:
public CountDownTimer countDown = new CountDownTimer(respawnTime, 1000) {
#Override
public void onTick(long millisUntilFinished) {
timer =(Integer)(int) millisUntilFinished / 1000;
if(timer < 31)
timerText.setTextColor(Color.parseColor("#FF0000"));
timerText.setText(timer.toString());
}
#Override
public void onFinish() {
timerText.setTextColor(Color.parseColor("#00FF00"));
timerText.setText("UP");
}
};
At this point I have respawnTime set to equal 360000 hoping for a 360 second countdown, but like I said it just immediately runs the onFinish. Simply changing the first parameter to a literal instead of a variable fixes everything but I need to use a variable here. Thanks in advance for the help!
Change
#Override
public void onTick(long millisUntilFinished) {
to
#Override
public void onTick(long respawnTime) {
use the variable you are sending in the constructor in onTick().
Edit
Here is one of mine
private class MyCountDown extends CountDownTimer
{
long duration, interval;
public MyCountDown(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
// TODO Auto-generated constructor stub
duration = millisInFuture;
interval = countDownInterval;
start();
}
#Override
public void onFinish() {
secs = 10;
Intent intent = new Intent(CalibrationTimeoutScreen.this, CalibrationTakeTempScreen.class);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
CalibrationTimeoutScreen.this.finish();
}
#Override
public void onTick(long duration) {
cd.setText(String.valueOf(secs));
secs = secs - 1;
}
}
You did not run start(). Simply add .start() after the last '}' or add a new line calling countDown.start().