I have following code in my service.
countDownTimer = new CountDownTimer(60000 * 3, 1000) {
#Override
public void onTick(long l) {
intentDSU.putExtra("remaind", TimeUnit.MILLISECONDS.toSeconds(l));
sendBroadcast(intentDSU);
}
#Override
public void onFinish() {
postHandler();
intentDSU.putExtra("remaind", 0);
sendBroadcast(intentDSU);
countDownTimer.start();
}
};
countDownTimer.start();
That's work fine, but when i try convert seconds to minutes and remaind of seconds on my activity
private void updateGUI(Intent intent){
if(intent.getExtras() != null){
long remaind = intent.getLongExtra("remaind", 0);
if(remaind == 0){
onRefresh();
}
long minutes = TimeUnit.SECONDS.toMinutes(remaind) - (TimeUnit.SECONDS.toHours(remaind)* 60);
long seconds = TimeUnit.SECONDS.toSeconds(remaind) - (TimeUnit.SECONDS.toMinutes(remaind) *60);
MenuItem menuItem = menu.findItem(R.id.action_timer);
if(menuItem != null){
if(minutes > 0){
menuItem.setTitle(String.format("%o min.", minutes));
}
else {
menuItem.setTitle(String.format("%o sec.", seconds));
}
}
}
}
I become notice unusual results, seconds will start 73 instead 60. I haven't idea, what's wrong?
you're code is correct, I quess you get problem in String.format("%o min.", minutes) and here String.format("%o sec.", seconds).
Try to use this.
MenuItem menuItem = menu.findItem(R.id.action_timer);
if(menuItem != null){
if(minutes > 0){
menuItem.setTitle(String.format("%s min.", Long.toString(minutes)));
}
else {
menuItem.setTitle(String.format("%s sec.", Long.toString(seconds)));
}
}
try this
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
long sec=TimeUnit.MILLISECONDS.toSeconds(passmillitimer);
Related
public void startCountdownTimer() {
currentCountdown = startCountdown;
// stopTimer=false;
if (stopTimer == true) {
return;
}
for (int i = 1; i <= startCountdown + 1; i++) {
task = new TimerTask() {
#Override
public void run() {
countdownHandler.post(doA);
}
};
countdownTimer = new Timer();
countdownTimer.schedule(task, i * 1000);
}
}
final Runnable doA = new Runnable() {
#Override
public void run() {
//reset timer when switching to another question
if (currentCountdown != -1 && btn_next.getText().equals("CHECK") && stopTimer != true) {
if (currentCountdown == 0) {
relative_stop.setVisibility(View.INVISIBLE);
currentCountdown = startCountdown;
btn_next.setText("NEXT");
toast = Toasty.warning(getApplicationContext(), "Time's UP", 1000);
toast.show();
toast = Toasty.info(getApplicationContext(), correctAnswer, 1000);
toast.show();
countdownTimer.cancel();
countdownTimer.purge();
}
tv_timer.setText("" + currentCountdown);
currentCountdown--;
}
}
};
I'm trying to make a timer that counts down for 10 seconds, it works normally when it runs for the first time, and when it runs consecutively, the timer caused by delay suddenly speeds up.
In my application i should use CountDownTimer and for this I want use this library : CountdownView.
I want when lasted 5s show me Toast.
For example : I want show 17s countTimer, when this timer receive to 5s show me toast "just 5s".
I use this code, but show me ever 5s .
long time1 = 17 * 1000;
mCvCountdownViewTest1.start(time1);
mCvCountdownViewTest1.setOnCountdownIntervalListener(5000, new CountdownView.OnCountdownIntervalListener() {
#Override
public void onInterval(CountdownView cv, long remainTime) {
Toast.makeText(MainActivity.this, "Just 5s ", Toast.LENGTH_SHORT).show();
}
});
I want just lasted 5s not ever 5s.
how can i it?
By modifying your code:
boolean toastShown = false;
long time1 = 17 * 1000;
mCvCountdownViewTest1.start(time1);
mCvCountdownViewTest1.setOnCountdownIntervalListener(1000, new CountdownView.OnCountdownIntervalListener() {
#Override
public void onInterval(CountdownView cv, long remainTime) {
if(remainTime < 5000 && !toastShown) {
toastShown = true;
Toast.makeText(MainActivity.this, "Just 5s ", Toast.LENGTH_SHORT).show();
}
}
});
You can try this code also:
CountDownTimer countDownTimer = new CountDownTimer(17000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Toast.makeText(HomeActivity.this, "running" + millisUntilFinished, Toast.LENGTH_SHORT).show();
if (millisUntilFinished < 5000) {
Toast.makeText(HomeActivity.this, "5 sec left", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFinish() {
Toast.makeText(HomeActivity.this, "Countdown Timer Finished", Toast.LENGTH_SHORT).show();
}
};
countDownTimer.start();
I think you should check how many seconds remains.
I rewrote your code:
long time1 = 17L * 1000;
mCvCountdownViewTest1.start(time1);
mCvCountdownViewTest1.setOnCountdownIntervalListener(1000, new CountdownView.OnCountdownIntervalListener() {
#Override
public void onInterval(CountdownView cv, long remainTime) {
long remainTimeInSeconds = remainTime / 1000;
if (remainTimeInSeconds == 5) {
Toast.makeText(MainActivity.this, "Just 5s ", Toast.LENGTH_SHORT).show();
}
}
});
I have strange problem with countdowntimer. Normally it works well, but sometimes (like 5% chance or so) after locking phone and unlocking it bugs like on video:
https://www.dropbox.com/s/1nbp63gmv4spzgf/bug.mp4
Here i set the timer:
private void startCurrentLessonTimer() {
if(lessonsBreak) {
lessonsBreakEnd.setText(String.format("%02d:%02d:%02d", (currentLessonTimeInMillis / 1000) / 3600, ((currentLessonTimeInMillis / 1000) % 3600) / 60,
(currentLessonTimeInMillis / 1000) % 60));
} else {
currentLessonEnd.setText(String.format("%02d:%02d:%02d", (currentLessonTimeInMillis / 1000) / 3600, ((currentLessonTimeInMillis / 1000) % 3600) / 60,
(currentLessonTimeInMillis / 1000) % 60));
}
currentLessonTimer = new CountDownTimer(currentLessonTimeInMillis, 1000) {
long hours = (currentLessonTimeInMillis / 1000) / 3600;
long minutes = ((currentLessonTimeInMillis / 1000) % 3600) / 60;
long seconds = (currentLessonTimeInMillis / 1000) % 60;
#Override
public void onTick(long millisUntilFinished) {
if(seconds == 0) {
seconds = 59;
if(minutes == 0 && hours > 0) {
minutes = 59;
hours--;
}
else {
minutes--;
}
} else {
seconds--;
}
if(lessonsBreak) {
lessonsBreakEnd.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds));
} else {
currentLessonEnd.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds));
}
}
#Override
public void onFinish() {
getNextLesson();
getCurrentLesson();
}
}.start();
}
And this function (inside getData()) is called in onResume()
#Override
public void onResume() {
super.onResume();
getData();
}
onPause():
#Override
public void onPause() {
super.onPause();
clean();
}
clean():
private void clean() {
if(currentLessonTimer != null) {
currentLessonTimer.cancel();
currentLessonTimer = null;
}
}
I tried to use other countdowntimer, but this problem still occurs (but not that often).
Code: http://pastebin.com/nKsasJ1S
Any ideas?
It looks like you get multiple CountDownTimers refreshing your UI. This leads me to your clean() function like it's not doing it's job on every onPause(). So on next onResume() there will be multiple CountDownTimers.
I don't know how CountDownTimer works but the thing I can think of is that your CountDownTimer is start()ed but still not initialized (currentLessonTimer is still null) when onPause() is occurring not letting clean() to run so it'd be a race condition that could be avoided with a Service for example.
My intention is to create an timer which starts from 00:00:00 and hangs together with a recording function. This recording is done in a service so, the timer is also in the same service. If the app moves to the background, the recording and thus the timer keep on going and the app picks the time up at the onResume with a myService.getTime().
But I experience two strange things. The first is that my timer sometimes goed faster than a second, sometimes slower, sometimes jumps from for example 00:00:04 to 00:00:06 etc. There is no consitency in it. I use the code below, but there might be a better option to solve this? The second is that it is causing a lag on my button, although I am starting it in a service?
SERVICE
//////////TIMER FUNCTION START//////////
private void startTimerClick() {
if (stopped) {
startTime = System.currentTimeMillis() - elapsedTime;
} else {
startTime = System.currentTimeMillis();
}
mHandler.removeCallbacks(startTimer);
mHandler.postDelayed(startTimer, 0);
}
private void pauseTimerClick() {
mHandler.removeCallbacks(startTimer);
stopped = true;
}
private void stopTimerClick() {
mHandler.removeCallbacks(startTimer);
stopped = false;
}
private void startTimer() {
startTimer = new Runnable() {
public void run() {
elapsedTime = System.currentTimeMillis() - startTime;
updateTimer(elapsedTime);
mHandler.postDelayed(this, REFRESH_RATE);
}
};
}
private void updateTimer(float time) {
secs = (long) (time / 1000);
mins = (long) ((time / 1000) / 60);
hrs = (long) (((time / 1000) / 60) / 60);
/*
* Convert the seconds to String and format to ensure it has a leading
* zero when required
*/
secs = secs % 60;
seconds = String.valueOf(secs);
if (secs == 0) {
seconds = "00";
}
if (secs < 10 && secs > 0) {
seconds = "0" + seconds;
}
/* Convert the minutes to String and format the String */
mins = mins % 60;
minutes = String.valueOf(mins);
if (mins == 0) {
minutes = "00";
}
if (mins < 10 && mins > 0) {
minutes = "0" + minutes;
}
/* Convert the hours to String and format the String */
hours = String.valueOf(hrs);
if (hrs == 0) {
hours = "00";
}
if (hrs < 10 && hrs > 0) {
hours = "0" + hours;
}
}
//////////TIMER FUNCTION END////////////
public String getHours(){
return hours;
}
public String getMinutes(){
return minutes;
}
public String getSeconds(){
return seconds;
}
}
ACTIVITY(/FRAGMENT)
private void timerStart() {
handler = new Handler();
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
handler.post(new Runnable() {
#Override
public void run() {
timer.setText(myService.getHours()+":"+myService.getMinutes()+":"+myService.getSeconds());
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
}
You are using Threads both in your Service and in your Activity/Fragment code.
Using threads for time sensitive tasks in Android is a problem because Android is able to significantly delay threads.
I have been using a ScheduledThreadPoolExecutor for a similar task and it worked great.
You are then using it like this:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); // where 1 is the number of needed concurrent threads. 1 should last for your needs.
executor.scheduleWithFixedDelay(new TimerTask() {
// your recurringly executed code here
}, 0, 1, TimeUnit.SECONDS);
Is it possible to implement a fast forward button using the onLongClick button event?
EDIT
i used runnable inside the onlongclicklistner and adding the code for reference who needs :)
Button.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
final Runnable r = new Runnable()
{
public void run()
{//do the forwarding logic here
if(Button.isPressed()){
Button.postDelayed(this, 1000); //delayed for 1 sec
}else{
Button.postInvalidate();
Button.invalidate();
}
}
};
Button.post(r);
return true;
}
});
In your onLongClick event, set a member variable (example: mShouldFastForward) to true.
In the rest of your code (perhaps each frame played?) check if mShouldFastForward == true; if so, perform a fast-forward on that frame.
Use an onTouch event to capture the MotionEvent.ACTION_UP to set mShouldFastForward to false.
I have done it in this project (the project is not finished (ie polished) but fast forward works):
https://bitbucket.org/owentech/epileptic-gibbon-android
Take a look at playerfragment.java :
I handle this by using Threads to fast forward the mediaplayer.
Example code from project:
/*******************************/
/* Fast-Forward button actions */
/*******************************/
ffbutton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
switch (event.getAction() ) {
case MotionEvent.ACTION_DOWN:
arrays.fastforwardpressed = true;
FastForwardThread newFFThread = new FastForwardThread();
arrays.fastforwardfrom = mp.getCurrentPosition();
arrays.fastforwardto = arrays.fastforwardfrom;
newFFThread.start();
break;
case MotionEvent.ACTION_UP:
arrays.fastforwardpressed = false;
mp.seekTo(arrays.fastforwardto);
break;
}
return true;
}
});
public class FastForwardThread extends Thread
{
public FastForwardThread()
{
super("FastForwardThread");
}
public void run()
{
while (arrays.fastforwardpressed == true)
{
arrays.fastforwardto = arrays.fastforwardto + 10000;
int fastforwardseconds = arrays.fastforwardto / 1000;
int hours = fastforwardseconds / 3600, remainder = fastforwardseconds % 3600, minutes = remainder / 60, seconds = remainder % 60;
String Hours = Integer.toString(hours);
String Minutes = Integer.toString(minutes);
String Seconds = Integer.toString(seconds);
if (Hours.length() == 1)
{
Hours = "0" + Hours;
}
if (Minutes.length() == 1)
{
Minutes = "0" + Minutes;
}
if (Seconds.length() == 1)
{
Seconds = "0" + Seconds;
}
arrays.formattedfftime = Hours + ":" + Minutes + ":" + Seconds;
fastforwardHandler.sendEmptyMessage(0);
try
{
sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}