0

I am trying to create an app which sends sms. As confirmation I requires user to hold down a "Send" button for one second. I am showing a progress bar which acts like countdown timer for them. I wanted to update progress of progress bar every 10 miliseconds and increment it by 1. By this approach I would get 100% progress in exactly 1 second. But I was not able to be that accurate. I have tried, runnables and countdown timers but everything failed.

Right now I am using this "hack" which uses time difference in milis to calculate progress add:

progressBar = (ProgressBar) findViewById(R.id.progressBarSend);
handler = new Handler();
final Runnable runnable = new Runnable() {
    @Override
    public void run() {
        if(progressStatus <= 100) {
            progressStatus += (int)((System.currentTimeMillis() - currentTime)/10f);
            currentTime = System.currentTimeMillis();
            progressBar.setProgress(progressStatus);
            handler.postDelayed(this, 10);
        }else{
            handler.removeCallbacks(this);

        }
    }
};

By this approach I have got +- 200ms accuracy on emulator. Is there any better way to be even more accurate?

Thanks in forward

horin
  • 1,664
  • 6
  • 23
  • 52
  • .... or update the progress bar every 100 miliseconds and increment it by 10. – Phantômaxx Jul 04 '15 at 17:39
  • it wouldnt be as smooth as I wanted. I am targetting API level 10+ so I cant use smoth transitions which are available (if I am correct) from API level 11 – horin Jul 04 '15 at 17:45
  • Wouldn't it be too stressful for the CPU? – Phantômaxx Jul 04 '15 at 17:49
  • I am running it on core i7 4700MQ CPU so I dont think CPU is problem. Anyway my solution dont work on real device it is stucked at 5% progress or so – horin Jul 04 '15 at 18:13
  • Use SystemClock http://developer.android.com/reference/android/os/SystemClock.html – ecle Jul 05 '15 at 05:33

2 Answers2

1

The smoothest progress that I could achieve was by using ObjectAnimator. I also tried with an AsyncTask but the transition wasn't smooth enough in the first 100-200 milliseconds. You can try with this and have a look.

ObjectAnimator animation = ObjectAnimator.ofInt(progressBar, "progress", 100);
animation.setDuration(1000);
animation.start();
Antrromet
  • 15,294
  • 10
  • 60
  • 75
  • unfortunately I cant use this because I am targeting devices from API level 10 and ObjectAnimator was only introduced in API Level 11 – horin Jul 04 '15 at 18:16
  • If you're satisfied with the above code in higher APIs then you can use [NineOldAndroids](http://nineoldandroids.com/). It supports ObjectAnimator that works from API 1 onwards. – Antrromet Jul 04 '15 at 18:18
0

Use CountDownTimer, it takes 2 parameters: 1. HowLong till onFinish is called and end the timer.Eg: 1000ms 2. OnTick to be called at what time.Eg: 10 ms

In OnTick just add code to update the progressbar. Below is an example code which is using a simple ProgressDialog which updates time every 10ms and shows progress from 1 to 100%.

final ProgressDialog progressdialog = ProgressDialog.show(getActivity(), "Will Send SMS", "Please hold on");
final CountDownTimer timer = new CountDownTimer(1000, 10) {
    @Override
    public void onTick(long millisUntilFinished) {
        Log.v("ranjapp", "Ticking " + millisUntilFinished / 10);
        progressdialog.setMessage("Will send SMS in " + millisUntilFinished / 10+" %");
    }

    @Override
    public void onFinish() {
        Log.v("ranjapp", "Countdowntimer onfinish called");
        progressdialog.dismiss();
    }
}.start();

You can change the above from ProgressDialog to any other progress dialogs.

Psypher
  • 10,717
  • 12
  • 59
  • 83
  • I said that I have tried countdowntimer. I have got a lot worse accuracy with it than with runnables and handler – horin Jul 04 '15 at 18:14
  • Frankly 1000ms is too little to be viewed in a progressbar. Rather than programming it you can create a gif image which finishes its cycle in 1 sec, that would be smoother. – Psypher Jul 04 '15 at 18:17
  • unfortunately this also isnt the way because I want the progress bar to go back if it isnt fully loaded and user releases button... I will probably need to think about other way of confirmation – horin Jul 04 '15 at 18:20