Hello so I have a App about a fact and tip each 24 hours it displays a fact or tip!
I am pretty new to Android studio anyways to keep track of the fact and tip the user is in I used a variabe "timing" in the start timer i put when the mTimeLeftInMillis == 0 then make timing = 1 and if timing == 1 then do that but ya for that it's not the case!
when the user leaves the timing variable resets and goes back to 124!
Could someone please help me! I tried to do shared perferences in it but It didn't work!
here is my java code!
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private static final long START_TIME_IN_MILLIS = 30000;
Button tip;
TextView texttip;
TextView textfact;
Button next;
Button back;
private TextView mTextViewCountDown;
private Button mButtonStartPause;
private Button mButtonStart;
private CountDownTimer mCountDownTimer;
private boolean mTimerRunning;
private long mTimeLeftInMillis;
private long mEndTime;
private long timing = 124;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextViewCountDown = findViewById(R.id.text_view_countdown);
mButtonStartPause = findViewById(R.id.button_start_pause);
next = (Button)findViewById(R.id.next);
next.setOnClickListener(this);
back = (Button)findViewById(R.id.back);
back.setOnClickListener(this);
mButtonStart = findViewById(R.id.tip);
tip = (Button) findViewById(R.id.tip);
texttip = (TextView)findViewById(R.id.texttip);
textfact = (TextView)findViewById(R.id.textfact);
mButtonStartPause.setOnClickListener((new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mTimerRunning) {
mButtonStartPause.setText("fact ");
} else {
startTimer();
}
}
}));
mButtonStart.setOnClickListener((new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mTimerRunning) {
mButtonStart.setText("Tip");
} else {
startTimer();
}
}
}));
}
#Override
public void onClick(View view) {
if(view.getId() == R.id.next){
tip.setVisibility(view.INVISIBLE);
mButtonStartPause.setVisibility(View.INVISIBLE);
mButtonStart.setVisibility(View.INVISIBLE);
textfact.setVisibility(View.INVISIBLE);
texttip.setVisibility(View.INVISIBLE);
mTextViewCountDown.setVisibility(View.INVISIBLE);
next.setVisibility(View.INVISIBLE);
back.setVisibility(View.VISIBLE);
}
if (view.getId() == R.id.back){
tip.setVisibility(View.VISIBLE);
mButtonStart.setVisibility(View.VISIBLE);
mButtonStartPause.setVisibility(View.VISIBLE);
textfact.setVisibility(View.VISIBLE);
texttip.setVisibility(View.VISIBLE);
mTextViewCountDown.setVisibility(View.VISIBLE);
next.setVisibility(View.VISIBLE);
back.setVisibility(View.INVISIBLE);
}
}
private void startTimer() {
if (timing == 5) {
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
updateButtons();
textfact.setText("Makeup was invented by egypt");
texttip.setText("Spend time with a loved one");
} else{
mButtonStartPause.setText("fact ");
}
if (timing == 4) {
timing = 5;
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
updateButtons();
textfact.setText("The US flag was designed by a student");
texttip.setText("Its okay to make mistakes because you will learn from them");
} else{
mButtonStartPause.setText("fact ");
}
if (timing == 3) {
timing = 4;
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
updateButtons();
textfact.setText("DID YOU KNOW THAT SCOTLAND HAS 421 WORDS FOR SNOW!!!");
texttip.setText("Don't compare your self to others!");
} else{
mButtonStartPause.setText("fact ");
}
if (timing == 2) {
timing = 3;
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
updateButtons();
textfact.setText("There is no q in all 50 states of US!");
texttip.setText("Do what you live. The purpose of life is to be happy!");
} else{
mButtonStartPause.setText("fact ");
}
if (timing == 1) {
timing = 2;
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
updateButtons();
textfact.setText("The phillipines has about 7,641 islands!!");
texttip.setText("Develop good habits! Like running outside could benefit you and your mental health and your body by alot!");
} else{
mButtonStartPause.setText("fact ");
}
if (mTimeLeftInMillis == 0 && timing == 124) {
timing = 1;
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
updateButtons();
textfact.setText("Sudan has the most pyramids in the world");
texttip.setText("Look for knowledge not results");
textfact.setVisibility(View.VISIBLE);
texttip.setVisibility(View.VISIBLE);
} else{
mButtonStartPause.setText("fact ");
}
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning= false;
updateButtons();
}
}.start();
mTimerRunning = true;
updateButtons();
}
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);
mTextViewCountDown.setText(timeLeftFormatted);
}
private void updateButtons() {
if(mTimerRunning){
mButtonStartPause.setText("fact");
}else {
mButtonStartPause.setText("fact");
if (mTimeLeftInMillis < 1000) {
mButtonStartPause.setVisibility(View.VISIBLE);
} else {
mButtonStartPause.setVisibility(View.VISIBLE);
}
}
}
#Override
protected void onStop() {
super.onStop();
SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong("millisLeft", mTimeLeftInMillis);
editor.putBoolean("timerRunning", mTimerRunning);
editor.putLong("endTime", mEndTime);
editor.apply();
}
#Override
protected void onStart() {
super.onStart();
SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
mTimeLeftInMillis = prefs.getLong("millisLeft", START_TIME_IN_MILLIS);
mTimerRunning = prefs.getBoolean("timerRunning", false);
updateCountDownText();
updateButtons();
if (mTimerRunning) {
mEndTime = prefs.getLong("endTime", 0);
mTimeLeftInMillis = mEndTime - System.currentTimeMillis();
if (mTimeLeftInMillis < 0) {
mTimeLeftInMillis = 0;
mTimerRunning = false;
updateCountDownText();
updateButtons();
} else{
startTimer();
}
}
}
}
I tried making two timers and the other timer will save it because i know how to do shared preferences on timers but not on stuff like that but it didn't work also because errors started coming!
I wanted the timing thing to save.
Related
I write in Java music player for Android. It have a special function to trim a fragment of audio with range seekbar. After replay button is turned ON this fragment is looped. It works and selected fragment with range seekbar is played but not always as it would be necessary. Sometimes it gets out of max selected duration and goes to end of song.I can't find the place why this is happening...
Preview
Many thanks for any help and suggestions.
Here is the logic responsible for playing the song, that is activated when PLAY button is pressed:
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(mMediaPlayer != null){
if(mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
playButton.setText("PLAY");
timer.shutdown();
}else{
mMediaPlayer.start();
playButton.setText("PAUSE");
timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
playProgress();
if (mMediaPlayer != null) {
if (!mSeekBar.isPressed()) {
mSeekBar.setProgress(mMediaPlayer.getCurrentPosition());
}
}
}
},10,10, TimeUnit.MILLISECONDS);
}
}
}
});
A function that regulates the playback of a fragment in rangeSeekbar
private void playProgress () {
if (mMediaPlayer.getCurrentPosition() == max) {
if(isRepeat == true) {
mMediaPlayer.seekTo(min);
}else{
mMediaPlayer.seekTo(min);
mMediaPlayer.pause();
}
}
if (mMediaPlayer.isPlaying()) {
mRunnable = new Runnable() {
#Override
public void run() {
playProgress();
}
};
mHandler.postDelayed(mRunnable, 0);
}
}
The logic responsible for "creating" the player that will form when the song is opened:
public void createMediaPlayer(Uri uri){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mMediaPlayer.setDataSource(getApplicationContext(), uri);
mMediaPlayer.prepare();
title.setText(getNameFromUri(uri));
playButton.setEnabled(true);
mRangeSeekBar.setNotifyWhileDragging(true);
max = mMediaPlayer.getDuration();
mRangeSeekBar.setRangeValues(0, mMediaPlayer.getDuration());
mSeekBar.setMax(mMediaPlayer.getDuration());
long total_secs = TimeUnit.SECONDS.convert(max, TimeUnit.MILLISECONDS);
long mins = TimeUnit.MINUTES.convert(total_secs, TimeUnit.SECONDS);
long secs = total_secs - (mins*60);
duration = mins + ":" + secs;
elapse.setText("00:00 / " + duration);
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer();
}
});
} catch (IOException e){
title.setText(e.toString());
}
}
Replay function activated by the REPLAY button
replayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//repeat = false
if(isRepeat){
isRepeat = false;
mMediaPlayer.setLooping(false);
replayButton.setText("Powtórka wyłączona");
Toast.makeText(PlayerActivity.this, "Tryb powtórki jest wyłączony", Toast.LENGTH_SHORT).show();
}else{
isRepeat = true;
mMediaPlayer.setLooping(true);
replayButton.setText("Powtórka włączona");
Toast.makeText(PlayerActivity.this, "Tryb powtórki jest włączony", Toast.LENGTH_SHORT).show();
}
//mediaPlayer.setLooping(true);
// Toast.makeText(PlayerActivity.this, "Repeat if ON", Toast.LENGTH_SHORT).show();
}
});
Here is code for this double slider that is supposed to set the beginning and end:
mRangeSeekBar.setOnRangeSeekBarChangeListener(new RangeSeekBar.OnRangeSeekBarChangeListener<Integer>() {
#Override
public void onRangeSeekBarValuesChanged(RangeSeekBar<?> bar, Integer minValue, Integer maxValue) {
//mRangeSeekBar.setNotifyWhileDragging(true);
mMediaPlayer.seekTo(minValue);
max = maxValue;
min = minValue;
String infoMax = String.valueOf(max);
Log.i("MAX", infoMax);
}
});
And here for this green bar with one point representing the duration of the song:
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (mMediaPlayer != null){
int millis = mMediaPlayer.getCurrentPosition();
long total_secs = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
long mins = TimeUnit.MINUTES.convert(total_secs, TimeUnit.SECONDS);
long secs = total_secs - (mins*60);
elapse.setText(mins + ":" + secs + " / " + duration);
Hi I am making simple countdown timer and I would like to resume it after pause. Very important for me is that I won't put my countdown timer to public void method.
mTextViewCountDown = findViewById(R.id.text_view_countdown);
mButtonStartPause = findViewById(R.id.button_start_pause);
mButtonStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
updateCountDownText();
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
}
}.start();
}
private void startTimer() {
mTimerRunning = true;
mCountDownTimer.start();
}
private void pauseTimer() {
mCountDownTimer.cancel();
mTimerRunning = false;
mButtonStartPause.setText("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);
mTextViewCountDown.setText(timeLeftFormatted);
}
it is but you need to make a new instance of the timer and passing the current paused time
read the details here :
Pausing/stopping and starting/resuming Java TimerTask continuously?
I have some troubles with creating a way to send notifications foreground when the timer hits 00:00.
I mean, i want that when the timer ends, it sends a notification event if the app is closed.
I already found a way to show notifications and to make a timer who works even if the app is closed.
But when i put the function to send notification at the end of the timer it only works when the app is opened.
There is my MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notificationManager = NotificationManagerCompat.from(this);
mTextViewCountDown = findViewById(R.id.timerTv);
mButtonStartPause = findViewById(R.id.btn_start_pause);
mButtonReset = findViewById(R.id.btn_reset);
mButtonStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
mButtonReset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
resetTimer();
}
});
}
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimeLeftInMillis=0;
updateCountDownText();
mTimerRunning = false;
updateButtons();
Notification notification = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_money)
.setContentTitle("Test 1")
.setContentText("Important Message")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.build();
notificationManager.notify(1, notification);
}
}.start();
mTimerRunning = true;
updateButtons();
}
private void pauseTimer() {
mCountDownTimer.cancel();
mTimerRunning = false;
updateButtons();
}
private void resetTimer() {
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
updateButtons();
}
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);
mTextViewCountDown.setText(timeLeftFormatted);
}
private void updateButtons() {
if (mTimerRunning) {
mButtonReset.setVisibility(View.INVISIBLE);
mButtonStartPause.setText("Pause");
} else {
mButtonStartPause.setText("Start");
if (mTimeLeftInMillis < 1000) {
mButtonStartPause.setVisibility(View.INVISIBLE);
} else {
mButtonStartPause.setVisibility(View.VISIBLE);
}
if (mTimeLeftInMillis < START_TIME_IN_MILLIS) {
mButtonReset.setVisibility(View.VISIBLE);
} else {
mButtonReset.setVisibility(View.INVISIBLE);
}
}
}
#Override
public void onStop() {
super.onStop();
SharedPreferences prefs = getSharedPreferences("pref", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong("millisLeft", mTimeLeftInMillis);
editor.putBoolean("timerRunning", mTimerRunning);
editor.putLong("endTime", mEndTime);
editor.apply();
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
}
#Override
public void onStart() {
super.onStart();
SharedPreferences prefs = getSharedPreferences("pref", MODE_PRIVATE);
mTimeLeftInMillis = prefs.getLong("millisLeft", START_TIME_IN_MILLIS);
mTimerRunning = prefs.getBoolean("timerRunning", false);
updateCountDownText();
updateButtons();
if (mTimerRunning) {
mEndTime = prefs.getLong("endTime", 0);
mTimeLeftInMillis = mEndTime - System.currentTimeMillis();
if (mTimeLeftInMillis < 0) {
mTimeLeftInMillis = 0;
mTimerRunning = false;
updateCountDownText();
updateButtons();
} else {
startTimer();
}
}
}
}
App Java Class
public class App extends Application {
public static final String CHANNEL_1_ID = "channel1";
#Override
public void onCreate() {
super.onCreate();
createNotificationChannels();
}
private void createNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel1 = new NotificationChannel(
CHANNEL_1_ID,
"Channel 1",
NotificationManager.IMPORTANCE_HIGH
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel1);
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.krisix.notificationtest">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name=".App"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".ExampleService"/>
</application>
</manifest>
Thank you for your help !
Have a nice day
Krisix
Thank you for your help sorry i'm a beginner so i'm not sure i understand all the things you told me.
So do you mean something like this ?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notificationManager = NotificationManagerCompat.from(this);
mTextViewCountDown = findViewById(R.id.timerTv);
mButtonStartPause = findViewById(R.id.btn_start_pause);
mButtonReset = findViewById(R.id.btn_reset);
mButtonStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
mButtonReset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
resetTimer();
}
});
}
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimeLeftInMillis=0;
updateCountDownText();
mTimerRunning = false;
updateButtons();
if(mTimeLeftInMillis==0){
callNotification();
}
}
}.start();
mTimerRunning = true;
updateButtons();
}
private void pauseTimer() {
mCountDownTimer.cancel();
mTimerRunning = false;
updateButtons();
}
private void resetTimer() {
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
updateButtons();
}
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);
mTextViewCountDown.setText(timeLeftFormatted);
}
private void updateButtons() {
if (mTimerRunning) {
mButtonReset.setVisibility(View.INVISIBLE);
mButtonStartPause.setText("Pause");
} else {
mButtonStartPause.setText("Start");
if (mTimeLeftInMillis < 1000) {
mButtonStartPause.setVisibility(View.INVISIBLE);
} else {
mButtonStartPause.setVisibility(View.VISIBLE);
}
if (mTimeLeftInMillis < START_TIME_IN_MILLIS) {
mButtonReset.setVisibility(View.VISIBLE);
} else {
mButtonReset.setVisibility(View.INVISIBLE);
}
}
}
#Override
public void onStop() {
super.onStop();
SharedPreferences prefs = getSharedPreferences("pref", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong("millisLeft", mTimeLeftInMillis);
editor.putBoolean("timerRunning", mTimerRunning);
editor.putLong("endTime", mEndTime);
editor.apply();
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
}
#Override
public void onStart() {
super.onStart();
SharedPreferences prefs = getSharedPreferences("pref", MODE_PRIVATE);
mTimeLeftInMillis = prefs.getLong("millisLeft", START_TIME_IN_MILLIS);
mTimerRunning = prefs.getBoolean("timerRunning", false);
updateCountDownText();
updateButtons();
if (mTimerRunning) {
mEndTime = prefs.getLong("endTime", 0);
mTimeLeftInMillis = mEndTime - System.currentTimeMillis();
if (mTimeLeftInMillis < 0) {
mTimeLeftInMillis = 0;
mTimerRunning = false;
updateCountDownText();
updateButtons();
} else {
startTimer();
}
}
}
public void callNotification(){
Notification notification = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_money)
.setContentTitle("Test 1")
.setContentText("Important Message")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.build();
notificationManager.notify(1, notification);
}
}
I am having a problem with the Timer in my quiz Game. Essentially it's a multiple choice game and the player is timed on each question. I have the timer starting when the application starts and the player sees the first question. My issue is that if the player answers the question correctly or Incorrectly the timers starts giving random values, even though I reset the timer to 30 seconds on the onclick method. How do I get the timer to start at 30 seconds and countdown normally.
public class MainActivity extends AppCompatActivity {
//Views
TextView questionTextView;
TextView mscoreTextView;
TextView mtimerTextView;
Button mchoice1;
Button mchoice2;
Button mchoice3;
Button mchoice4;
//Constructors
private questions Question = new questions();
private Answers cAnswers = new Answers();
private choices Choices = new choices();
//Variables
private int questionNumber = 0;
private int mScore = 0;
private String correctAnswer;
public void onClick(View view) {
Button answer1 = (Button) view;
if(answer1.getText() == correctAnswer) {
mScore = mScore + 1;
Toast.makeText(getApplicationContext(), "CORRECT!!", Toast.LENGTH_SHORT).show();
mtimerTextView.setText("30s");
runTimer();
} else {
Toast.makeText(getApplicationContext(), "WRONG!!", Toast.LENGTH_SHORT).show();
mtimerTextView.setText("30s");
runTimer();
}
updateScore(mScore);
updateUI();
}
private void updateScore(int points) {
mscoreTextView.setText("" + points + "/" + Question.getLength());
}
public void runTimer() {
new CountDownTimer(30100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
String tick = String.valueOf(millisUntilFinished/1000 + "s");
mtimerTextView.setText(tick);
}
#Override
public void onFinish() {
Toast.makeText(getApplicationContext(), "TIME RAN OUT!!", Toast.LENGTH_LONG).show();
mtimerTextView.setText("0s");
updateUI();
}
}.start();
}
private void updateUI () {
if (questionNumber < Question.getLength()) {
questionTextView.setText(Question.getQuestion(questionNumber));
mchoice1.setText(Choices.getChoices(questionNumber, 1));
mchoice2.setText(Choices.getChoices(questionNumber, 2));
mchoice3.setText(Choices.getChoices(questionNumber, 3));
mchoice4.setText(Choices.getChoices(questionNumber, 4));
correctAnswer = cAnswers.getAnswer(questionNumber);
questionNumber ++;
} else {
Toast.makeText(getApplicationContext(), "This is the last question", Toast.LENGTH_LONG).show();
//Intent intent = new Intent(MainActivity.this, HighScoreActivity.class);
//intent.putExtra("Score", mScore);
//startActivity(intent);
}
runTimer();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
questionTextView = (TextView) findViewById(R.id.questionTextView);
mchoice1 = (Button) findViewById(R.id.choice1);
mchoice2 = (Button) findViewById(R.id.choice2);
mchoice3 = (Button) findViewById(R.id.choice3);
mchoice4 = (Button) findViewById(R.id.choice4);
mtimerTextView = (TextView) findViewById(R.id.timerTextView);
mscoreTextView = (TextView) findViewById(R.id.scoreTextView);
updateScore(mScore);
updateUI();
}
}
The thing is, you never really cancel a timer you've launched. Along with this, for every time you need a timer - you create a new one, which is not essential. The following must solve your problem:
You need to store CountDownTimer in a class field:
private CountDownTimer timer;
Then you can create it once on the start of app:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
timer = createTimer();
...
}
CreateTimer function:
public void createTimer() {
timer = new CountDownTimer(30100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
...
}
#Override
public void onFinish() {
...
}
}
}
So when you need to run timer you just call:
timer.start();
And when user gives an answer, you need to cancel timer first, then start it again:
public void onClick(View view) {
...
timer.cancel();
timer.start();
...
}
Also: you have some duplicated code in your OnClick() method. Regardless of user's answer correctness you need to run timer and set a value to mtimerTextView, so basically you want to do it outside of if-else construction.
You have to define a variable inside a CountDownTimer class.
public void runTimer() {
new CountDownTimer(30100, 1000) {
private int time = 30;
#Override
public void onTick(long millisUntilFinished) {
mtimerTextView.setText(time--+"s");
}
#Override
public void onFinish() {
Toast.makeText(getApplicationContext(), "TIME RAN OUT!!", Toast.LENGTH_LONG).show();
mtimerTextView.setText("0s");
updateUI();
}
}.start();
}
Cancelable Timer
If you want your Timer cancelable you have to define it as a global variable.
private CountDownTimer timer; // global variable
start the timer by calling the below runTimer() method.
public void runTimer() {
timer = new CountDownTimer(30100, 1000) {
private int time = 30;
#Override
public void onTick(long millisUntilFinished) {
mtimerTextView.setText(time--+"s");
}
#Override
public void onFinish() {
Toast.makeText(getApplicationContext(), "TIME RAN OUT!!", Toast.LENGTH_LONG).show();
mtimerTextView.setText("0s");
updateUI();
}
}.start();
}
You can cancel the timer by calling the below method.
public void stopTimer(){
if(timer != null){
timer.cancel();
}
}
Hope this will help
I have a countdown timer, I have a button that pause it, but I need that when you click on button, continue to countdown. I search but couldn't a function related this. How can do it? This is my code, I only managed to restart it, but not continue:
private TextView cuentaRegresiva;
private Button btnEmpezar;
private CountDownTimer countDownTimer;
private boolean timerHasStarted = false;
private long startTime = 30 * 1000;
private final long interval = 1 * 1000;
private long restante;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
btnEmpezar.setOnClickListener(iniciar);
}
OnClickListener iniciar=new OnClickListener() {
#Override
public void onClick(View arg0) {
if (!timerHasStarted && !pausado) {
countDownTimer.start();
timerHasStarted = true;
btnEmpezar.setText("Pause");
pausado=false;
}
else if(timerHasStarted && !pausado){
countDownTimer.cancel();
timerHasStarted = false;
btnEmpezar.setText("Restart");
pausado=true;
}
else if(!timerHasStarted && pausado){
countDownTimer2.start();
timerHasStarted = true;
btnEmpezar.setText("Pause");
pausado=false;
}
}
};
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
cuentaRegresiva.setText("Tiempo!");
}
#Override
public void onTick(long millisUntilFinished) {
cuentaRegresiva.setText("" + millisUntilFinished / 1000);
}
}
public class MyCountDownTimer2 extends CountDownTimer {
public MyCountDownTimer2(long restante, long interval) {
super(restante, interval);
}
#Override
public void onFinish() {
cuentaRegresiva.setText("Tiempo!");
}
#Override
public void onTick(long millisUntilFinished) {
cuentaRegresiva.setText("" + millisUntilFinished / 1000);
}
}
I thought about taking millisUntilFinished to a variable, but didn't work. Anyway I guess the way is close to that.
You can try saving the seconds until finish, and then you can start the new countdown timer with that seconds.
// -----------------------
Cuando presionas el boton de pausa, guarda los segundos que le faltan al timer para que termine. Entonces, cuando volves a apretar play, creas un nuevo CountDownTimer con esos segundos que te faltaban.
UPDATE
I did an example:
public class MainActivity extends Activity {
private static final int TIMER_TIME = 10000; // in millis
private Button btnCountdown;
private TextView tvTimeUntilFinish;
private boolean mIsPaused = true;
private long mMillisUntilFinish;
private CountDownTimer mTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMillisUntilFinish = TIMER_TIME;
btnCountdown = (Button) findViewById(R.id.btnCountdown);
tvTimeUntilFinish = (TextView) findViewById(R.id.tvTimeUntilFinish);
btnCountdown.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (mIsPaused) {
btnCountdown.setText("Pause");
initTimer();
} else {
btnCountdown.setText("Play");
cancelTimer();
}
mIsPaused = !mIsPaused;
}
});
}
private void cancelTimer() {
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
private void initTimer() {
mTimer = new CountDownTimer(mMillisUntilFinish, 1000) {
public void onTick(long millisUntilFinished) {
tvTimeUntilFinish.setText("seconds remaining: " + millisUntilFinished / 1000);
mMillisUntilFinish = millisUntilFinished;
}
public void onFinish() {
}
}.start();
}
}