This is my first question but as a learner, I read often to find solutions to problems.
So, I am following a tutorial on Android using Java. The challenge is creating a Timer to cook an egg.
I was able to manage everything so far:
- created a seekBar
to set the time;
- moving the seekBar
edit the TextView to show the timer;
- created a button to start and stop the timer (button change when pressed from start to stop and another way round)
.
Now I realize that I have a little bug. If I open the app, scrub the SeekBar and then press the button, everything works. If I press the button as soon the app is open, crash.
Here the error messages:
01-27 14:50:41.011 20206-20206/com.example.yuri.eggtimer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.yuri.eggtimer, PID: 20206
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.CountDownTimer android.os.CountDownTimer.start()' on a null object reference
at com.example.yuri.eggtimer.MainActivity$override.startTimer(MainActivity.java:26)
at com.example.yuri.eggtimer.MainActivity$override.access$dispatch(Unknown Source:95)
at com.example.yuri.eggtimer.MainActivity.startTimer(MainActivity.java:0)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Here the code:
public class MainActivity extends AppCompatActivity {
//Button startStop = findViewById(R.id.startButton);
//Creating a countDownTimer variable
CountDownTimer count;
// Creating a boolean variable to check if the timer is running.
boolean isRunning = false;
//Button method for start and stop
public void startTimer(View view) {
Log.i("info","Button pressed");
if (!isRunning){
final Button startStop = findViewById(R.id.startButton);
count.start();
startStop.setText("Stop");
isRunning = true;
}else{
final Button startStop = findViewById(R.id.startButton);
count.cancel();
startStop.setText("Start");
isRunning = false;
}
}
public void updateClock(int progress){
int time=progress/1000;
int minutes = Math.round(time/60);
int seconds = time%60;
TextView clock = findViewById(R.id.clockTextView);
clock.setText(minutes+":"+seconds);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Setting variable for max time and starting time
int max = 300;
final int[] startingPosition = {30};
//Calling the seekbar and setting the max and starting point
SeekBar timer = findViewById(R.id.eggSeekBar);
timer.setMax(max*1000);
timer.setProgress(startingPosition[0] *1000);
//creating Long type for countDownTimer
final Long[] timerProgress = {new Long(timer.getProgress())};
//set the starting clock
updateClock(startingPosition[0]*1000);
timer.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
timerProgress[0] = Long.valueOf(progress);
updateClock(progress);
count = new CountDownTimer(timerProgress[0],1000){
public void onTick(long secondLeft){
Long seconds = secondLeft;
int sec = seconds.intValue();
updateClock(sec);
Log.i("Second left", String.valueOf(secondLeft/1000));
}
public void onFinish(){
Log.i("Info","We are done!");
}
};
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
I tried the button only with a log, and there is no problem. I noticed that the problem is when I want to start the countdown (in my case called count).
If in the method starttimer
I just put count.start(), if I click as soon the app starts it to crash. So I got that the problem should be somewhere in the countdown, but I do not understand why it works if I scrub the seekBar
first.
Thanks, everyone will take the time to read and/or answer this.