Hi im a newbie in Android & java lang.
i have this code that tells you how long have you been playing.
the code works fine, except when the screen turns off or when the user press the power button (sleep mode) it stop working.
can any one suggest a simple code to keep my time counting even when the screen is off or in sleep mode. Thanks...
public class test extends Activity
{
Handler mHandler = new Handler();
Runnable mUpdateTime = new Runnable()
{
public void run()
{
sec += 1;
if(sec >= 60)
{
sec = 0;
min += 1;
if (min >= 60)
{
min = 0;
hour += 1;
}
}
playtime.setText(String.format("%02d:%02d:%02d", hour, min, sec));
mHandler.postDelayed(mUpdateTime, 1000);
}
};
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mHandler.postDelayed(mUpdateTime, 1000);
}
}
I would suggest not counting the time, rather setting a start time and then subtracting that from the current to get the elapsed time.
A Chronometer widget might solve your problems.
I would advise against any solution where you might have to count during sleep mode, since that will kill the user's battery life.
Related
I'm working on this android app...and I have a textview, where I'd like to count UP. In this textview I have the statement "This page was refreshed X seconds ago". Every 20 seconds I'd like it to restart its countup from 0.
I've implemented a function which uses the ValueAnimator class. However, I'm not sure how to make the ValueAnimator increase the integer value by 1 every second. I'd like it to count up like a clock's second hand 1...2..3...4..5......20. Right now its counting up incredibly fast...and I want to slow it waaayyyy down. 1 count per second.
Please how do I do this? I've looked at some of the method calls for ValueAnimator, and I'm not sure how to slow it down...right now it's so fast.
Also, where would I add a method call, lets say, everytime the counter gets to 20 seconds? Lets say I want to call refreshView() when it gets to 20, before it starts all over.
Thank you for your time, and thanks for your help.
The ValueAnimator class:
https://developer.android.com/reference/android/animation/ValueAnimator
In my method I have:
ValueAnimator valueAnimator = ValueAnimator.ofInt(initialValue, finalValue);
valueAnimator.setDuration(10000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
textview.setText("This page was refreshed " + valueAnimator.getAnimatedValue().toString() + " seconds ago");
}
});
valueAnimator.start();
// Repeat 100 times
valueAnimator.setRepeatCount(100);
ValueAniamtor is used for animation. Animation are refreshed at very high rate. I don't think that you can count seconds with a valueAnimator.
In one of my apps i use a Timer to refresh periodically a textView.
final TextView textview=findViewById(R.id.tv);
new Timer().scheduleAtFixedRate(new TimerTask() {
int value=0; //start at 0
#Override
public void run() {
value++ ;
runOnUiThread(new Runnable() { //only the main thread can touch his views
#Override
public void run() {
textview.setText("This page was refreshed " + value + " seconds ago"); //refresh text
}
});
}
}, 0, 1000); //reschedule every 1000 milliseconds
}
I have problem with Countdown Timer. When I press button the Timer starts and after clossing app and waiting for a while the Timer stops. So the main idea what I want to do is to let app be awake in background process until the Timer Finish. I dont know the code or in which direction I should go. Please help me. Thanks a lot!
//paste the following code inside your button method
// mind you the example giving here is countdown for 60 seconds
int yoursecondsLeft = 0;
new CountDownTimer(60000, 100) {
public void onTick(long milliseconds) {
/////////////////////////////////////////////////////////////
////////////////////////This is the code that convert to real system time so that yo will have your exact seconds//////////////////////////////
if (Math.round((float)milliseconds / 1000.0f) != yoursecondsLeft)
{
syoursecondsLeft = Math.round((float)milliseconds / 1000.0f);
}
//////////////////////////////////////////////////////////////////////////////
Log.i("test","ms="+milliseconds+" till finished="+yoursecondsLeft );
// You can print the count down value to your texview here: e.g tv.setText(yoursecondsLeft);
}
public void onFinish() {
/*Close your application here: you can now call this method here: finish(); to end your application */
Log.i("finish","Countdown completed");
}
}.start();
I am having a really hard time trying to solve this problem :
I programmed an app that allows user to get rid of some colored squares on the screen. In my class coloredSquare, I have a method like this :
public void appearance(){
setLayoutParams(new RelativeLayout.LayoutParams(side/ 10, side/ 10));
final int[] count = {1};
final Runnable run = new Runnable() {
#Override
public void run() {
setLayoutParams(new RelativeLayout.LayoutParams(count[0] * side/ 50, count[0] * side/ 50));//View grows of 1/50 of its final size
if (count[0] < 50){
handler.postDelayed(this, 20);
} else {
setClickable(true);//When done
}
count[0]++;
}
};
handler = new Handler();
handler.postDelayed(run, 10);
}
When running on my Samsung Galaxy S4 mini, it's working juste fine.
But for instance, it does not work on the Wiko Highway 4G or on an emulator 1080x1920 and I can't understand why.
When I say that's not working : The view appears and grows but when it grows, every little view that was here before the postDelayed stays there.
And when I try to make them disappear by tapping on it, it shrinks well but all the other bigger views (before postDelayed) stay there too.
If you do not understand there, you will on the timer below.
In the meantime, I got a very simple timer like this :
final java.util.Timer t = new java.util.Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if(termine){
t.cancel();
}
if(seconds == 0){
vCoul.setText(String.valueOf(minutes) + ":00");
} else if (seconds < 10) {
vCoul.setText(String.valueOf(minutes) + ":0" + String.valueOf(seconds));
} else {
vCoul.setText(String.valueOf(minutes) + ":" + String.valueOf(seconds));
}
seconds -= 1;
if(seconds == -1){
seconds = 59;
minutes=minutes-1;
}
}
});
}
}, 0, 1000);
But every second, the new time is overlapping the former one.
Sorry for the long post, thanks in advance for your answer!
I figured this out some months ago but I hope this answer will help others.
I didn't put any background in the Activity so on most of samsung devices, there were no issues since Samsung handle just fine the no background activities.
Though, on several Wiko and Archos devices, you have to put a background (like background:#000000) so that you can move views smoothly upon it.
I am new at programming in Android and I am trying to figure out how to link the seekbar with my timer. In my program I allow the user to put in a time then click start timer, which then sends that value to a TextView and decrements seconds until finished. I would like the seekbar to "follow" along. Any help would be appreciated!
I've got the seekbar to sort of follow the timer but now its too choppy... is there an easy way to make a smooth progress?
public void startTimer() {
int min = Integer.parseInt(edit_minute.getText().toString());
int sec = Integer.parseInt(edit_second.getText().toString());
int value = (min * 60) + sec;
seek_bar.setMax(value *10000);
new CountDownTimer(getValues(), 1000) { // adjust the milli seconds here
public void onTick(long millisUntilFinished) {
text1.setText(""
+ String.format(
FORMAT,
TimeUnit.MILLISECONDS
.toHours(millisUntilFinished),
TimeUnit.MILLISECONDS
.toMinutes(millisUntilFinished)
- TimeUnit.HOURS
.toMinutes(TimeUnit.MILLISECONDS
.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS
.toSeconds(millisUntilFinished)
- TimeUnit.MINUTES
.toSeconds(TimeUnit.MILLISECONDS
.toMinutes(millisUntilFinished))));
seek_bar.setProgress((seek_bar.getProgress() + 1));
}
public void onFinish() {
text1.setText("done!");
}
}.start();
You just need to update it from your CountDownTimer. First, create an instance variable:
SeekBar progressBar;
Within your onCreate, get a reference to the seek bar:
progressBar = (SeekBar) findViewById(R.id.seek_bar_current);
Once you start the timer, tell progressBar the maximum it should go to:
progressBar.setMax(); // How ever long the timer will run for
Then in the CountDownTimer, update the progress:
progressBar.setProgress(); // The total time, minus millisUntilFinished
I have an app with multiple timers; when I start one, I can see it counting down in Logcat in Eclipse.
When I hit the Back button, onStop() is called in the app but the timer continues to countdown in logcat (the onTick() is continuing to tick away).
What I would like is when onResume() is called, I want to get that timer which is still counting down and continue it. Is this possible?
Here are my buttons that start the countdown:
//Button1 Timer
final CountDown button1 = new CountDown(420000,1000,bButton1);
bButton1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
button1.start();
long currentTime = System.currentTimeMillis();
//Set start time for calculating time elapsed if needed
saveTime("START_TIME_BUTTON1", currentTime);
}
});
//Button2 Timer
final CountDown button2 = new CountDown(360000,1000,bButton2);
bButton2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
button2.start();
long currentTime = System.currentTimeMillis();
//Set start time for calculating time elapsed if needed
saveTime("START_TIME", currentTime);
}
});
My onResume() looks like this:
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
//Reset the timers on appropriate buttons if there was something running
//If nothing was running or timer finished - have button in default state
//See if there was a button1 timer running - if not, it will be 0
SharedPreferences start = PreferenceManager.getDefaultSharedPreferences(this);
long startTime = start.getLong("START_TIME_BUTTON1", 0);
long timeElapsed = (System.currentTimeMillis()-startTime);
long timeRemaining = (420000 - timeElapsed);
if (timeRemaining == 0) {
} else if (timeRemaining > 0) {
final CountDown button1Timer = new CountDown(timeRemaining,1000,bButton1);
button1Timer.start();
long currentTime = System.currentTimeMillis();
saveTime("START_TIME", currentTime);
} else {
}
}
This actually works — the onResume() starts another timer right where the first one would be, and the text displays the appropriate number and continues counting down with the onTick() method. But now logcat shows 2 timers counting down instead of just one!
Ultimately I wouldn't want to start another timer, I just want to pick up the first timer I started where it is currently in the countdown at and have the onTick() display appropriately. Is there a way to do that? Would services be what I'm looking for? Is it already a service since it continues to tick down in the background?
I'm a little confused on what would be best practice to get this done.
onTick() will continue being called until either the time remaining reaches 0 or you call cancel() on the CountDownTimer.
So in your onStop() method you will need to call cancel() on the timer you want to stop receiving onTick() notifications.
Android's implementation of CountDownTimer uses a Handler to perform timing by queuing a Message to be sent to the Handler after each tick. Unfortunately there is no way to pause the CountDownTimer, so I believe you will need to create a new Timer with the appropriate values like you're doing currently.
When you're calculating the timeElapsed, you shouldn't use System.currentTimeMillis() because it can be changed at any time, instead you should use SystemClock.elapsedRealtime(). System.currentTimeMillis() is the timer used for the wall clock (time and date) and so can change unpredictably, see the Android documentation.