I'm trying to implement a decreasing counter using for loop in android java. I have used handler & runnable to delay for loop iteration and I want the counter to start from 80 and end on 0, but in output, I'm getting counter from 0 to 80. In short, the reverse is required.
This is my code,
TextView totalpoints = (TextView) findViewById(R.id.txttotalpoints);
Handler handler1 = new Handler();
for (int count = 80;count>=0; count--){
int finalCount = count;
handler1.postDelayed(new Runnable() {
#Override
public void run() {
totalpoints.setText("Total Points : "+ finalCount);
System.out.println("This is in newpointsCounter" + finalCount);
}
}, 1000 * count);
}
Current output => Start from 0 & end on 80
Required output => Start from 80 & end on 0
You can user CountDownTimer as:
CountDownTimer countDownTimer = new CountDownTimer(80000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
//TODO on each interval, print your count
}
#Override
public void onFinish() {
//TODO on finish of timer, you will get notified
}
};
countDownTimer.start();
Try this :
final Handler handler = new Handler();
int count = 80;
final Runnable runnable = new Runnable() {
public void run() {
totalpoints.setText("Total Points : " + count);
Log.d(TAG, "count: " + count);
if (count-- > 80) {
handler.postDelayed(this, 5000);
}
}
};
handler.post(runnable);
Also I would recommend using log tags rather than system.println for android
No need to use handler, Android provides CountDownTimer itself just use it.
// For Java
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
System.out.println( millisUntilFinished / 1000)
}
public void onFinish() {
//work done
}
}.start();
// For kotlin
object : CountDownTimer(30000, 1000) {
override fun onTick(millisUntilFinished: Long) {
System.out.println( millisUntilFinished / 1000)
}
override fun onFinish() {
}
}.start()
Related
I want to make a stopwatch. when my stopwatch reaches 1 minute I want it to print a statement, how can i make it do this?
I am using android studio(java), Here is a bit of my code:
Button btnStart,btnPause,btnLap;
TextView txtTimer;
Handler customHandler = new Handler();
LinearLayout container;
TextView lt;
long startTime=0L,timeinMilliseconds=0L,timeSwapBuff=0L,updateTime=0L;
Runnable updateTimerThread = new Runnable() {
#Override
public void run() {
timeinMilliseconds = SystemClock.uptimeMillis() -startTime;
updateTime = timeSwapBuff+timeinMilliseconds;
int secs=(int) (updateTime/1000);
int mins=secs/60;
secs%=60;
int milliseconds=(int) (updateTime%1000);
String s = "" + mins + ":" + String.format("%02d",secs) + ":" + String.format("%03d",milliseconds);
txtTimer.setText (s);
customHandler.postDelayed(this,0);
}
};
If you just want to setText after some X minutes just create a method like this:
private void printText(int minutes) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//do you setText here
}
}, minutes * 1000);
}
and use it like:
printText(1);
Update:
Chronometer is exactly what you are looking for.
It extends TextView, so just replace your timer textview with Chronometer
mChronometer = findViewById(R.id.chronometer2);
mChronometer.setBase(SystemClock.elapsedRealtime());
mChronometer.start();
mChronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
long elapsedMillis = SystemClock.elapsedRealtime() - mChronometer.getBase();
int secs = (int) (elapsedMillis/1000);
int mins = secs/60;
if (mins == 1) {
mChronometer.stop();
anotherTextVeiw.setText("the 1 minute mark has passed");
}
}
});
You don't have to deal with Handler and Runnable with this approach
When I call the function() I want to have a chance to cancel the SOS call, If I click the button.
Basically It reads Integer.parseInt(cancelTime.getText().toString()) that has a time in second to be able to cancel.
My problem is that I'm trying to show like a countdown of the time elapsed from Integer.parseInt(cancelTime.getText().toString()) to 0 and it appears a huge number: ex: 10546468261
private void function()
{
startTime = System.currentTimeMillis();
Runnable runnable = new Runnable() {
#Override
public void run() {
double elapsedTime = (System.currentTimeMillis() - startTime)/1000;
alertButton.setText("CANCEL THE SOS: " + (int)elapsedTime);
alertButton.setBackgroundColor(Color.parseColor("#FF0000"));
}
};
Handler handler = new Handler();
handler.postDelayed(runnable, Integer.parseInt(cancelTime.getText().toString()));
}
I have modified your code, This may help you.
private void function()
{
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
alertButton.setText("seconds remaining: " + millisUntilFinished / 1000);
alertButton.setBackgroundColor(Color.parseColor("#FF0000"));
}
public void onFinish() {
alertButton.setText("Cancel SOS");
}
}.start();
}
Modify new CountDownTimer(30000, 1000) as per your need
Parameter 1:- long millisInFuture
Parameter 2:- long countDownInterval
I create a Android app and I want to make time counter. there are two long variables that it storage long data.
When running second finished, walking second must started and after this process go on four times that must finished.
public void Counter(long runsecond, final long walksecond) {
new CountDownTimer(runsecond, 1000) {
public void onTick(long millisUntilFinished) {
showtext.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
showtext.setText("done!");
new CountDownTimer(walksecond, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
showtext.setText("done!");
}
}.start();
}
}.start();
}
i take in for. only it count once. how can i correct this problem?
I think something like that might satisfy your needs. Number of seconds for both, run and walk counters, is configurable. Repeat rate specifies, how many times should both counters run.
public enum CounterType {
RUN_COUNTER,
WALK_COUNTER
}
private void start() {
int runSeconds = 5;
int walkSeconds = 5;
int repeatRate = 4; // 2 - run, 2 walk
startCount(runSeconds, walkSeconds, repeatRate, RUN_COUNTER);
}
private void startCount(final int runSeconds, final int walkSeconds, final int repeatRate, final CounterType actualCounter) {
if (repeatRate == 0) {
return;
}
int actualSeconds = 0;
if (actualCounter == RUN_COUNTER) {
actualSeconds = runSeconds;
} else if (actualCounter == WALK_COUNTER) {
actualSeconds = walkSeconds;
}
new CountDownTimer(actualSeconds * 1000, 1000) {
#Override public void onTick(long millisUntilFinished) {
Log.d("Counter - onTick", actualCounter.toString() + ": millis remaining: " + millisUntilFinished);
}
#Override public void onFinish() {
Log.d("Counter - onFinish", actualCounter.toString());
CounterType nextCounter = actualCounter == RUN_COUNTER ? WALK_COUNTER : RUN_COUNTER;
startCount(runSeconds, walkSeconds, repeatRate - 1, nextCounter);
}
}.start();
}
I have a MediaPlayer and an audio file, which I need to play, also I have an ArrayList with the certain seconds of this audio file, on this seconds while audio is playing, I need to switch pages in the ViewPager. How to get a CallBack from the MediaPlayer in these certain moments of the time? or maybe you will recommend some other way how is possible to do it.
What I have right now is the method, where I use CountDownTimer, which change pages in ViewPager, but it works wrong and it doesn't take into the account fact that an audio track can be stop and then resume.
public void startPlayingLabels() {
mPlayer = new MediaPlayer();
try {
String mFileName = CameraFragment.mAudioFolder + "/" + ViewActivity.parentName + ".3gp";
mPlayer.setDataSource(mFileName);
mPlayer.prepare();
mPlayer.start();
for (int i=0; i<zeroLabelPosition.size()-1; i++) {
final int finalI = i;
new CountDownTimer(Integer.parseInt(String.valueOf(Integer.parseInt((String) zeroTime.get(finalI + 1)) - Integer.parseInt((String) zeroTime.get(finalI)))), 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
mPager.setCurrentItem(Integer.parseInt(String.valueOf(zeroLabelPosition.get(finalI))));
}
}.start();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
Android madiaplayer does not have any timeline update, thats why you can write your own, or you can use something like this.
CountDownTimer timer;
int timeStampIterator;
int[] timeStamp = new int[5]; // your own time stamps when view must be switched
void play() {
mPlayer.start();
timer = new CountDownTimer(mPlayer.getDuration() - mPlayer.getCurrentPosition(), 1000) {
#Override
public void onTick(long millisUntilFinished) {
int timeSpends = mPlayer.getDuration() - mPlayer.getCurrentPosition();
if (timeSpends == timeStamp[timeStampIterator]) {
//switchToNExtSlide();
timeStampIterator++;
}
}
#Override
public void onFinish() {
}
}.start();
}
void pause() {
mPlayer.pause();
timer.cancel();
timer = null;
}
void stop() {
mPlayer.stop();
timer.cancel();
timer = null;
timeStampIterator = 0;
}
you can also use handler for it like following
Handler handler = new Handler();
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater();// change hear page for view pager, because it call after every 1 second
}
};
handler.postDelayed(notification, 1000);
I have checked all SO answers about how to pause/resume timer, but can't find a solution.
I have created a Timer task which counts the effort time for an employee and puts it inside a TextView to show.
Code below:
Timer T = new Timer();
T.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
String workingTime = "Your effort is "
+ format.format(Double.valueOf(hr)) + ":"
+ format.format(Double.valueOf(min)) + ":"
+ format.format(Double.valueOf(sec))
+ " till now for the day";
storeEffort.setText(workingTime);
sec++;
if (sec > 59) {
sec = 0;
min = min + 1;
}
if (min > 59) {
min = 0;
hr = hr + 1;
}
}
});
}
}, 1000, 1000);
where storeEffort is my TextView which shows the effort time which is stuck inside the running thread(main problem). I want to pause the effort timer with a button click and resume it when the same button clicked again.Is there any other way to do this kind of task?
You solution might have a slight problem - you are using timer to count time intervals whereas there is no need to. You could use i.e. StopWatch to count elapsed time. So instead of adding seconds in a timer job you could just get elapsed time from this timer. To pause the timer you could call stopWatch.stop() and to start it, you could call stopWatch.start().
It could look like this:
Stopwatch stopwatch = Stopwatch.createStarted();
void startThreadUpdateTimer(){}
Timer T = new Timer();
T.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
String workingTime = "Your effort is " + sw.toString() +
" till now for the day";
}
});
}
}, 1000, 1000);
}
public void pause(){
if(stopwatch.isRunning()){
stopwatch.stop();
}
}
public void resume(){
if(!stopwatch.isRunning()){
stopwatch.start();
}
}
UPDATE Solution if the timer needs to start from beginning every second time:
public class YourOuterClass extends Activity {
private YourTimerTask mTimerTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button;
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (mTimerTask != null && mTimerTask.isTaskActive()) {
mTimerTask.deactivateTimer();
mTimerTask = null;
} else {
startTask();
}
}
});
...
}
private class YourTimerTask extends TimerTask {
private boolean mIsTimerActive;
public YourTimer() {
mIsTimerActive = true;
}
public void deactivateTimer() {
mIsTimerActive = false;
}
public boolean isTaskActive() {
return mIsTimerActive;
}
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
String workingTime = "Your effort is "
+ format.format(Double.valueOf(hr)) + ":"
+ format.format(Double.valueOf(min)) + ":"
+ format.format(Double.valueOf(sec))
+ " till now for the day";
if (!mIsTimerActive) {
cancel(); // will cancel this timer instance
}
sec++;
if (sec > 59) {
sec = 0;
min = min + 1;
}
if (min > 59) {
min = 0;
hr = hr + 1;
}
}
});
}
}
...
private void startTask() {
Timer T = new Timer();
mTimerTask = new YourTimertask();
T.scheduleAtFixedRate(mTimerTask, 1000, 1000);
}
}