androidandroid-activitytimerthredds

Show timer in activity


I have created a timer in activity, some times it works perfectly but some time it run faster than the specified execution period.Here is my code

public void StartTimer()
{try
    {
    // Start Timer

            Log.e("", "time1 : " + AppConstants.TOTALTIME);

            int millisUntilFinished = Integer.parseInt(AppConstants.TOTALTIME) * 60000;
            final String hh = String.format("%02d",(int) ((millisUntilFinished / (1000 * 60 * 60)) % 24));
            final String mm = String.format("%02d", (millisUntilFinished / 60000) % 60);
            final String ss = (String.format("%02d",(millisUntilFinished % 60000 / 1000)));

            Log.e("", "time : " + hh + ":" + mm + ":" + ss);
            txtTime.setText(hh + ":" + mm + ":" + ss);
            txtTimeSpent.setText("00:00:00");
            t = new Timer();
            t.scheduleAtFixedRate(new TimerTask() {

                @Override
                public void run() {
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {

                            if (txtTimeSpent.getText().toString().trim().equalsIgnoreCase(hh + ":" + mm + ":" + ss)) 
                            {
                                if (t != null)
                                    t.cancel();

                                Calendar c = Calendar.getInstance();
                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss a");
                                String enddate = sdf.format(c.getTime());

                                AppConstants.ENDTIME = enddate;

                                Intent intent = new Intent(act,TestSubmissionActivity.class);
                                startActivity(intent);
                                finish();
                            } 
                            else 
                            {
                                txtTimeSpent.setText(" "
                                        + String.format("%02d", hrSpent) + ":"
                                        + String.format("%02d", minSpent) + ":"
                                        + String.format("%02d", secSpent));
                                AppConstants.TIMETAKEN = txtTimeSpent.getText().toString().trim();
                                secSpent++;

                                if (secSpent == 60)
                                {
                                    txtTimeSpent.setText(" "
                                            + String.format("%02d", hrSpent) + ":"
                                            + String.format("%02d", minSpent) + ":"
                                            + String.format("%02d", secSpent));
                                    AppConstants.TIMETAKEN = txtTimeSpent.getText().toString().trim();
                                    secSpent = 0;
                                    minSpent++;

                                    if (minSpent == 60) 
                                    {
                                        txtTimeSpent.setText(" "
                                                + String.format("%02d", hrSpent)
                                                + ":"
                                                + String.format("%02d", minSpent)
                                                + ":"
                                                + String.format("%02d", secSpent));
                                        AppConstants.TIMETAKEN = txtTimeSpent.getText().toString().trim();
                                        minSpent = 0;
                                        hrSpent++;
                                    }
                                }

                                CountTimeSpend++;
                                if(CountTimeSpend==5)
                                {
                                    CountTimeSpend=0;
                                    try {

                                        Date d=sdfDate.parse((sdfDate.format(c.getTime())+" "+txtTimeSpent.getText().toString().trim()));

                                        new AsyncSaveTimeSpend().execute(d);
                                    } catch (ParseException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                    });
                }
            }, 0, 1000);

    }
    catch(Exception e)
   {
     e.printStackTrace();
   }
}

StartTimer() is get called inside a AsyncTask. and here is ondestroy()

@Override
protected void onDestroy() {
    super.onDestroy();

    if (t != null) {
        t.cancel();
        t.purge();
        t = null;
    }
}

Solution

  • Found solution to my problem. Don't know what was wrong in previous approach, but CountDownTimer works perfectly. Here is my solution

    public void StartTimer()
    {
        final long millisTotalTime = Integer.parseInt(AppConstants.TOTALTIME) * 60000;
        hh = String.format("%02d",(int) ((millisTotalTime / (1000 * 60 * 60)) % 24));
        mm = String.format("%02d", (millisTotalTime / 60000) % 60);
        ss = (String.format("%02d",(millisTotalTime % 60000 / 1000))); 
    
        Log.e("", "time : " + hh + ":" + mm + ":" + ss);
        txtTime.setText(hh + ":" + mm + ":" + ss);
        txtTimeSpent.setText("00:00:00");
        millisSpent=0;
    
         countDownTimer=new CountDownTimer(millisTotalTime, 1000) 
         {
            @Override
            public void onTick(long millisUntilFinished) 
            {
                millisSpent=millisTotalTime-millisUntilFinished;
    
                hh = String.format("%02d",(int) ((millisSpent / (1000 * 60 * 60)) % 24));
                mm = String.format("%02d", (millisSpent / 60000) % 60);
                ss = (String.format("%02d",(millisSpent % 60000 / 1000)));
    
                txtTimeSpent.setText( hh + ":"+ mm + ":"+ ss);
                System.out.println("Time Spent=="+txtTimeSpent.getText());
    
                AppConstants.TIMETAKEN = txtTimeSpent.getText().toString().trim();
    
                CountTimeSpend++;
                if(CountTimeSpend==5)
                {
                    CountTimeSpend=0;
                    try {
                        Date d=sdfDate.parse((sdfDate.format(c.getTime())+" "+txtTimeSpent.getText().toString().trim()));
                        new AsyncSaveTimeSpend().execute(d);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            }
    
            @Override
            public void onFinish() {
    
                Calendar c = Calendar.getInstance();
                String enddate = sdf.format(c.getTime());
                AppConstants.ENDTIME = enddate;
    
                Intent intent = new Intent(act,TestSubmissionActivity.class);
                act.startActivity(intent);
                act.finish();
            }
        }.start();
    }
    

    And if you want to cancel the CountDownTimer before its Specified time then just call countDownTimer.cancel(); Hope it helps some one :)