2016-09-27 73 views
0

所以我有一個代碼與CountDownTimer現在工作。但我需要把這個放在服務當然在後臺運行。 我不知道該怎麼做,我試過沒有成功。android - 實現倒計時工作服務

這是我的課倒計時

public class CountDown { 

//Interface a ser implementada por um listener 
public interface CountDownListener { 
    //Chamado quando o valor de secondsLeft é alterado, 
    //quando for decrementado ou incrementado. 
    void onChange(long timeLeft); 
    //Chamado quando o contador chegar ao fim. 
    void onEnd(); 
} 

private long fromSeconds; 
private long secondsLeft; 
private CountDownListener listener; 
private boolean isCounting = false; 

//Valor em milissegundos de um segundo. 
private static final long ONE_SECOND = 1000; 
private static final int MSG = 1; 

//Constrói o contador com o valor inicial de segundos. 
public CountDown(long fromSeconds){ 

    this.fromSeconds = fromSeconds; 
    handler = new CountDownHandler(this); 
} 

//Inicia a contagem, a partir do valor inícial. 
public synchronized void start(){ 
    if(isCounting){ 
     return;//ou talvez lançar uma excepção 
    } 
    isCounting = true; 
    secondsLeft = fromSeconds; 
    handler.sendMessage(handler.obtainMessage(MSG)); 
} 

//Pára a contagem. 
public synchronized void stop(){ 
    if(!isCounting){ 
     return;//ou talvez lançar uma excepção 
    } 
    isCounting = false; 
    handler.removeMessages(MSG); 
} 

//Retoma a contagem. 
public synchronized void resume(){ 
    if(isCounting || secondsLeft == 0){ 
     return;//ou talvez lançar uma excepção 
    } 
    isCounting = true; 
    handler.sendMessageDelayed(handler.obtainMessage(MSG), ONE_SECOND); 
} 

//Incrementa o valor do contador. 
public synchronized long increaseBy(long fromSeconds){ 
    secondsLeft += fromSeconds; 
    return secondsLeft; 
} 

//true se o contador estiver contando. 
public boolean isCounting(){ 
    return isCounting; 
} 

//Guarda um listener. 
public void setCountDownListener(CountDownListener listener){ 
    this.listener = listener; 
} 

//Método para formatar um valor em segundos em algo tipo "mm:ss" ou "HH:mm:ss". 
public static String secondsToString(long seconds, String format){ 
    return DateFormat.format(format, seconds * ONE_SECOND).toString(); 
} 

private final Handler handler; 

//Handler para controlar o contador 
private static class CountDownHandler extends Handler 
{ 

    private final WeakReference<CountDown> countDownWeakReference; 

    private CountDownHandler(CountDown countDownInstance) { 
     countDownWeakReference = new WeakReference<>(countDownInstance); 
    } 

    @Override 
    public void handleMessage(Message msg) { 

     CountDown countDown = countDownWeakReference.get(); 
     if(countDown == null){ 
      return; 
     } 

     synchronized (countDown) { 

      //Guarda o instante em que inicia o processamento. 
      long tickStart = SystemClock.elapsedRealtime(); 

      //Se tiver sido parado sai. 
      if(!countDown.isCounting){ 
       return; 
      } 

      //Notifica o listener com o segundos que faltam para terminar. 
      if (countDown.listener != null) { 
       countDown.listener.onChange(countDown.secondsLeft); 
      } 

      //O contador chegou ao fim, notifica o listener. 
      if (countDown.secondsLeft == 0) { 
       countDown.isCounting = false; 
       if (countDown.listener != null) { 
        countDown.listener.onEnd(); 
       } 
      } else { 
       //decrementa o contador. 
       countDown.secondsLeft--; 

       //Obtém o tempo para o próximo decremento. 
       //Leva em conta o tempo gasto no processamento, 
       //principalmente o eventualmente gasto pela implementação 
       // do método onChange() no listener. 
       long delay = ONE_SECOND - (SystemClock.elapsedRealtime() - tickStart); 

       //Se o tempo gasto for superior a um segundo, ajusta-o para o próximo. 
       //Se o tempo gasto no método onChange() for próximo ou 
       // superior a um segundo ele só será chamado no próximo. 
       while(delay < 0){ 
        countDown.secondsLeft--; 
        delay += ONE_SECOND; 
       } 
       //Garante o término se o tempo for excedido 
       if(countDown.secondsLeft < 0){ 
        countDown.listener.onEnd(); 
       }else { 
        //Agenda o próximo decremento. 
        sendMessageDelayed(obtainMessage(MSG), delay); 
       } 
      } 
     } 
    } 
};} 

隨着第二類

public CountDownBehavior(long alarmTime, String displayFormat){ 

    //Valor em segundos no qual deve ser chamado onAlarm(). 
    this.alarmTime = alarmTime; 
    //Formato da string passada ao displayTimeLeft(). 
    this.displayFormat = displayFormat; 
} 

@Override 
public void onChange(long timeLeft) { 
    //Aqui é implementado o comportamento que queremos ter enquanto 
    //o CountDown "conta". 

    //Deve informar quando chegar a altura de accionar o alarma. 
    if(timeLeft == alarmTime) 
    { 
     onAlarm(); 
    } 
    //Informa o valor actual do contador, com o formato indicado por displayFormat. 
    displayTimeLeft(CountDown.secondsToString(timeLeft, displayFormat)); 

} 

//Metodos a implementar em resposta ao comportamento. 
protected abstract void onAlarm(); 
protected abstract void displayTimeLeft(String timeLeft);} 

而且從MyActivity

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

    textView = (TextView)findViewById(R.id.textView); 

    createNotification(); 

    //Cria o contador com 1 minuto 
    countDown = new CountDown(TIME); 

    //Cria e atribui um CountDownBehavior ao contador 
    countDown.setCountDownListener(new CountDownBehavior(ALARM, "mm:ss") { 
     @Override 
     public void onEnd() { 
      mBuilder.mActions.clear(); 
      mBuilder.setOngoing(false); 
      mBuilder.setContentText("Seu tempo acabou."); 
      mNotifyMgr.notify(mNotificationId, mBuilder.build()); 
      //mNotifyMgr.cancel(mNotificationId); 
     } 

     @Override 
     protected void onAlarm() { 
      alarmMethodwithCount(); 
     } 

     @Override 
     protected void displayTimeLeft(String timeLeft) { 
      mBuilder.setContentText(timeLeft + " restante"); 
      mNotifyMgr.notify(mNotificationId, mBuilder.build()); 
      textView.setText(timeLeft); 
     } 
    }); 

    alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE); 
    countDown.start(); 
    alarmMethod(); 
} 

回答

0

基於有您在您的文章中提供的信息是最重要的研究使用IntentService而不是服務?這是一個很好的鏈接https://developer.android.com/training/run-background-service/create-service.html。定時器到期時,您的應用程序的serviceIntent可以發送廣播。你的UI線程會實現一個廣播監聽器來更新UI。

+0

他們之間有什麼不同? –

+0

無論你使用哪一種都取決於你提供的信息。 – MrMagoo

+0

基本上我需要把這個代碼在後臺工作,當用戶完成活動時,看看運行時間。 –