OnCreate called twice when using CountDownTimer in Android - android

I am trying to implement a view with a text view counting down a number every 600 miliseconds and dynamically displaying the number in text view.
The problem: the activity gets called as expected, but during countdown the activity gets created again and the countdown begins from the start. The OnCreate() method in my activity gets called twice although it should be called once. I know it could be triggered by a change in screen orientation and other configuration changes, but it doesn't seem to happen here.
OnCreate() in my activity:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.SqueezeLayout);
countdownTextView = (TextView)FindViewById(Resource.Id.countdown_text_view);
Timer myTimer = new Timer(18000, 600, this);
myTimer.Start();
}
My implementation of CountDownTimer:
class Timer : CountDownTimer
{
public int count = 30;
SqueezeActivity squeezeActivity;
public Timer(long totaltime, long interval, SqueezeActivity activity)
: base(totaltime, interval)
{
squeezeActivity = activity;
}
public override void OnTick(long millisUntilFinished)
{
count--;
String countStr = count.ToString();
squeezeActivity.countdownTextView.Text = countStr;
}
public override void OnFinish()
{
squeezeActivity.StartActivity(typeof(AnotherActivity));
}
}
I am a beginner in Xamarin development so please be forgiving :) Thanks.

As it turned out, the method called twice was caused by a simple mistake in code logic - I was calling StartActivity twice. So it had nothing to do with the countdown timer. Thanks for the answers. :)

Related

Expected behaviour of a task updating UI if onPause and onResume is not implemented

Consider I have a TimerTask in my Activity for a ticker in UI. I get the value of a TextView every time Timer is called and increment it by 1.What is the expected behavior in UI if onPause and onResume is not implemented and I am going background and coming back. Will the value get updated while I am in background?
Sample code
public class home extends Activity {
private android.os.Handler mTimerHandler = new android.os.Handler();
private Timer mTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mTimer = new Timer();
mTimer.schedule(getTimer(), 1, 1000);
}
private TimerTask getTimer() {
final TextView counterView = (TextView) findViewById(R.id.counter);
return new TimerTask() {
public void run() {
mTimerHandler.post(new Runnable() {
public void run() {
long currentValue = Long.parseLong(counterView.getText().toString());
counterView.setText(String.valueOf(currentValue));
}
});
}
};
}
}
I have a BroadcastReceiver and TimerTask in onCreate (both updates
UI). I am curious to know what is the expected behavior if onPause and
onResume is not implemented and I am going background and coming back.
The callbacks are implemented. You usually override and call the super (otherwise an exception will be thrown). It will happen nothing. The super.onResume/super.onPause will be called as usual. What will happen to your BroadcastReceiver depends on your implementation

Finish an activity after a time period

I am trying to develop a game like matching small pictures.My problem is that i want to finish the game after a time period.For instance in level 1 we have 10 seconds to match picture.I want to display remaining time also.I will be thankful for any help.
Since you also want to show the countdown, I would recommend a CountDownTimer. This has methods to take action at each "tick" which can be an interval you set in the constructor. And it's methods run on the UI Thread so you can easily update a TextView, etc...
In it's onFinish() method you can call finish() for your Activity or do any other appropriate action.
See this answer for an example
Edit with more clear example
Here I have an inner-class which extends CountDownTimer
#Override
public void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.some_xml);
// initialize Views, Animation, etc...
// Initialize the CountDownClass
timer = new MyCountDown(11000, 1000);
}
// inner class
private class MyCountDown extends CountDownTimer
{
public MyCountDown(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
frameAnimation.start();
start();
}
#Override
public void onFinish() {
secs = 10;
// I have an Intent you might not need one
startActivity(intent);
YourActivity.this.finish();
}
#Override
public void onTick(long duration) {
cd.setText(String.valueOf(secs));
secs = secs - 1;
}
}
#nKn described it pretty well.
However, if you do not want to mess around with Handler. You always can delay the progress of the system code by writing:
Thread.sleep(time_at_mili_seconds);
You probably need to surround it with try-catch, which you can easily add via Source-> Surround with --> Try & catch.
You can use postDelayed() method of Handler...pass a Thread and specific time after which time the Thread will be executed as below...
private Handler mTimerHandler = new Handler();
private Runnable mTimerExecutor = new Runnable() {
#Override
public void run() {
//here, write your code
}
};
Then call postDelayed() method of Handler to execute after your specified time as below...
mTimerHandler.postDelayed(mTimerExecutor, 10000);

Capture the countdown timer in different activities

I´am designing a countdown timer, that works perfectly but only If I stay in this Activity. Because, if the countdown starts and I go back for example and start other Activity, the countdonws follows counting down. And logically if I start again the activty where the countdown timer is, it appears like nothing is counting down, but in the bacground is counting down, I know because on the ontick of the timer, I throw a continue notification to show it at the notification tab.
The code is bellow, sendnotification method is a method that throws a alert when the time finishes, and the sendnotificationTiempo to send a notification to the tab every second to show at the top.
public static final int NOTIFICATION_ID = 33;
public static final int NOTIFICATION_ID_Tiempo = 34;
private int minCrono;
TextView text;
MyCounter timer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StartCrono = (Button) findViewById(R.id.butt_start);
CancelCrono = (Button) findViewById(R.id.butt_cancel);
text=(TextView)findViewById(R.id.text_countTime1);
CancelCrono.setEnabled(false);
minCrono = mins.getCurrentItem();
StartCrono.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
minCrono=(60000*minCrono);
timer = new MyCounter(minCrono,1000);
timer.start();
}
});
CancelCrono.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
timer.cancel();
text.setText("El tiempo se ha cancelado");
minutosCrono = mins.getCurrentItem();
if (mNotificationManager != null)
mNotificationManager.cancel(NOTIFICATION_ID_Tiempo);
}
});
}
Countdown Class:
public class MyCounter extends CountDownTimer{
public MyCounter(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
StartCrono.setEnabled(true);
CancelCrono.setEnabled(false);
mins.setEnabled(true);
minCrono = mins.getCurrentItem();
//
text.setText("Time Complete!");
sendnotification("Guau", "Time finished.");
}
#Override
public void onTick(long millisUntilFinished) {
long segRestantesTotal=(millisUntilFinished/1000);
long minRestantes= (segRestantesTotal/60);
long segRestantes= (segRestantesTotal%60);
if(segRestantes>=10){
text.setText(minRestantes+":"+segRestantes);
sendnotificationTiempo("Guau", minRestantes+":"+segRestantes);
}
else{
text.setText(minRestantes+":0"+segRestantes);
sendnotificationTiempo("Guau", minRestantes+":0"+segRestantes);
}
}
}
}
So what I would to do, is to know when I go back the Activity and I start another one, to show the time what is counting down at the background to show it for example in a textview.
Or maybe if I can get the time that is counting down from the notification tab perfect.
Thanks!
Move your MyCounter instance out of the Activity. When the Activity restarts, the instance is being recreated so the old one is gone. There are a couple ways you can do this, but you need to have your MyCounter instance live somewhere that the Activity can access it but isn't responsible for its life cycle. I use a rudimentary ServiceLocator implementation that I wrote, but you can easily create a custom Application class and keep the timer (or a controller class that creates and controls the timer) there.

How can i have screen idle listener?

I need to use idle listener to listen the user is using the application or idle when the activity is alive.
I need to do something when the user is not using the application more than ten seconds.
How can i make it possible?
Here is the idea how you can achieve this task:
Firstly you need a Runnable(), which will be Run when your timeout(e.g. 10 sec) occurs. Below is the Runnable():
private Runnable DoOnTimeOut = new Runnable()
{
public void run()
{
// Do something Here
}
}
Now, in your activity, you can call postDelayed for the DoOnTimeOut:
Handler hl_timeout = new Handler();
#Override
public void onCreate(Bundle b)
{
hl_timeout.postDelayed(DoOnTimeOut, 10000); // The DoOnTimOut will be triggered after 10sec
}
Now, most important part is that when you see user interaction, you want to cancel the call to DoOnTimeOut and then again set the call for next 10 sec. Here is the Override method of your Activity for User Interaction:
#Override
public void onUserInteraction()
{
super.onUserInteraction();
//Remove any previous callback
hl_timeout.removeCallbacks(DoOnTimeOut);
hl_timeout.postDelayed(DoOnTimeOut, 10000);
}
I hope it will be helpful for you.

how to stop/cancel android CountDownTimer

I'm extending the CountDownTimer class to obtain some custom functionality .In onTick() in case some conditions are met I call cancel() , expecting that will be the end of it, however the onTick() callback gets call until the the count down is reached . So how to prevent this from happening ?
CountDownTimer.cancel() method seems to be not working. Here's another thread without a solution Timer does not stop in android.
I would recommend you to use Timer instead. It's much more flexible and can be cancelled at any time. It may be something like that:
public class MainActivity extends Activity {
TextView mTextField;
long elapsed;
final static long INTERVAL=1000;
final static long TIMEOUT=5000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextField=(TextView)findViewById(R.id.textview1);
TimerTask task=new TimerTask(){
#Override
public void run() {
elapsed+=INTERVAL;
if(elapsed>=TIMEOUT){
this.cancel();
displayText("finished");
return;
}
//if(some other conditions)
// this.cancel();
displayText("seconds elapsed: " + elapsed / 1000);
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, INTERVAL, INTERVAL);
}
private void displayText(final String text){
this.runOnUiThread(new Runnable(){
#Override
public void run() {
mTextField.setText(text);
}});
}
}
CountDownTimer is also working fine for me, but I think it only works if you call it OUTSIDE of the CountDownTimer implemetation (that is don't call it in the onTick).
Calling it inside also didn't worked.
I tried this code snippet, since most answers are saying you cannot cancel the timer inside its implementation, thus i tried using a handler inside onFinish. Old post but if anyone comes across this its helpful.
new Handler().post(new Runnable() {
#Override
public void run() {
timerTextView.setText("00:" + String.format("%02d", counter));
cancel();
}
});

Categories

Resources