Search code examples
androidandroid-service

How to run CountDownTimer in a Service in Android?


I want a service which runs a CountDownTimer and in every tick I want to show the countdown in a Activity and after some interval play a sound.

All the process are going fine in a single Activity but during incoming call the countdown not working that's why I want to do this using a Service.

Can anybody help me?

thanks in advance.

Update...

mCountDownTimer = new CountDownTimer(mTimerDuration, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                if (mTimerDuration > 0) {
                    mDurationCount += 1000;
                    showCountDown(
                            ActivityA.this,
                            (mSimpleDateFormat.format(mTimerDuration
                                    - mDurationCount)));
                    if (mDurationCount == mTimerDuration) {
                        if (mRepeatTime > 1) {
                            startRepeatTimer();
                        }
                        finishTimer();
                    }
                }
            }

            @Override
            public void onFinish() {
            }
        }.start();

Solution

  • The easiest way is probably to create a broadcast receiver in your activity and have the service send broadcasts to the receiver. Here's a full listing for a service class with a simplified CountDownTimer.

    package com.example.cdt;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.CountDownTimer;
    import android.os.IBinder;
    import android.util.Log;
    
    public class BroadcastService extends Service {
    
        private final static String TAG = "BroadcastService";
    
        public static final String COUNTDOWN_BR = "your_package_name.countdown_br";
        Intent bi = new Intent(COUNTDOWN_BR);
    
        CountDownTimer cdt = null;
    
        @Override
            public void onCreate() {       
                super.onCreate();
    
                Log.i(TAG, "Starting timer...");
    
                cdt = new CountDownTimer(30000, 1000) {
                    @Override
                    public void onTick(long millisUntilFinished) {
    
                        Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
                        bi.putExtra("countdown", millisUntilFinished);
                        sendBroadcast(bi);
                    }
    
                    @Override
                    public void onFinish() {
                        Log.i(TAG, "Timer finished");
                    }
                };
    
                cdt.start();
            }
    
            @Override
            public void onDestroy() {
    
                cdt.cancel();
                Log.i(TAG, "Timer cancelled");
                super.onDestroy();
            }
    
            @Override
            public int onStartCommand(Intent intent, int flags, int startId) {       
                return super.onStartCommand(intent, flags, startId);
            }
    
            @Override
            public IBinder onBind(Intent arg0) {       
                return null;
            }
    }
    

    And here are the relevant lines from a main activity:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        startService(new Intent(this, BroadcastService.class));
        Log.i(TAG, "Started service");
    }
    
    private BroadcastReceiver br = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {            
            updateGUI(intent); // or whatever method used to update your GUI fields
        }
    };
    
    @Override  
    public void onResume() {
        super.onResume();        
        registerReceiver(br, new IntentFilter(BroadcastService.COUNTDOWN_BR));
        Log.i(TAG, "Registered broacast receiver");
        }
    
    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(br);
        Log.i(TAG, "Unregistered broacast receiver");
    }
    
    @Override
    public void onStop() {
        try {
            unregisterReceiver(br);
        } catch (Exception e) {
            // Receiver was probably already stopped in onPause()
        }
        super.onStop();
    }
    @Override
    public void onDestroy() {        
        stopService(new Intent(this, BroadcastService.class));
        Log.i(TAG, "Stopped service");
        super.onDestroy();
    }
    
    private void updateGUI(Intent intent) {
        if (intent.getExtras() != null) {
            long millisUntilFinished = intent.getLongExtra("countdown", 0);
            Log.i(TAG, "Countdown seconds remaining: " +  millisUntilFinished / 1000);            
        }
    }
    

    You'll also need to define the service between the start/end application tags in your manifest file.

    <service android:name=".BroadcastService" />