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.
Related
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. :)
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);
I am having trouble thinking of a way to keep only one CountdownTimer going for an onClick listener. Basically I have an application that 6 buttons and each time you hit one of the buttons it starts a countdown on the respective buttons text. However, I only want the most recent countdown started by an OnClick for each button running and updating the text on the button.
Here's the code I have so far... It works, but the countdowns start "fighting" with each other over which is altering the text of the button. Is there a way so that each time the OnClick is registered that any countdowns created by earlier button clicks are destroyed / ignored?
oBlue.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Button was clicked so start our count down
CountDownTimer blueTime = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
String s = String.valueOf(millisUntilFinished / 1000);
oBlue.setText(s);
}
public void onFinish() {
oBlue.setText(String.valueOf(300));
}
}.start();
Replace your counter variable with an internal class, so that you do not need to create counter variable each time. Just create a time counter variable and call the start of it if you want to restart the counter each button.
Es:
public class MyCount extends CountDownTimer {
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
//enter your code
I want to write a countdown in android which starts counting from 3 to 0. Like at first 3 in appearing and then disappearing and 2 is appearing and so on. I searched a lot but I couldn't find any good sample. Can you help me that what should I do?
use CountDownTimer
For example:
import android.os.CountDownTimer;
MyCount timerCount;
public class TestCountdown extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
timerCount = new MyCount(3 * 1000, 1000);
timerCount.start();
}
public class MyCount extends CountDownTimer {
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
//some script here
}
#Override
public void onTick(long millisUntilFinished) {
//some script here
}
}
}
The good guys in Android thought about you.
You have a class for that - CountDownTimer.
I am not going to write you the code for this but this should not be difficult.Just use a thread to display the value 3(using say TextView) first then sleep for say (100ms assuming you want it to change after 1 sec) then decrease it and repeat.
An example would be
for i=0 to 3
print the number
thread.sleep(100)
In my activity oncreate method, i have called a service using OnStartCommand(). My requirement is when the user is on the same Activity (when the Activity is visible), a set of code should run repeatedly. (Example .. I should make a web service call and get the response and do some action based on it after regular intervals).
I have put this set of code in this method.
#Override
public int onStartCommand(Intent i, int flags , int startId){
// Code to be repeated
return Service.START_STICKY;
}
But, this is getting executed only once. How to make it run repeatedly from the time the user came to this page till he leaves this page ??
CountDownTimer.cancel() method seems to be not working.
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);
}});
}
}
You can use Timer for the fixed-period execution of a method.
See here is a tutorial on this:
http://steve.odyfamily.com/?p=12