I'm trying to check for variable changes within a specified amount of time. For example I got a variable:
int downloadProgress = 0;
and I got some code which downloads a file and the var downloadProgress is being update to 1..2.3....5.6..7. until ..100 (download finishes).
Now I want to have a thread like the following:
Runnable checkNet = new Runnable(){
public void run(){
// check variable changes
}
};
that checks for changes in the variable downloadProgress within a specified amount of time say 20 seconds. If the variable doesn't change for at least 20 seconds than I want to do something!
How could I utilize a timer to do this within a thread!!
you may use timer: http://developer.android.com/reference/java/util/Timer.html In this case you will not need a thread, because Timer imlies a thread
Here is example:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TextView(this);
this.setContentView(tv);
MyCount counter = new MyCount(5000,1000);
counter.start();
}
public class MyCount extends CountDownTimer{
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
tv.setText(”done!”);
}
#Override
public void onTick(long millisUntilFinished) {
tv.setText(”Left: ” + millisUntilFinished/1000);
}
}
}
Source: http://dewful.com/?p=3
Related
I'm making simple android app which should have counter which counts from 60 seconds down to 0 seconds. I have one idea how to do it, but I'm not sure if it is the smartest way to do it. And I'm not sure how to make it work in the code.
Idea:
In the .xml file I have added textView. I would make MyService class that extends Service which will be called by the .java file inside OnCreate function (because I want that counting starts immediately). MyService will change content of textView every second (I will have int counter which will be decreased every second and then text of textView will be changed).
Is there any better way to do it?
Here is MyService class:
public class MyService extends Service {
//for timer:
int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
doSomethingRepeatedly();
return START_STICKY;
}
private void doSomethingRepeatedly() {
timer.scheduleAtFixedRate( new TimerTask() {
public void run() {
//code for changing the content
}
}, 0, UPDATE_INTERVAL);
}
#Override
public void onDestroy() {
super.onDestroy();
//za timer
if (timer != null){
timer.cancel();
}
}
}
Do I have to put this code in separate .java file?
I'm not sure how to write code for changing the content of textView, because I'm not sure if I can call id of textView because it is in the separated file?
These would be functions for starting the Services:
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
Where do I have to put them?
Use a CountDownTimer.
Schedule a countdown until a time in the future, with regular
notifications on intervals along the way. Example of showing a 30
second countdown in a text field:
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
The calls to onTick(long) are synchronized to this object so that one
call to onTick(long) won't ever occur before the previous callback is
complete. This is only relevant when the implementation of
onTick(long) takes an amount of time to execute that is significant
compared to the countdown interval.
Before I start I have looked at lots of threads including:
How to add time to countdown timer?
Android game countdown timer
But I just cant get my timer to work in the way I require. I want the timer to be counting down from say 30 and when and image is pressed (named imageview1 in this case) the timer adds 3 seconds to the timer to give it more time. I know you cannot essentially add the time while its running and you need to cancel and then start a new timer, The code I have so far is :
public void onClick(View v) {
// TODO Auto-generated method stub
//GlobalClass global = new GlobalClass();
Random rand = new Random();
CountDownTimer thetimer = new myTimer(millisInFuture, 1000);
switch(v.getId()) {
case R.id.buttonstart:
btnstart.setVisibility(View.INVISIBLE);
thetimer.start();
break;
case R.id.imageView1:
if (thetimer != null){
thetimer.cancel();
thetimer = new myTimer(countdownPeriod + 3000, 1000).start();
}
break;
with lots of other case references then :
public class myTimer extends CountDownTimer {
public myTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
timedisplay.setText("Time Left: " + millisUntilFinished / 1000);
countdownPeriod=millisUntilFinished;
}
#Override
public void onFinish() {
timedisplay.setText("Timer Finished");
started = false;
btnstart.setVisibility(View.VISIBLE);
}
}
I think the problem is its not cancelling the original timer so the label that shows the timer does some crazy things, like jumping around on different numbers both up and down as there would appear more than 1 class of thetimer. That is even though I have included the line thetimer.cancel(); The timer works fine if I just let it run to 0.
Any help would be great
You should not create your timer as a local in onClick. Instead create it as a global and start it somewhere else (in onCreate perhaps).
What happens with your current code is that whenever onClick is called a new timer is created and you then cancel the new timer - which has no effect on any previously created timer(s).
Try something like this:
public class MyActivity extends Activity {
CountDownTimer thetimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
thetimer = new myTimer(millisInFuture, 1000);
}
public void onClick(View v) {
Random rand = new Random();
switch(v.getId()) {
case R.id.buttonstart:
btnstart.setVisibility(View.INVISIBLE);
thetimer.start();
break;
case R.id.imageView1:
if (thetimer != null) {
thetimer.cancel();
thetimer = new myTimer(countdownPeriod + 3000, 1000).start();
}
break;
}
}
}
You will still have to keep track of the global time somewhere - i.e. the countDonwPeriod used to re-create the timer instance when an image is touched - it should probably be extracted from the timer before canceling it.
I trying to make my textView appear in different place of the screen every minute or two (delay is not important). I've seen people are suggesting I use runOnUiThread to make a timer repeat the random function and the update the UI.
I'm really struggling getting my head around these different threads, just wondering if anyone could give me an example? Or should I research using something different?
Public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.digitalClock1);
Random r = new Random();
int x = r.nextInt(350 - 100);
int y = r.nextInt(800 - 100);
textView.setX(x);
textView.setY(y);
}
Try this method
public void doInback()
{
handler.postDelayed(new Runnable() {
#Override
public void run()
{
// TODO Auto-generated method stub
// Try the code that you want to repeat
doInback();
}
}, 1000);
}
just call the method where you want to use.
Create the runnable and the handler below
private Runnable runnable = new Runnable(){
#Override
public void run() {
handler.sendEmptyMessage(0);
}
};
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
//change the text position here
this.postDelayed(runnable , TIME_OUT_MS);
}
};
The TIME_OUT_MS is the time out you want in milliseconds.
And put this on the OnCreate() method of the activity
Thread thread =new Thread(runnable );
thread.start();
I am new to android (and not so hot with it, but trying to learn).
I am creating an application that has a number of various buttons that start countdown timers when they are clicked.
On the activity that has these buttons the following code is used to start the timer:
//Button 1 Start On Click
final CountDown buttonOneTimer = new CountDown(15000,1000);
buttonOne.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
buttonOneTimer.start();
}
});
//Button 2 Start On Click
final CountDown buttonTwoTimer = new CountDown(15000,1000);
buttonTwo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
buttonTwoTimer.start();
}
});
my CountDown class looks like this:
public class CountDown extends CountDownTimer {
public CountDown (long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
System.out.println("Timer Completed.");
****NAMEOFTHEBUTTONCLICKED****.setText("Timer Completed.");
}
#Override
public void onTick(long millisUntilFinished) {
****NAMEOFTHEBUTTONCLICKED****.setText((millisUntilFinished/1000)+"");
System.out.println("Timer : " + (millisUntilFinished/1000));
}
}
I am trying to get the name of the button pressed into the class so I can set the text on the button to countdown.
I'm sure I am doing all sorts of things wrong or there may be better ways to do it - so if you see areas where I could improve - feel free to critique me!
I read over the tutorial here however it has an 'inner class' (I believe that is what it is called?) inside the current class. A friend of mine said that's very rarely done and to just create a separate class such as CountDown. If I do it the same way as in the tutorial I can get the timer to work (by hardcoding the buttons name where it says *NAMEOFTHEBUTTONCLICKED* above, which means it only works for that button) - but I still need to figure out how to pass that class the buttons name so I don't have to write a separate class for each timer.
Would that be done through Extras? I have had a hard time finding any more info to my specific issue. Any help is appreciated!!
Try passing off the button instance to the Timer:
public class CountDown extends CountDownTimer {
Button button;
public CountDown (long millisInFuture, long countDownInterval, Button button) {
super(millisInFuture, countDownInterval);
this.button = button;
}
#Override
public void onFinish() {
System.out.println("Timer Completed.");
button.setText("Timer Completed.");
}
#Override
public void onTick(long millisUntilFinished) {
button.setText((millisUntilFinished/1000)+"");
System.out.println("Timer : " + (millisUntilFinished/1000));
}
}
Then call like this:
//Button 1 Start On Click
final CountDown buttonOneTimer = new CountDown(15000,1000,buttonOne);
buttonOne.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
buttonOneTimer.start();
}
});
I'm trying to make a countdown timer in android for use in a small android app. The app will countdown from some number of seconds to 0, upon which it will do some action. I'm using the coundowntimer supplied by android.os.countdowntimer. Here is my code:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.quizlayout);
new CountDownTimer(30000, 1000) {
TextView tx = (TextView) findViewById(R.id.textView2);
public void onTick(long millisUntilFinished) {
tx.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
tx.setText("done!");
}
}.start();
}
However, this countdown timer is really slow. It takes like 3 real-time seconds for the timer to countdown by one second. I wonder what's going on? The code I have above is more or less copied straight from google (CountDownTimer)
Can anyone help me as per why my timer is so slow, and offer a way to speed it up a bit?
(EDIT): I am running this on an emulator, the intel atom x86. I am emulating an android 2.3.3 environment.
According to Android documentation for countdown timer
The calls to onTick(long) are synchronized to this object so that one call to onTick(long) won't ever occur before the previous callback is complete. This is only relevant when the implementation of onTick(long) takes an amount of time to execute that is significant compared to the countdown interval.
Take a look at this example for countdown timer
Countdown timer example
Alternately you can spawn a new thread and just get that thread to sleep for the interval you want and take actions when it wakes or vice versa.
You can also timertask
use a handler that will post the same runnable . this will remove the need for extra threads :
Handler handler=new Handler();
handler.postRunnable(... , 1000) ;
in the runnable , call the postRunnable again for the same handler (and add a condition for when to stop) .
CountDownTimer is not efficient regardless to ui updating performances. For a flawless ui update, it is better to create a custom countdown. I did my own so here it is. It is flawless on my app.
public abstract class CountDown {
int totalTime = 0;
int tickTime = 0;
Thread thread;
boolean canceled = false;
public CountDown(int totalTime,int tickTime){
this.totalTime = totalTime;
this.tickTime = tickTime;
}
public abstract void onTick();
public abstract void onFinish();
public void start(){
thread = new Thread(new Runnable() {
#Override
public void run() {
// Do in thread
canceled = false;
for (int elapsedTime = 0; elapsedTime < totalTime; elapsedTime += tickTime) {
if(!canceled){
onTick();
try {
thread.sleep(tickTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
if(!canceled){
onFinish();
}
}
});
thread.start();
}
public void cancel(){
canceled = true;
}
}
Remember that every time you have to update your ui, call a runOnUiThread, or else you will have an exception, you are not in a handler and not on ui thread.
Here is how to use it in your code, it is identical to CountDownTimer, so you could just rename lines in your code :
CountDown cDown = new CountDown(10000, 20) {
public void onTick() {
// Do something
}
public void onFinish() {
runOnUiThread(new Runnable() {
#Override
public void run() {
myButton.setImageDrawable(drawable);
}
});
}
};