1

I have a countdown timer that counts down the current time which is set by the user. Although, I want to have the ability to access other apps or just go to the home screen of the device while having the countdown timer run and continue to update the textview with the timer left in the countdown. Is there any way to do this? I tried implementing a service which is below but I don't know if this is the right way to accomplish this task, for I did receive an error.

        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_count_down);



//        if (savedInstanceState != null){
//
//        }

        titleTextView = (TextView)findViewById(R.id.titleTextView);
        timeTextView = (TextView)findViewById(R.id.timeTextView);


        Bundle getAlarmInfo = getIntent().getExtras();
        titleOfAlarm = getAlarmInfo.getString("Title");
        totalTime = getAlarmInfo.getString("totalTime");

         number = new BigDecimal(totalTime).toBigInteger();


        actualTimeFiniliazedInMilliSeconds = number.intValue();
        titleTextView.setText(titleOfAlarm);

//        countDown = new CountDownTimer(actualTimeFiniliazedInMilliSeconds, timeInterval);

//        new UpdateCountDownTime().execute();


        countDown = new CountDownTime(actualTimeFiniliazedInMilliSeconds, timeInterval);
        countDown.start();
//        startService(new Intent(getApplicationContext(), CountDown.class));

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_count_down, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    public class CountDownTime extends CountDownTimer {


        /**
         * @param millisInFuture    The number of millis in the future from the call
         *                          to {@link #start()} until the countdown is done and {@link #onFinish()}
         *                          is called.
         * @param countDownInterval The interval along the way to receive
         *                          {@link #onTick(long)} callbacks.
         */
        public CountDownTime(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long millisUntilFinished) {



            long millis = millisUntilFinished;
            hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
                    TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
                    TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));


            timeTextView.setText(hms);
        }

        @Override
        public void onFinish() {
            Intent goBack = new Intent(CountDownAct.this, ListOfAlarms.class);
        startActivity(goBack);
            finish();
        }




    }

    @Override
    protected void onPause() {
        super.onPause();
        timeTextView.setText(hms);





    }



//    public class CountDown extends Service{
//
//        public  CountDown () {
//
//        }
//
//        @Override
//        public IBinder onBind(Intent intent) {
//            return null;
//        }
//
//        @Override
//        public void onCreate() {
//            super.onCreate();
//
//            countDown = new CountDownTime(actualTimeFiniliazedInMilliSeconds, timeInterval);
//            countDown.start();
//        }
//    }
leonardo
  • 93
  • 2
  • 10

2 Answers2

4

You need to use service and broadcast receiver . I have created some example for broadcast receiver for you .

Check it and let me know if you have some issues.

Create a service :TimerService.java

 @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //Initialize and start the counter
        countDown = new HokusFocusCountDownTimer(timeDifference, 1000);

            countDown.start();

        return super.onStartCommand(intent, flags, startId);
    }

In MainActivity.java

/*
    * This is used to receive the updated time from broadcast receiver
    * */
    private final BroadcastReceiver timeBroadCaster = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //method used to update your GUI fields
            updateGUI(intent);
        }
    };


    private void updateGUI(Intent intent) {

        AppLog.showLog("Update UI", "Timer Stopped");

        if (intent.getExtras() != null) {

            String focusHMS = intent.getStringExtra(Constants.HOCUS_FOCUS_TIMER);
            focusMilliSecond = intent.getLongExtra(Constants.HOCUS_FOCUS_TIMER_MILLI_SECOND, 0);
            txtFocusHourTimer.setText("" + focusHMS);
        }
    }


    @Override
    public void onResume() {
        super.onResume();
        registerReceiver(timeBroadCaster, new IntentFilter(
                HokusFocusCountDownTimer.COUNTDOWN_BROADCAST_RECEIVER));


    }

    @Override
    public void onPause() {
        super.onPause();
        try {
            unregisterReceiver(timeBroadCaster);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

Hope my answer would be helpful to you

c__c
  • 1,574
  • 1
  • 19
  • 39
1

Actually you need Alarm Manager + Broadcast Receiver

Your Alarm Manager is the one incharge for the countdown while your Broadcast Receiver will wait for the Alarm Manager signal.

EDIT

The full code can be downloaded here in GUI updater repo. enter image description here

Example Snippet

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="io.github.ecobin.gui_refresh_by_time" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".UpdateService"
            android:enabled="true"
            android:exported="true" >
        </service>
    </application>

</manifest>

MainActivity

    public class MainActivity extends Activity {

        public static final String[] WORD_BANK = {"Hello World!", "Ice cream", "Soda", "Cake", "Apple"};
        public static final int TIMER = 10; // 10 seconds timer.
        public TextView textView;

        IntentFilter fil;
        BroadcastReceiver receiver;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textView = (TextView) findViewById(R.id.hello_world);

            fil = new IntentFilter("mybroadcast");
            receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    Log.i(">>>>>>>>>>>", "Updating UI!");
                    updateGUI();
                }
            };

            AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
            Intent in = new Intent(this, UpdateService.class);
            PendingIntent pending = PendingIntent.getService(this, 1234, in, 0);

            manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000 * TIMER, 1000 * TIMER, pending);
        }

        @Override
        protected void onPause() {
            super.onPause();
            unregisterReceiver(receiver);
        }

        @Override
        protected void onResume() {
            super.onResume();
            registerReceiver(receiver, fil);
        }


// MORE CODE HERE......

        public void updateGUI() {
            int randomNumber = (int) (Math.random() * WORD_BANK.length);
            textView.setText(WORD_BANK[randomNumber]);
        }
    }
neferpitou
  • 1,642
  • 2
  • 20
  • 26
  • where would I put my public countdown class – leonardo Jul 21 '15 at 03:54
  • In my Example I am using AlarmManager instead of Countdown Class, the advantage of AlarmManager is that >> It will still count even if you are not opening your app. – neferpitou Jul 21 '15 at 03:58
  • do you know how to get the alarm manager time value to display in a textview. The application is supposed to recieve an amount of time which will count down, the code is working but I need it to get the value of alarm manager and put it to the textview – leonardo Jul 22 '15 at 19:36
  • hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), // TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), // TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))); // this is the code which transforms milliseconds into readable time values – leonardo Jul 22 '15 at 19:38