JavascriptProva

martedì 2 agosto 2016

Aggiunta dei listener, della chiusura del Service alla rimozione del recent Task, e correzione dell'errore di startService per ottenere un vero service Foreground.

Come terzo passaggio, sistemiamo il listener dello status del Service, a seconda che l'alarm sia on o off.

Scrivo l'interfaccia, la variabile e il setter.
 public interface OnAlarmChangeListener {
  public void AlarmChange();
 }
OnAlarmChangeListener onAlarmChangeListener;
 public void setOnAlarmChangeListener(OnAlarmChangeListener listener){
  onAlarmChangeListener=listener;
 }
Quindi devo impostare una variabile booleana per il Service che dica se l'alarm è on o off:
boolean alarmOn;
...e devo vedere dove questa variabile cambia, in modo da piazzarci un innesco dell'evento AlarmChange:

in startTime:
 public void startTime(){
  Runnable runnable=new Runnable(){

   @Override
   public void run() {
    Intent intent =new Intent(getApplicationContext(),Telefono.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    
   }
   
  };
  handler.postDelayed(runnable, 7000);
  alarmOn=true;
  if(onAlarmChangeListener!=null)onAlarmChangeListener.AlarmChange();


in stopTime:
 public void stopTime(){
  handler.removeCallbacksAndMessages(null);
  alarmOn=false;
  if(onAlarmChangeListener!=null)onAlarmChangeListener.AlarmChange();
 }
Oltre a notificare lo stato dell'Alarm quando questo cambia, è il caso di notificarlo quando si setta il listener.
Per questo modifico il setter:
 public void setOnAlarmChangeListener(OnAlarmChangeListener listener){
  onAlarmChangeListener=listener;
  onAlarmChangeListener.AlarmChange();
 }
Ora vado a gestire l'evento in MainActivity:
  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   LocalBinder bnd=(LocalBinder)service;
   mService=bnd.getService();
   mBound=true;
   mService.setOnAlarmChangeListener(new OnAlarmChangeListener(){

    @Override
    public void AlarmChange() {
     // TODO Auto-generated method stub
     
    }
    
   });
E ora si imposta l'aspetto di MainActivity a seconda che l'alarm sia on o off. Quel circoletto rosso l'ho chiamato in xml "semaforo" e serve a indicare visivamente se l'alarm è attivo o no.
Lo istanzio...
View semaforo;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  semaforo=(View)findViewById(R.id.semaforo);
   mService.setOnAlarmChangeListener(new OnAlarmChangeListener(){

    @Override
    public void AlarmChange() {
     if(mService.alarmOn){
      semaforo.setBackgroundResource(R.drawable.tondinoverde);
     }
     else {
      semaforo.setBackgroundResource(R.drawable.tondinorosso);
     }
      
     
    }
    
   });
Ma oltre al semaforo mi interessa anche attivare e disattivare i pulsanti a seconda che siano utili o inutili, disattivando il tasto "Attiva" se l'alarm è attivato, e il tasto "Disattiva" se l'alarm è disattivato:
   mService.setOnAlarmChangeListener(new OnAlarmChangeListener(){

    @Override
    public void AlarmChange() {
     if(mService.alarmOn){
      semaforo.setBackgroundResource(R.drawable.tondinoverde);
      bttAttiva.setEnabled(false);
      bttDisattiva.setEnabled(true);
     }
     else {
      semaforo.setBackgroundResource(R.drawable.tondinorosso);
      bttAttiva.setEnabled(true);
      bttDisattiva.setEnabled(false);
     }
      
     
    }
    
   });
E proviamo...

Funziona!

Una cosa importante è che il TimerService si disattivi qualora venga chiusa l'applicazione.
Per fare in modo che allo swipe dalla finestra delle app recenti si elimini tutto c'è questo metodo nel Service:
 @Override
 public void onTaskRemoved(Intent rootIntent){
  stopSelf();
 }
Sperimentiamola.

Sì, okay.
E ho scoperto anche un'altra cosa fondamentale: che se non inserisco startService quando apro il service, questo non è foreground, in quanto sparisce con la sparizione delle activities..
Ecco la correzione in onStart di MainActivity:
 @Override
 public void onStart(){
  super.onStart();
  
  Intent intent=new Intent(this,TimerService.class);
  startService(intent);
  bindService(intent,mConnection,Service.BIND_AUTO_CREATE);
 }

Nessun commento:

Posta un commento