I am trying to add numbers to an already existing number based on a formula when a CountDownTimer is running. The timer is working, but the number(amount) crashes the app
public class Main extends AppCompatActivity {
TextView Time;
ImageButton button;
TextView amount;
TextView rate, milltime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Time = findViewById(R.id.Time);
button = findViewById(R.id.button);
amount = findViewById(R.id.Amount);
rate = findViewById(R.id.Ratenumber);
milltime = findViewById(R.id.milltime);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new CountDownTimer(10000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
NumberFormat f = new DecimalFormat("00");
long hour = (millisUntilFinished / 3600000) % 24;
long min = (millisUntilFinished / 60000) % 60;
long sec = (millisUntilFinished / 1000) % 60;
Time.setText(f.format(hour) + ":" + f.format(min) + ":" + f.format(sec));
}
#Override
public void onFinish() {
Time.setText("Click to start");
}
}.start();
new CountDownTimer(10000,1){
#Override
public void onTick(long millisUntilFinished) {
milltime.setText(""+millisUntilFinished /1000 + millisUntilFinished %1000);
}
#Override
public void onFinish() {
milltime.setText("Did it work?");
}
}.start();
int n1 = Integer.parseInt(milltime.getText().toString());
int n2 = Integer.parseInt(rate.getText().toString());
int n3 = (1000 - n1) * n2;
amount.setText(""+String.valueOf(n3));
}
});
}
What I am trying to get, is the amount to increase as the timer runs based on the rate.
without the xml I'm only assuming here
First of all, the calculation code is on the button click and out of the counter scope your crash might be because of the Integer parsing
where your milltime and rate could be empty and that's what making it crash due to NumberFormatException
Related
I am trying to create a countDownTimer but, whenever I click on the button the app crashes.
I want that if I click on player1 button player2 countdown should pause and vice versa for player2.
The Error I am getting:
Attempt to invoke virtual method 'void
android.os.CountDownTimer.cancel()' on a null object reference
Here is the Code
public class Timer extends AppCompatActivity {
Button player1, player2;
long incrementTime = 3000;
int time;
long timeinLong;
ImageButton pause;
CountDownTimer player1count, player2count;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
player1 = findViewById(R.id.player1);
player2 = findViewById(R.id.player2);
Intent intent = getIntent();
time = intent.getIntExtra("time", 0);
timeinLong = time * 60000;
int minutes = (int) (timeinLong / 1000) / 60;
int seconds = (int) (timeinLong / 1000) % 60;
String timeFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
player1.setText(timeFormatted);
player1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startCountDown(player1);
player2count.cancel();
}
});
player2.setText(timeFormatted);
player2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startCountDown2(player2);
player1count.cancel();
}
});
}
private void startCountDown(final Button button) {
player1count = new CountDownTimer(timeinLong, 1000) {
#Override
public void onTick(long millisUntilFinished) {
timeinLong = millisUntilFinished;
updateCountDownText(button);
}
#Override
public void onFinish() {
timeinLong = 0;
updateCountDownText(button);
}
}.start();
}
private void startCountDown2(final Button button) {
player2count = new CountDownTimer(timeinLong, 1000) {
#Override
public void onTick(long millisUntilFinished) {
timeinLong = millisUntilFinished;
updateCountDownText(button);
}
#Override
public void onFinish() {
timeinLong = 0;
updateCountDownText(button);
}
}.start();
}
private void updateCountDownText(Button button) {
int minutes = (int) (timeinLong / 1000) / 60;
int seconds = (int) (timeinLong / 1000) % 60;
String timeFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
button.setText(timeFormatted);
if (timeinLong < 30000) {
button.setTextColor(Color.RED);
} else {
button.setTextColor(Color.BLACK);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (player1count != null) {
player1count.cancel();
}
}
}
player2count only gets initialized inside startCountDown2, which is only called inside player2.setOnClickListener. Hence, if you click on the player1 button before ever clicking on player2 button, you'll get a NullPointerException, since calling player2count.cancel() on a not-yet-initialized player2count is not allowed. To prevent this from happening, it would be appropriate to just check for null in this case:
if (player2count != null) {
player2count.cancel();
}
Just don't cancel timers unless they're intialized, it will bring NPE, so check if they're not null in both players as below
player1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startCountDown(player1);
if (player2count != null)
player2count.cancel();
}
});
player2.setText(timeFormatted);
player2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startCountDown2(player2);
if (player1count != null)
player1count.cancel();
}
});
you don't initialize that when click listener called
i fixed it for myself by add try catch on .cancel lines
or set
if (player1count != null)
...
I want to build a 5 second timer that counts down to 0 in 1 second intervils and then resets to the initial value of 5 seconds. The timer needs to run continously. After looking at this thread,
Android - loop part of the code every 5 seconds
I used the CountDownTimer Class and called the start() method within the onFinish() method so that when the timer finished, it would reset to 5. It does run on a continous loop, however I notice that after the first loop, it either countsdown as 4-3-2-1-0 or 5-3-2-1-0.
Can somebody explain to me why this happens?
private long START_TIME_IN_MILLIS = 5000;
//set up our variables
private CountDownTimer timer;
private TextView textView;
private Button starttimer;
private long mTimeLeftInMillis = START_TIME_IN_MILLIS;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text_view_countdown);
starttimer = findViewById(R.id.button_start_pause);
//set onclik listener when touch imput button
starttimer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
beginTime();
}
});
}
//creating my own method
private void beginTime() {
timer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
start();
}
}.start();
}
private void updateCountDownText(){
int minutes= (int) (mTimeLeftInMillis / 1000)/ 60;
int seconds= (int) (mTimeLeftInMillis / 1000) % 60;
String timeLeftFormatted = String.format(Locale.getDefault(),"%02d:%02d", minutes, seconds);
textView.setText(timeLeftFormatted);
}
}
Try this
#Override
public void onFinish() {
mTimeLeftInMillis = START_TIME_IN_MILLIS;
}
I need a count up timer in my application. I browsed many forums about this subject, but I could not find anything. Actually I understood we can do this with chronometer, but I have 2 problem with chronometer:
I cannot using chronometer in Service because chronometer needs a layout.
I cannot initialize chronometer to count more than 1 hour.
My code is here:
stopWatch = new Chronometer (MainActivity.this);
startTime = SystemClock.elapsedRealtime();
stopWatch.start();
stopWatch.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer arg0) {
countUp = (SystemClock.elapsedRealtime() - arg0.getBase()) / 1000;
String asText = (countUp / 60) + ":" + (countUp % 60);
Log.i("t", asText);
}
});
You can use a countDownTimer in reverse and get the time elapsed.
long totalSeconds = 30;
long intervalSeconds = 1;
CountDownTimer timer = new CountDownTimer(totalSeconds * 1000, intervalSeconds * 1000) {
public void onTick(long millisUntilFinished) {
Log.d("seconds elapsed: " , (totalSeconds * 1000 - millisUntilFinished) / 1000);
}
public void onFinish() {
Log.d( "done!", "Time's up!");
}
};
To start the timer.
timer.start();
To stop the timer.
timer.cancel();
The sec,min and hr increments everytime the values hit 59,59,23 respectively. Each values are displayed in different views creating a digital stopwatch.
checkin.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(final View view) {
checkin.setEnabled(false);
new CountDownTimer(300000000, 1000){
public void onTick(long millisUntilFinished){
sec++;
if(sec==59) {
min++;
sec=0;
}
if(min==59){
min=0;
hr++;
}
if(hr==23){
hr=00;
}
secView.setText(String.valueOf(sec));
minView.setText(String.valueOf(min));
hrView.setText(String.valueOf(hr));
}
public void onFinish(){
Snackbar.make(view, "Finish", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}.start();
}
});
Using RxJava, you can write
Disposable var = Observable
.interval(1, TimeUnit.SECONDS)
.subscribe(
time -> {
long minutes = time / 60;
long second = time % 60;
timer.setText("" + minutes + ":" + second);
});
you can stop the timer by using
var.dispose()
You can use this code to do so:
https://gist.github.com/MiguelLavigne/8809180c5b8fe2fc7403
/**
* Simple timer class which count up until stopped.
* Inspired by {#link android.os.CountDownTimer}
*/
public abstract class CountUpTimer {
private final long interval;
private long base;
public CountUpTimer(long interval) {
this.interval = interval;
}
public void start() {
base = SystemClock.elapsedRealtime();
handler.sendMessage(handler.obtainMessage(MSG));
}
public void stop() {
handler.removeMessages(MSG);
}
public void reset() {
synchronized (this) {
base = SystemClock.elapsedRealtime();
}
}
abstract public void onTick(long elapsedTime);
private static final int MSG = 1;
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
synchronized (CountUpTimer.this) {
long elapsedTime = SystemClock.elapsedRealtime() - base;
onTick(elapsedTime);
sendMessageDelayed(obtainMessage(MSG), interval);
}
}
};
}
i am trying to implement a countdown timer that starts from the number that the user inputs in the EditText. When i am running my program with the emulator, i realise that something goes wrong inside the countdown timer block since it does not enter inside this block.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText countDownTxt = (EditText) findViewById(R.id.editText2);
final EditText intervalTxt = (EditText) findViewById(R.id.editText1);
findViewById(R.id.button1).setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
int interval = Integer.parseInt(intervalTxt.getText().toString());
Log.d("buttonpressed", "interval countdown equals " + interval);
new CountDownTimer(Integer.parseInt(intervalTxt.getText().toString()), 1000) {
public void onTick(final long millisUntilFinished) {
Log.d("counttimer1", "enter");
runOnUiThread(new Runnable() {
#Override
public void run() {
countDownTxt.setText("" + millisUntilFinished / 1000);
}
});
countDownTxt.setText(""+ millisUntilFinished / 1000);
}
public void onFinish() {
countDownTxt.setText("done!");
}
}.start();
}
}
);
Any suggestions on solving this problemt ?
try using this
long timeVal = Long.parseLong(intervalTxt.getText().toString());
new CountDownTimer(timeVal, 1000) {
}
If you want the entered number by user present seconds, you should have like:
int time = Integer.parseInt(intervalTxt.getText().toString()) * 1000;
new CountDownTimer(time, 1000) {
...
I have gone through the link http://dewful.com/?tag=basic-android-timer regarding the timer application in android. It is working fine. I need to add the pause button to stop the timer and a play button to start the timer again from where I stopped. Can I achieve that task?
My Code:
long timervalue = 50000;
CountDownTimer Counter1 = new CountDownTimer(timervalue, 1000)
{
public void onTick(final long millisUntilFinished)
{
time.setText(formatTime(millisUntilFinished));
pause.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Counter1.cancel();
}
}
);
resume.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Counter1.start();
timervalue = Long.parseLong(output);
System.out.println("paused timer value resumed"+timervalue);
Counter1.onTick(timervalue);
}
}
);
}
public void onFinish()
{
Counter1.cancel();
}
};
public String formatTime(long millis)
{
output = "00";
seconds = millis / 1000;
seconds = seconds % 60;
System.out.println("seconds here"+seconds);
String secondsD = String.valueOf(seconds);
System.out.println("secondsD here"+secondsD);
if (seconds <
10) secondsD = "0" + seconds;
System.out.println("secondsD here in if"+secondsD);
output = secondsD;
return output;
}
In the above code when resume button is clicked the timer is again starting from 50sec and I don't want like that. It should start from the time where I paused. Please help me regarding this...I am struggling for this since one week......
Will be really thankful for the help..........
public class TimerActivity extends Activity
{
EditText e1;
MyCount counter;
Long s1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
e1=(EditText)findViewById(R.id.editText1);
counter= new MyCount(5000,1000);
counter.start();
}
public void asdf(View v)
{
switch(v.getId())
{
case R.id.button1: counter.cancel();
break;
case R.id.button2: counter= new MyCount(s1,1000);
counter.start();
}
}
public class MyCount extends CountDownTimer
{
public MyCount(long millisInFuture, long countDownInterval)
{
super(millisInFuture, countDownInterval);
}
#Override public void onFinish()
{
e1.setText("DONE");
}
#Override public void onTick(long millisUntilFinished)
{
s1=millisUntilFinished;
e1.setText("left:"+millisUntilFinished/1000);
}
}
}
public void time(long m){
timer=new CountDownTimer(m, 1000) {
public void onTick(long millisUntilFinished) {
tv_timer.setText(formatTime(millisUntilFinished));
}
public void onFinish() {
tv_timer.setText("done!");
}
}.start();
}
i have used this for timer and i have put button for pause and use this
case R.id.bT_PAUSE:
String s_time = null;
try{
if(Bt_pause.getText().equals("PAUSE")){
s_time=tv_timer.getText().toString();
timer.cancel();
String[] Pause_time=s_time.split(":");
m=Long.parseLong(Pause_time[0].trim());
n=Long.parseLong(Pause_time[1].trim());
m=(m*60)+n;
m=m*1000;
Bt_pause.setText("RESUME");
}else if(Bt_pause.getText().equals("RESUME")){
//min_longmillis=Long.parseLong(sss);
//min_longmillis=min_longmillis*1000*60;
//min_longmillis=m;
//timer.start();
Toast.makeText(this,String.valueOf(m),Toast.LENGTH_SHORT).show();
time(m);
Bt_pause.setText("PAUSE");
}
}catch(Exception e){
Toast.makeText(this,e.toString(),Toast.LENGTH_SHORT).show();
}
break;
and this for format time
public String formatTime(long millis) {
String output = "00:00";
long seconds = millis / 1000;
long minutes = seconds / 60;
seconds = seconds % 60;
minutes = minutes % 60;
String sec = String.valueOf(seconds);
String min = String.valueOf(minutes);
if (seconds < 10)
sec = "0" + seconds;
if (minutes < 10)
min= "0" + minutes;
output = min + " : " + sec;
return output;
}//formatTime