Question

If I have my counter up over 30 seconds, it often skips a second here and there. I have it counting down, with the display showing. But it chooses to skip random numbers. The numbers it skips are the same number each time. If I change the length of the timer (the user does that), it changes what number gets skipped. I posted my code;

Disclaimer: It is my first (useful) app, so it might suck really bad or not be structured well. That's okay, let me know. I can take the criticism. But take a look, and if anyone has an idea why certain seconds go missing please pipe up. Thanks!

package com.ApphHose.runnersTimer;

//import a bunch of stuff

public class MainActivity extends Activity {
TextView text, lapNumber;
Button start;
boolean workrest, vibe;
int letsRun, lapCounter;
long length;
CountDownTimer timer;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    text = (TextView) findViewById(R.id.tv);
    lapNumber = (TextView) findViewById(R.id.tvLap);
    start = (Button) findViewById(R.id.bStart);
    letsRun = 2;
    lapCounter = 1;
    workrest = true;
    vibe = true;

    start.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);

    start.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            start.setText("Stop");
            start.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
            lapNumber.setText("Lap Number: 1");
            lapCounter = 0;
            run();
        }

    });

}

private void run() {

    SharedPreferences getSetup = PreferenceManager
            .getDefaultSharedPreferences(getBaseContext());
    String setRun = getSetup.getString("run", "1");
    long setRunset = Long.parseLong(setRun);
    setRunset = setRunset * 1000;

    String setWalk = getSetup.getString("walk", "1");
    long setWalkset = Long.parseLong(setWalk);
    setWalkset = setWalkset * 1000;

    if (letsRun >= lapCounter) {

        if (workrest == true) {
            workrest = false;
            length = setRunset;

        } else {
            workrest = true;
            length = setWalkset;
        }

        final CountDownTimer timer = new CountDownTimer(length, 1000) {

            @Override
            public void onFinish() {

                if (workrest){
                    if (vibe){
                        Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                        v.vibrate(2000);
                        run();
                    } else {
                        run();
                    }

                }else{
                lapCounter ++;
                lapNumber.setText("Lap Number: " + lapCounter);
                run();
                }
            }

            @Override
            public void onTick(long millisUntilFinished) {
                long min, sec;
                // TODO Auto-generated method stub
                min = millisUntilFinished / (60 * 1000);
                sec = (millisUntilFinished / 1000) % 60;
                String tmr = String.format("%d:%02d", min, sec);
                text.setText("" + tmr);

            }

        };
        timer.start();
        start.setOnClickListener(new View.OnClickListener() {
            //this is my button. start and stop. 
            public void onClick(View v) {
                if (start.getText() == "Stop") {
                    start.setText("Start");
                    lapCounter = 1;
                    start.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);
                    timer.cancel();
                    lapNumber.setText("Lap Number: 1");
                    text.setText("Stopped");
                } else {
                    start.setText("Stop");
                    start.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
                    run();
                }
            }
        });

    } else {
        text.setText("Done!");
        lapCounter = 1;

    }

}

// pop up menu
@Override
public boolean onCreateOptionsMenu(android.view.Menu menu) {
    // TODO Auto-generated method stub
    super.onCreateOptionsMenu(menu);
    MenuInflater blowUp = getMenuInflater();
    blowUp.inflate(R.menu.setup, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // TODO Auto-generated method stub
    switch (item.getItemId()) {
    case R.id.setup:
        Intent i = new Intent("com.ApphHose.runnersTimer.SETUP");
        startActivity(i);
        break;
    case R.id.out:
        finish();
        break;
    }
    return false;
}
}
Was it helpful?

Solution

sec = (millisUntilFinished / 1000) % 60;

Integer divided by integer produces integer, likely rounding error.

sec = (millisUntilFinished / (double) 1000) % 60;

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top