I'm a begginer in android programming and trying to improve my knowledge. I want to make an app that is a regressive chronometer, like this: I insert the seconds I want in a text view named "seconds", then press a button and the app counts down the seconds (for example: 50, 49, 48, ..., 0) in another text view called, let's say... "timeRemaining".
How this can be done? I have read some other questions here, but to be honest, I could not understand them...
Well, I managed to do something here, The countdown is working, but only if I set the time directly on the code. I cannot find a way to implement the conversion of the number (text) entered in the text view to LONG and then use this value as the time to countdown.
There is no error when debugging, but when the simulator is about to run the app and opens the activity, it stop with the message "Unfortunately, app has stopped"
Here's the code, if anyone can help me finding what I'm missing, I'll be glad!
Thank you all!
public class cronometro extends Activity implements View.OnClickListener {
Long tempo3 = Long.parseLong(findViewById(R.id.tempo).toString());
private CountDownTimer countDownTimer;
private boolean timerStarted = false;
private Button buttonStart;
public TextView textView;
private final long startTime = tempo3 * 1000;
private final long interval = 1 * 1000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cronometro);
buttonStart = (Button) this.findViewById(R.id.button);
buttonStart.setOnClickListener(this);
textView = (TextView) this.findViewById(R.id.textView);
countDownTimer = new CountDownTimerActivity(startTime, interval);
textView.setText(textView.getText() + String.valueOf(startTime/1000));
}
#Override
public void onClick(View v) {
if (!timerStarted) {
countDownTimer.start();
timerStarted = true;
buttonStart.setText("PARAR");
} else {
countDownTimer.cancel();
timerStarted = false;
buttonStart.setText("REINICIAR");
}
}
public class CountDownTimerActivity extends CountDownTimer {
public CountDownTimerActivity(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
textView.setText("tempo esgotado!");
}
#Override
public void onTick(long millisUntilFinished) {
textView.setText("" + millisUntilFinished/1000);
}
}
}
Related
I have found numerous examples of how to pause a countdowntimer in Android, but each of these examples utilises more than 1 button (pause, resume and cancel).
I want to have one button that when I press it the timer starts, then when I press it again it pauses (cancelling the original timer, capturing the timer value) and resumes when clicked again (taking the captured time from the pause to start off a new counterdowntimer).
Does anyone have an example of how to achieve this? I have tried if else loops in the onClick listener of the button. I have a very crude semi-working example;
if (gameOn == 1) {
if((clkOnTimerBtn % 2)==0) {
isPaused = true; // PAUSE COUNTDOWN TIMER
resumeCountDownTimer(view, "pause");
} else { // RESUME COUNTDOWN TIMER
resumeCountDownTimer(view, "resume");
}
The problem with the above is that this is carried out in the button onclick listener, so if a new CountDownTimer is created inside my resumeCountDownTimer its not possible to access the timer later on to cancel it (pause). I have also tried looking for a way to cancel all countdowntimers, messy if I could, but I couldn't find any examples or references to doing so as this would at least get the desired behaviour even if it isn't the most elegant way.
If I understood you correctly, something like this should work.
public class MainActivity extends AppCompatActivity {
CountDownTimer countDownTimer;
long duration = 100000; //This is the initial time,
long millisecondsLeft = 100000; // This is the time left. At the start it equales the duration.
boolean isCountDownTimerActive = false;
Button startButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.startStop);
final TextView timeLeft = (TextView) findViewById(R.id.timeLeft);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isCountDownTimerActive) {
if (countDownTimer != null)
countDownTimer.cancel();
isCountDownTimerActive = false;
} else {
countDownTimer = new CountDownTimer(millisecondsLeft, 1000) {
#Override
public void onTick(long l) {
millisecondsLeft = l;
timeLeft.setText(" " + l);
}
#Override
public void onFinish() {
}
};
isCountDownTimerActive = true;
countDownTimer.start();
}
}
});
}
}
I'm trying to do some example about countdown timer using Button and set OnclickListener for that Button. My Default value is 10 and it will be decrease each second, how can i reset my value back to 10?
CountDownTimer cannot be restarted, it can only be used once. You either have to create your own count down class that can handle being restarted, or just create a new instance of your CountDownTimer and cancel the old instance.
See the example code below where we have a CountDownTimer that counts down for 10 seconds in 1 second intervals, a Button that resets the timer when clicked (by cancelling the current timer and starting a new one), and a TextView that displays the time left in the current timer.
public class YourActivity extends Activity {
private CountDownTimer countDownTimer;
private TextView timerDisplayTextView;
private static final long TEN_SECONDS = TimeUnit.SECONDS.toMillis(10);
private static final long COUNTDOWN_INTERVAL = TimeUnit.SECONDS.toMillis(1);
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Button myButton; // initialized here
// timerDisplayTextView initialized here
myButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
countDownTimer.cancel();
countDownTimer = getNewCountDownTimer(TEN_SECONDS);
countDownTimer.start();
showTimeInTextView(TEN_SECONDS);
}
});
countDownTimer = getNewCountDownTimer(TEN_SECONDS);
countDownTimer.start();
}
#Override
protected void onDestroy() {
super.onDestroy();
countDownTimer.cancel();
}
private void showTimeInTextView(long millisecondsLeft) {
timerDisplayTextView.setText(TimeUnit.MILLISECONDS.toSeconds(millisecondsLeft) + " seconds left");
}
private CountDownTimer getNewCountDownTimer(long length) {
return new CountDownTimer(length, COUNTDOWN_INTERVAL) {
#Override
public void onTick(long millisUntilFinished) {
showTimeInTextView(millisUntilFinished);
}
#Override
public void onFinish() {
}
};
}
}
I've recently started working on my first application for android, and I'm a bit stuck. My application uses the CountDownTimer class, which, it seems, malfuncions - CountDownTimer.cancel() doesn't work. I do know how to fix this by modifying the CountDownTimer.java file, but I don't have the permission to do so. I'm working in Android Studio. I couldn't find an explanation online, even though it seems quite a fundamental question, isn't it? Perhaps I'm not using the right terms?
Thank you very much for your help, and I apologize if my question's a bit ignorant haha.
Try this way :
public class Main extends Activity implements OnClickListener
{
private static final String tag = "Main";
private MalibuCountDownTimer countDownTimer;
private long timeElapsed;
private boolean timerHasStarted = false;
private Button startB;
private TextView text;
private TextView timeElapsedView;
private final long startTime = 50000;
private final long interval = 1000;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startB = (Button) this.findViewById(R.id.button);
startB.setOnClickListener(this);
text = (TextView) this.findViewById(R.id.timer);
timeElapsedView = (TextView) this.findViewById(R.id.timeElapsed);
countDownTimer = new MalibuCountDownTimer(startTime, interval);
text.setText(text.getText() + String.valueOf(startTime));
}
#Override
public void onClick(View v)
{
if (!timerHasStarted)
{
countDownTimer.start();
timerHasStarted = true;
startB.setText("Start");
}
else
{
countDownTimer.cancel();
timerHasStarted = false;
startB.setText("RESET");
}
}
// CountDownTimer class
public class MalibuCountDownTimer extends CountDownTimer
{
public MalibuCountDownTimer(long startTime, long interval)
{
super(startTime, interval);
}
#Override
public void onFinish()
{
text.setText("Time's up!");
timeElapsedView.setText("Time Elapsed: " + String.valueOf(startTime));
}
#Override
public void onTick(long millisUntilFinished)
{
text.setText("Time remain:" + millisUntilFinished);
timeElapsed = startTime - millisUntilFinished;
timeElapsedView.setText("Time Elapsed: " + String.valueOf(timeElapsed));
}
}
}
I have a working countdown, but it only counts down from a hard coded integer that I put in. I want the user to be able to type in a number and have it count down from that number instead. I want the text put into "timeedit" to be put into a string and put to the value of "startTime".
EDIT: If the code below is not indented correctly on your screen, you can also view the code here: http://pastebin.com/BnzEtFX5
Code:
public class TimerActivity extends Activity implements OnClickListener {
private CountDownTimer countDownTimer;
private boolean timerHasStarted = false;
private Button startB;
public TextView text;
public String time;
private long startTime = 30 * 1000;
private final long interval = 1 * 1000;
private EditText timeedit;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_countdown);
startB = (Button) this.findViewById(R.id.button);
startB.setOnClickListener(this);
text = (TextView) this.findViewById(R.id.timer);
timeedit = (EditText) findViewById(R.id.timeedit);
countDownTimer = new MyCountDownTimer(startTime, interval);
time = timeedit.getText().toString();
text.setText(time); //+ String.valueOf(startTime/1000)
}
#Override
public void onClick(View v) {
if (!timerHasStarted) {
countDownTimer.start();
timerHasStarted = true;
startB.setText("STOP");
} else {
countDownTimer.cancel();
timerHasStarted = false;
startTime = 30 * 1000;
startB.setText("RESTART");
}
}
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
text.setText("Time's up!");
}
#Override
public void onTick(long millisUntilFinished) {
text.setText("" + millisUntilFinished / 1000);
}
}
}
Ummm...I'm not sure what the problem is but if I understand you correctly, you just need to do something like this in onCreate()
String userTime = timeedit.getText().toString();
startTime = Long.parseLong(userTime);
Edit
you will actually want to put startTime and userTime in your onClick. If it is in onCreate() then your EditText will be empty unless you put a default value in your xml but either way it won't be what the user has entered. You also need to surround with a try/catch in case the user enters something other than numeric characters.
public void onClick(View v) {
String userTime = timeedit.getText().toString();
long startTime = Long.parseLong(userTime);
if (!timerHasStarted) {
countDownTimer.start();
timerHasStarted = true;
startB.setText("STOP")
If You want to let user do some input, you simply have to get this with:
String userCountDown = timeEdit.getText().toString();
then parse it into Long:
long userStartTime = Long.parseLong(userCountDown);
and then, pass it to the countDown
countDownTimer = new MyCountDownTimer(UserStartTime, interval);
But You have to be sure that the value inside your timeEdit is an Long value. By setting the attribute inputType="number" inside Your layout.xml file to the R.id.timeedit, you can get sure to get an Long. But to be very sure that there is an input, You can do any check and show a warning for the user.
if (!timerHasStarted) {
String userCountDown = timeEdit.getText().toString();
if(userCountDown.length()<1){
Toast.makeText(yourActivity.this,"PLEASE DO SOME INPUT",Toast.LENGTH_LONG).show();
}else{
long userStartTime = Long.parseLong(userCountDown);
countDownTimer = new MyCountDownTimer(userStartTime, interval);
countDownTimer.start();
timerHasStarted = true;
startB.setText("STOP");
}
} else {
countDownTimer.cancel();
timerHasStarted = false;
startTime = 30*1000;
startB.setText("RESTART");
}
So I'm trying to write a stopwatch app that displays time in milliseconds, but for some reason it won't work. Basically I have just a togglebutton that, after being pressed, starts printing the milliseconds from the start time to the current time... In the simulator though, the app locks up. What's wrong?
public class testing extends Activity {
/** Called when the activity is first created. */
Button start,stop;
long init,now,time;
TextView display;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
display = (TextView) findViewById(R.id.chronometer1);
final ToggleButton passTog = (ToggleButton) findViewById(R.id.onoff);
passTog.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
init=System.currentTimeMillis();
while(passTog.isChecked())
{
now=System.currentTimeMillis();
time=now-init;
display.setText("t: " + time);
}
}
});
}
}
You definitely should not run a busy loop like you are doing inside the OnClickListener. That's why the app locks up. You need to let the rest of the system have its say. Also, it doesn't make sense to update the display more than once every 30 milliseconds or so, since that's about the fastest that the human eye can track. Also, you might want to suspend your timer when the activity is paused. Here's a version that does all that:
public class testing extends Activity {
/** Called when the activity is first created. */
Button start,stop;
long init,now,time,paused;
TextView display;
Handler handler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler();
setContentView(R.layout.test);
display = (TextView) findViewById(R.id.chronometer1);
final ToggleButton passTog = (ToggleButton) findViewById(R.id.onoff);
final Runnable updater = new Runnable() {
#Override
public void run() {
if (passTog.isChecked()) {
now=System.currentTimeMillis();
time=now-init;
display.setText("t: " + time);
handler.postDelayed(this, 30);
}
}
};
passTog.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
init = System.currentTimeMillis();
handler.post(updater);
}
});
}
#Override
protected void onPause() {
super.onPause();
paused = System.currentTimeMillis();
}
#Override
protected void onResume() {
super.onResume();
init += System.currentTimeMillis() - paused;
}
}
You put the setText() method in your onClick(), so will you click the button every second?
Its not even a thread!
Try the onTick() method of CountDownTimer class instead.