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
Related
I am learning android. I made this stopwatch app work from my reference book.It only shows Hour:minutes:seconds but I want to add milliseconds right to the seconds.how do I do that.
code::-
public class StopWatchActivity extends AppCompatActivity {
int seconds;
boolean running;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stop_watch);
runTimer();
}
public void startTimer(View view){
running = true;
}
public void stopTimer(View view){
running = false;
}
public void resetTimer(View view){
running = true;
seconds = 0;
}
public void runTimer(){
final TextView textView = (TextView) findViewById(R.id.timer);
final Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
int hours = seconds / 3600;
int minutes = (seconds % 3600) / 60;
int sec = seconds % 60;
String time = String.format("%d:%02d:%02d", hours,
minutes,sec);
textView.setText(time);
if(running) {
seconds++;
}
handler.postDelayed(this, 1000);
}
});
}
}
The first step would be to change the field seconds to milliSeconds because you want to keep track of that TimeUnit.
When restarting your handler with handler.postDelayed(this, 1000); define 1 millisecond as delay instead of 1000 (= 1 Second) like this handler.postDelayed(this, 1); then you just need to adjust your calculations and you are done :-)
An easier solution would be:
Instead of saving the elapsed seconds in your activity, save the time that the timer started (e.g. startTime)
Then, in your handler's runnable, get the current time and subtract the start time to find the elapsed time.
Pseudocode:
long startTimeNanos
public void runTimer() {
startTime = new Date()
final Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
long currentTime = System.nanoTime()
long elapsedNanos = currentTime - startTimeNanos
// calculate seconds and millis
// and set the textview text
handler.postDelayed(this, 1000);
}
});
}
This way, you can change the time that the handler fires and it won't affect anything else.
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.
I am making a login screen for an android app. If a user enter wrong password credential 3 times, then the edit text field will be disable for 30 second. After 30 seconds, user can input their password again. How can i achieve it? Thank you
you can try
//Disable your EditText
Handler handlerTimer = new Handler();
handlerTimer.postDelayed(new Runnable(){
public void run() {
// Enable it
}}, 30000);
But I think it's not a good solution to block an edit text 30 seconds, why would you do that?
I hope that help you.
int start1=18000;
final Timer timer = new Timer();
new Thread(new Runnable() {
#Override
public void run() {
timer.schedule(new TimerTask() {
#Override
public void run() {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
if (start1 <= 0) {
timer.cancel();
timer.purge();
editTextActivation.setEnabled(true);
}
start1 = start1 - 1000;
}
});
}
}, 0, 1000);
}
}).start();
Well first you'll have to have a counter that increments every time a wrong password is submitted. A simple int field would do the trick:
int passwordAttempt = 0;
Next, you'll have to increment this "counter" when a user has entered a wrong password. If the counter reaches 3, disable your EditText (and re-enable it after 30 seconds):
if(passwordAttempt == 3) {
// User has entered wrong password 3 times.
// Disable your EditText.
yourEditText.setEnabled(false);
// Re-enable your EditText after 30000 milliseconds (30 seconds).
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
yourEditText.setEnabled(true);
}
}, 30 * 1000);
// Reset the counter.
passwordAttempt = 0;
}
Try this out...
Thanks to #ridsatrio, I have UPDATED the code.
editText.setEnabled(false);
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setVisibility(View.GONE);
editText.setEnabled(true);
}
}.start();
Sorry for my English! :)
Ok, I want to repeat something multiple times every second - like here:
//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);
Now, inside it I want to generate random number between 1-3 (including) and do something if it is 3.
So:
//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Random rand = new Random();
int num = rand.nextInt(3)+1;
if(num==3){
// repeat action here.
}
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);
And inside the if statement, I want to repeat other action (moving ImageView every 5 milliseconds or something like this). How can I do it? Thank you.
You can use either a CountDownTimer
http://developer.android.com/reference/android/os/CountDownTimer.html
e.g. create a CountDownTimer for 30secs (30000ms) and notify each second (1000ms)
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
//I get called every 1000ms
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
or just a Handler.
http://developer.android.com/reference/android/os/Handler.html
final Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
//dostuff
handler.postDelayed(this,1000); //repeat after a second
}
});
For animations you should have a look at ObjectAnimator/ViewPropertyAnimation.
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