skywalkergonpwnya
skywalkergonpwnya

Reputation: 11

Android CountDownTimer and Runnable

what I'm trying to do: My app connects with a Bluetooth accelerometer and gets acceleration data every 50ms. I want to check for these with a Runnable. And this worked fine. However, for the complete app I added two CountDownTimers:

1) introTimer(), which runs in an AlertDialog and counts down from 3. OnFinish() calls (i) my Runnable, that deals with new acceleration data and (ii) a second timer called

2) mainTimer(), which counts down from 20 and refreshes a TextView on the UI.

My problem is, that my Runnable is only executed once when it is first called. Why is that? Apparently I have not yet understood the threading principles behind this. My next step (probably going to be complicated) is to refresh ImageViews every 50ms (or maybe less often, but still with a relatively high frequency) on the UI, depending on the accelerometer data.

I have thought about deleting the Runnable and putting my calculations in the CountDownTimer, but this might be difficult or inaccurate with the timing/frequency/periods. What do you think?

Here are the code parts. If you think other parts are relevant, I can post them as well:

            startButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                LayoutInflater layoutInflater = getActivity().getLayoutInflater();
                View promptView = layoutInflater.inflate(R.layout.intro_timer_prompt, null);
                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                final TextView introTimer = (TextView) promptView.findViewById(R.id.introTimer);
                builder.setView(promptView);
                AlertDialog alertD = builder.create();
                alertD.show();
                introTimer(introTimer, alertD);
            }

            private void introTimer(final TextView introTimer, final AlertDialog alertD) {
                new CountDownTimer(4*1000, 1000) {
                     public void onTick(long millisUntilFinished) {
                         introTimer.setText( ""+ (millisUntilFinished / 1000)); 
                     }
                     public void onFinish() {
                         alertD.cancel();
                       //  mainTimer();
                         clearArrayLists();
                         mHandler = new Handler();
                         mHandlerTask.run();
                         mainTimer();
                     }
                  }.start();
            }

            private void mainTimer() {
                new CountDownTimer((int)DURATION*1000, 10) {
                     public void onTick(long millisUntilFinished) {
                         //mTimerView.setText("seconds remaining: " + millisUntilFinished / 1000 + ":" + millisUntilFinished / 1000. );
                         long millisecs = Math.round(millisUntilFinished % 1000 / 100);
                         mTimerView.setText("seconds remaining: " + millisUntilFinished / 1000 + ":" + millisecs );
                     }

                     public void onFinish() {
                         String energy = new DecimalFormat("#.##").format(accumulatedKineticEnergy.get(accumulatedKineticEnergy.size()-1));
                         mTimerView.setText("Accumulated Energy is " + energy + " Joule.");
                     }
                  }.start();
            }

        Runnable mHandlerTask = new Runnable() {
        @Override
        public void run() {
            Log.i(TAG, "executed only once :( ");
            if (a_x.size() < DURATION/INTERVAL) {
                try {
                    calcAccList();
                    //...calc things...;
                    mHandler.postDelayed(this, (long) (1000*INTERVAL));
                } catch (Exception e) {
                    e.getMessage();
                }
            }
            else {
                mHandler.removeCallbacks(mHandlerTask);
            }

        }
    };

Upvotes: 1

Views: 809

Answers (1)

greywolf82
greywolf82

Reputation: 22193

A countdown timer doesn't repeat itself when it expires, but you need to start it again. Maybe you can use the AlarmManager in this case to have a better design.

Upvotes: 0

Related Questions