Nesting countdown timers in android - java

I want call CountDownTimer when one countdownTimer finishes it's execution.I tried calling one countdowntimer from another countdown timer's onFinish() method but it giving me nullpointer exception when I run this code.
public void First_Timer(){
Timer_Off =false;
dialog = new Dialog(context,android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
dialog.setCancelable(false);
dialog.setContentView(R.layout.backwash_timer_dialog);
final ToggleButton togglebtn_BW_timer = (ToggleButton)dialog.findViewById(R.id.togglebtn_BW_timer);
final ProgressBar bar = (ProgressBar)dialog.findViewById(R.id.progressBar1);
textView1 = (TextView)dialog.findViewById(R.id.textView1);
btn_BW_timer_stop = (Button)dialog.findViewById(R.id.btn_BW_timer_stop);
/** CountDownTimer starts with 2 minutes and every onTick is 1 second */
cdt = new CountDownTimer(twoMin, 1000) {
public void onTick(long millisUntilFinished) {
bar.setProgress((int) ((millisUntilFinished / 1000) ));
messageHandler.sendMessage(Message.obtain(messageHandler,(int) ((millisUntilFinished / 1000) ) ));
}
public void onFinish(){
textView1.setText("Time Up! ");
cdt.cancel();
Timer_Off =true;
dialog.dismiss();
// Call Second Timer Here
Second_Timer();
}
}.start();
btn_BW_timer_stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
cdt.cancel();
bar.setProgress(0);
textView1.setText("0");
Timer_Off=true;
dialog.dismiss();
//onBackwashStopped();
}
});
dialog.show();
}
And Code for another timer is,
public void Second_Timer(){
Timer_Rinse_Off =false;
dialog_Rinse = new Dialog(context,android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
dialog_Rinse.setCancelable(false);
dialog_Rinse.setContentView(R.layout.rinse_timer_dialog);
final ProgressBar bar = (ProgressBar)dialog.findViewById(R.id.progressbar_Rinse);
txtRinse_TimerVal = (TextView)dialog.findViewById(R.id.txtRinse_TimerVal);
btn_Rinse_timer_stop = (Button)dialog.findViewById(R.id.btn_Rinse_timer_stop);
/** CountDownTimer starts with 2 minutes and every onTick is 1 second */
cdt_Rinse = new CountDownTimer(twoMin, 1000) {
public void onTick(long millisUntilFinished) {
bar.setProgress((int) ((millisUntilFinished / 1000) ));
messageHandler.sendMessage(Message.obtain(messageHandler,(int) ((millisUntilFinished / 1000) ) ));
}
public void onFinish(){
txtRinse_TimerVal.setText("Time Up! ");
Timer_Rinse_Off =true;
dialog_Rinse.dismiss();
}
}.start();
btn_Rinse_timer_stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
cdt_Rinse.cancel();
bar.setProgress(0);
txtRinse_TimerVal.setText("0");
Timer_Rinse_Off=true;
dialog_Rinse.dismiss();
//onBackwashStopped();
}
});
dialog_Rinse.show();
}

Related

How To Destroy CoundownTimer in Java when the button is pressed?

I make a timer with a count time of 5 seconds, then when I press the exit button the counter automatically stops?
Here is my timer code:
public void startTimer(final long finish, long tick) {
CountDownTimer t;
t = new CountDownTimer(finish, tick) {
public void onTick(long millisUntilFinished) {
long remainedSecs = millisUntilFinished / 1000;
textTimer.setText("" + (remainedSecs / 60) + ":" + (remainedSecs % 60));// manage it accordign to you
}
public void onFinish() {
textTimer.setText("00:00");
Toast.makeText(FloatingVideoWidgetShowService.this, "Waktu Habis", Toast.LENGTH_SHORT).show();
long seek = videoView.getCurrentPosition();
videoView.setKeepScreenOn(false);
stopSelf();
WritableMap args = new Arguments().createMap();
args.putInt("index", index);
args.putInt("seek", (int) seek);
args.putString("url", playingVideo.getString("url"));
args.putString("type", "close");
sendEvent(reactContext, "onClose", args);
onDestroy();
cancel();
}
}.start();
}
And this is my code when pressing the stop / exit button :
floatingWindow.findViewById(R.id.btn_deny).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
long seek = videoView.getCurrentPosition();
videoView.setKeepScreenOn(false);
stopSelf();
WritableMap args = new Arguments().createMap();
args.putInt("index", index);
args.putInt("seek", (int) seek);
args.putString("url", playingVideo.getString("url"));
args.putString("type", "close");
sendEvent(reactContext, "onClose", args);
onDestroy();
}
});
How so when btn_deny is clicked Cuntdowntimer stops and does not force close?
Thanks.
You can't use onDestroy() to close your activity or fragment. Instead, you need to call finish().
To close the CountDownTimer, you need to make it a class scope variable. Prepare the timer at your startTimer then stop the timer by calling t.cancel() like the following code:
public class YourActivity extends Activity {
// Declare the variable to be accessed later.
CountDownTimer t;
...
public void startTimer(final long finish, long tick) {
t = new CountDownTimer(finish, tick) {
...
}.start();
}
private void yourOtherMethod() {
floatingWindow.findViewById(R.id.btn_deny).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(t != null) t.cancel();
...
}
});
}
}

I am trying to display a CountDownTimer on screen and I get "Only one looper can be created per thread" in my logcat

I'm a beginner in Android programming. I'm trying to display a timer for an upgrade in my game to show how long the upgrade will be activated for. In my collision flag I call Looper.prepare and start my thread class as the logcat suggested I do. How would I get this to run on one looper?
Here is the snippet that starts the thread.
BigGapUpgrade.java
public boolean playerCollectUpgrade(Player player){
if(Rect.intersects(rectangle, player.getRectangle())){
Looper.prepare();
bigGapUpgradeHandler.start();
}
return Rect.intersects(rectangle, player.getRectangle());
}
And here is my thread class
BigGapUpgradeHandler.java
public class BigGapUpgradeHandler extends Thread {
TimerTask scanTask;
Timer timer = new Timer();
#Override
public void run() {
Looper.prepare();
scanTask = new TimerTask() {
public void run() {
}
};
timer.schedule(scanTask, 0, 4000);
CountDownTimer countDownTimer = new CountDownTimer(4000, 100) {
#Override
public void onTick(long l) {
Log.i(TAG, "onTick: ");
}
#Override
public void onFinish() {
timer.cancel();
Log.i(TAG, "onFinish: ");
}
}.start();
Looper.loop();
}
}
After running it I get this error
W/System.err: java.lang.RuntimeException: Only one Looper may be created per thread
--Edit
Here is the solution I came up with.
-- Solution
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
CountDownTimer countDownTimer = new CountDownTimer(5000,100) {
#Override
public void onTick(long millisUntilFinished) {
millis = millisUntilFinished/100;
}
#Override
public void onFinish() {
}
}.start();
}
});
OK, So what you can do is just use a TimerTask. That creates it's own background thread for you do stuff:
// This TimerTask Updates the UI so it needs a reference to the Activity.
static class PowerUpTimerTask extends TimerTask
{
WeakReference<AppCompatActivity> mActivity;
long mInterval;
long mPeriod;
public PowerUpTimerTask(AppCompatActivity activity, long period, long interval)
{
mActivity = new WeakReference<>(activity);
mInterval = interval;
mPeriod = period;
}
#Override
public void run()
{
AppCompatActivity activity = mActivity.get();
if (activity != null)
{
final TextView timerTextView = activity.findViewById(R.id.timerTextView);
mPeriod -= mInterval;
if (mPeriod > 0)
{
// Set time remaining
activity.runOnUiThread(new Runnable()
{
#Override
public void run()
{
timerTextView.setText(String.valueOf(mPeriod));
}
});
}
else
{
// Out of time...clear the Text and stop the timer task.
activity.runOnUiThread(new Runnable()
{
#Override
public void run()
{
timerTextView.setText("");
}
});
Log.d(TAG, "Timer done. Canceling.");
cancel();
}
}
else
{
// Cancel this timer task since we don't have a reference to
// the Activity any more.
Log.d(TAG, "Lost reference to Activity. Canceling.");
cancel();
}
}
}
Then you can start your Timer task like so:
...
// Will count down from 10 by 1s.
mPowerUpTimerTask = new PowerUpTimerTask(this, powerUpTime, 1);
// Schedule for every second.
Timer t = new Timer();
t.scheduleAtFixedRate(mPowerUpTimerTask, 1000, 1000);
...
Here is a link to this running sample:
https://github.com/didiergarcia/TimerTaskExample
I think you have to use LocalBroadcastManager for the timing to continuously in loop. Please check below code for for that :-
private void startTimer() {
countDownTimer = new CountDownTimer(Constant.getInstance().ANSWER_TIME_IN_SECOND * 1000, 1000) {
public void onTick(long millisUntilFinished) {
remaininTimeInMillies = millisUntilFinished;
tvTimer.setText(getTime(Integer.parseInt(String.valueOf(millisUntilFinished))));
}
public void onFinish() {
Intent intent = new Intent(Constant.getInstance().TIMER_RECEIVER);
LocalBroadcastManager.getInstance(PatientDetailActivity.this).sendBroadcast(intent);
}
};
countDownTimer.start();
}
private String getTime(int milliSec) {
int minut = 0, second = 0;
minut = milliSec / 60000;
second = (milliSec - (minut * 60000)) / 1000;
String strMinute = "", strSecond = "";
if (minut < 10) {
strMinute = "0" + String.valueOf(minut);
} else {
strMinute = String.valueOf(minut);
}
if (second < 10) {
strSecond = "0" + String.valueOf(second);
} else {
strSecond = String.valueOf(second);
}
return strMinute + ":" + strSecond;
}
#Override
protected void onResume() {
LocalBroadcastManager.getInstance(this).registerReceiver(timerBroadcast, new IntentFilter(Constant.getInstance().TIMER_RECEIVER));
super.onResume();
}
#Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(timerBroadcast);
super.onDestroy();
}
Thanks and Hope that will help you

Repeat specific action X number of times in Android

So I want certain action to be performed X number of times, depends on how many times user wants it. User selection will be selected from a TextView string which is set up with this code:
homeScreenPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dodajInterval();
homeScreenMinus.setEnabled(counter > 0);
}
});
homeScreenMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
oduzmiInterval();
homeScreenMinus.setEnabled(counter > 0);
}
});
}
private void oduzmiInterval() {
counter--;
brojIntervala.setText(Integer.toString(counter));
}
private void dodajInterval() {
counter++;
brojIntervala.setText(Integer.toString(counter));
}
Those are basicly two buttons that increment or decrement value of TextView.
The action I want to perform X times is this:
public void homeScreenStart(View view) {
linearniLayoutSetup.setVisibility(View.GONE);
new CountDownTimer(seekBarTimerDelay.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
countDownTimerTrci();
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_trci));
}
}.start();
}
private void countDownTimerTrci() {
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
new CountDownTimer(seekBarIntervaliVisokogIntenziteta.getProgress() * 1000 + 100, 1000){
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
imageViewTimerSlika.setImageResource(R.drawable.ic_timer_niski_intenzitet);
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_hodaj));
countDownTimerHodaj();
}
}.start();
}
private void countDownTimerHodaj(){
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
new CountDownTimer(seekBarIntervaliNiskogIntenziteta.getProgress() * 1000 + 100, 1000){
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.colorAccent));
textViewTimerTrciHodajBlaBla.setText("Done!");
}
}.start();
}
So it is combination of 3 seekbars, or timers, one running after another and then they should run as many times as user selects.
The problem is, I have no idea how to set this up, and I need that first block of code in timers to run just once, and those 2 methods below it to run X times.
How can I do it?
Unless I am missing something couldn't you just wrap your code in the action in a loop that references the current counter? You may need to block input so that the user can not modify the counter (unless you want them to) after execution has begun but that should be it.
public void homeScreenStart(View view) {
linearniLayoutSetup.setVisibility(View.GONE);
CountDownTimer firstCountDown = new CountDownTimer(seekBarTimerDelay.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
countDownTimerTrci();
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_trci));
}
}
CountDownTimer secondCountDown = new CountDownTimer(seekBarIntervaliVisokogIntenziteta.getProgress() * 1000 + 100, 1000){
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
imageViewTimerSlika.setImageResource(R.drawable.ic_timer_niski_intenzitet);
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_hodaj));
countDownTimerHodaj();
}
}
CountDownTimer thirdCountDown = new CountDownTimer(seekBarIntervaliVisokogIntenziteta.getProgress() * 1000 + 100, 1000){
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
imageViewTimerSlika.setImageResource(R.drawable.ic_timer_niski_intenzitet);
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_hodaj));
countDownTimerHodaj();
}
}
for (int i = 0; i < counter; i++) {
firstCountDown.start();
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
secondCountDown.start();
thirdCountDown.start();
}
}
Should work for you

How to logout from android application.?

here is my code.but if this runs my app closed from 60seconds.but when i again press app icon.its open as logged.how to close app with logout.?i added these in my service class.
public class BackgroundService extends Service {
private int interval3 = 10; // 10 seconds
private Handler mTimer3 = new Handler();
private Runnable mTask3 = new Runnable() {
public void run() {
mTimer3.postDelayed(this, interval3 * 1000L);
CountDownTimer timer = new CountDownTimer(10*1000, 1000) {
public void onTick(long millisUntilFinished) {
Log.w("Seconds remaining: ", String.valueOf(millisUntilFinished / 1000));
}
public void onFinish() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
};
timer.start();
}
};
public void onCreate() {
mTimer1.postDelayed(mTask1, interval1 * 1000L); // start the timer for the first time
mTimer2.postDelayed(mTask2, interval2 * 1000L); // start the timer for the first time
mTimer3.postDelayed(mTask3, interval3 * 1000L); // start the timer for the first time
}
please give me a suggestion.because we need to sign out from app when idle at more time.
thanks all
now its ok.i tried with activity class instead of service class and i added code to after login screen going page.now its working perrfect for me :-)
public class #MyActivityClass extends Activity {
//=============================================================================================================================
private Handler mTimer3 = new Handler();
private Runnable mTask3 = new Runnable() {
public void run() {
CountDownTimer timer = new CountDownTimer(10*1000, 1000) {
public void onTick(long millisUntilFinished) {
Log.w("Seconds remaining: ", String.valueOf(millisUntilFinished / 1000));
}
public void onFinish() {
//Here finally added finish(); and System.exit(0); methods
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//***Change Here***
startActivity(intent);
finish();
System.exit(0);
}
};
timer.start();
mTimer3.postDelayed(this, interval3 * 1000L);
}
};
private int interval3 = 10*60; // 60 seconds
#Override
protected void onDestroy() {
if (mTimer3 != null) {
mTimer3.removeCallbacks(mTask3); // cancel the timer
}
}

How can I stop a Timer?

I have a simple question, how can I stop timer?
Button bCancel = (Button)findViewById(R.id.bt1);
bCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
startActivity(new Intent("com.jom.testcdt2.CANCELCLASS"));
}
});
final Thread logoTimer = new Thread(){
public void run(){
try {
int logoTimer = 0;
while (logoTimer < 10000) {
sleep(100);
logoTimer = logoTimer + 100;
}
startActivity(new Intent("com.jom.testcdt2.CLEARSCREEN"));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
finally{
finish();
}
}
};
logoTimer.start();
}
When I press button bCancel, it starts a new activity, but timer is still running and after 10 seconds it starts CLEARSCREEN. On click I want timer to stop. How can I do that?
I would recommend using a CountDownTimer:
final CountDownTimer myTimer = new CountDownTimer(10000, 5000) {
#Override
public void onFinish() {
//DO SOMETHING AFTER 10 000 ms
}
#Override
public void onTick(long millisUntilFinished) {
//DO SOMETHING EVERY 5 000 ms until stopped
}
}
myTimer.start() //Starts it
myTimer.cancel() //Stops it
And instead of writing
(new Intent("com.jom.testcdt2.CANCELCLASS")
you should use
(new Intent(YOURCLASS.this, CancelClass.class)
Could you try to have a boolean value that you check in the while loop, and set it to true when you press the cancel button?
boolean pressedCancel = false;
....
while (logoTimer < 10000 && !pressedCancel) {
....

Categories