¿Cómo ejecutar CountDownTimer en un servicio en Android?

Quiero un servicio que ejecute CountDownTimer y en cada tick quiero mostrar la cuenta regresiva en una actividad y después de un cierto intervalo reproducir un sonido.

Todo el proceso va bien en una sola actividad, pero durante la llamada entrante la cuenta regresiva no funciona, es por eso que quiero hacer esto usando un servicio.

Alguien puede ayudarme?

gracias por adelantado.

Actualizar…

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(); 

La forma más fácil es probablemente crear un receptor de difusión en su actividad y hacer que el servicio envíe transmisiones al receptor. Aquí hay una lista completa de una clase de servicio con CountDownTimer simplificado.

 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; } } 

Y aquí están las líneas relevantes de una actividad principal:

 @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); } } 

También deberá definir el servicio entre las tags de la aplicación de inicio / final en su archivo de manifiesto.

  

Descargar el código fuente Android Countdown Timer Run In Background

activity_main.xml

       

Timer_Service.java

 package com.countdowntimerservice; import android.app.Service; import android.content.Intent; import android.content.SharedPreferences; import android.os.Handler; import android.os.IBinder; import android.preference.PreferenceManager; import android.support.annotation.Nullable; import android.util.Log; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; public class Timer_Service extends Service { public static String str_receiver = "com.countdowntimerservice.receiver"; private Handler mHandler = new Handler(); Calendar calendar; SimpleDateFormat simpleDateFormat; String strDate; Date date_current, date_diff; SharedPreferences mpref; SharedPreferences.Editor mEditor; private Timer mTimer = null; public static final long NOTIFY_INTERVAL = 1000; Intent intent; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); mEditor = mpref.edit(); calendar = Calendar.getInstance(); simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); mTimer = new Timer(); mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL); intent = new Intent(str_receiver); } class TimeDisplayTimerTask extends TimerTask { @Override public void run() { mHandler.post(new Runnable() { @Override public void run() { calendar = Calendar.getInstance(); simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); strDate = simpleDateFormat.format(calendar.getTime()); Log.e("strDate", strDate); twoDatesBetweenTime(); } }); } } public String twoDatesBetweenTime() { try { date_current = simpleDateFormat.parse(strDate); } catch (Exception e) { } try { date_diff = simpleDateFormat.parse(mpref.getString("data", "")); } catch (Exception e) { } try { long diff = date_current.getTime() - date_diff.getTime(); int int_hours = Integer.valueOf(mpref.getString("hours", "")); long int_timer = TimeUnit.HOURS.toMillis(int_hours); long long_hours = int_timer - diff; long diffSeconds2 = long_hours / 1000 % 60; long diffMinutes2 = long_hours / (60 * 1000) % 60; long diffHours2 = long_hours / (60 * 60 * 1000) % 24; if (long_hours > 0) { String str_testing = diffHours2 + ":" + diffMinutes2 + ":" + diffSeconds2; Log.e("TIME", str_testing); fn_update(str_testing); } else { mEditor.putBoolean("finish", true).commit(); mTimer.cancel(); } }catch (Exception e){ mTimer.cancel(); mTimer.purge(); } return ""; } @Override public void onDestroy() { super.onDestroy(); Log.e("Service finish","Finish"); } private void fn_update(String str_time){ intent.putExtra("time",str_time); sendBroadcast(intent); } } 

MainActivity.java

 package com.countdowntimerservice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import java.text.SimpleDateFormat; import java.util.Calendar; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button btn_start, btn_cancel; private TextView tv_timer; String date_time; Calendar calendar; SimpleDateFormat simpleDateFormat; EditText et_hours; SharedPreferences mpref; SharedPreferences.Editor mEditor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); listener(); } private void init() { btn_start = (Button) findViewById(R.id.btn_timer); tv_timer = (TextView) findViewById(R.id.tv_timer); et_hours = (EditText) findViewById(R.id.et_hours); btn_cancel = (Button) findViewById(R.id.btn_cancel); mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); mEditor = mpref.edit(); try { String str_value = mpref.getString("data", ""); if (str_value.matches("")) { et_hours.setEnabled(true); btn_start.setEnabled(true); tv_timer.setText(""); } else { if (mpref.getBoolean("finish", false)) { et_hours.setEnabled(true); btn_start.setEnabled(true); tv_timer.setText(""); } else { et_hours.setEnabled(false); btn_start.setEnabled(false); tv_timer.setText(str_value); } } } catch (Exception e) { } } private void listener() { btn_start.setOnClickListener(this); btn_cancel.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_timer: if (et_hours.getText().toString().length() > 0) { int int_hours = Integer.valueOf(et_hours.getText().toString()); if (int_hours<=24) { et_hours.setEnabled(false); btn_start.setEnabled(false); calendar = Calendar.getInstance(); simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); date_time = simpleDateFormat.format(calendar.getTime()); mEditor.putString("data", date_time).commit(); mEditor.putString("hours", et_hours.getText().toString()).commit(); Intent intent_service = new Intent(getApplicationContext(), Timer_Service.class); startService(intent_service); }else { Toast.makeText(getApplicationContext(),"Please select the value below 24 hours",Toast.LENGTH_SHORT).show(); } /* mTimer = new Timer(); mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);*/ } else { Toast.makeText(getApplicationContext(), "Please select value", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_cancel: Intent intent = new Intent(getApplicationContext(),Timer_Service.class); stopService(intent); mEditor.clear().commit(); et_hours.setEnabled(true); btn_start.setEnabled(true); tv_timer.setText(""); break; } } private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String str_time = intent.getStringExtra("time"); tv_timer.setText(str_time); } }; @Override protected void onResume() { super.onResume(); registerReceiver(broadcastReceiver,new IntentFilter(Timer_Service.str_receiver)); } @Override protected void onPause() { super.onPause(); unregisterReceiver(broadcastReceiver); } }