2010-11-26 2 views
0

J'ai un écran (Activité) qui fait ce qui suit: il a un bouton bascule qui bascule le mode avion; il le fait en utilisant un service qui engendre un nouveau thread. Il a aussi un bouton qui fait exactement la même chose exactement de la même manière. Il n'y a vraiment rien d'extraordinaire comme le montrent les extraits de code ci-dessous. Alors que tout fonctionne comme prévu pour le bouton bascule (le mode avion passe à "on" si actuellement le téléphone n'est pas en mode avion, passe à "off" si actuellement en mode avion), lorsque le bouton est cliqué, le mode avion bascule (Le mode avion passe de "on" à "off" et revient à "on" puis à "off" ...) comme s'il tombait en boucle. Après quelques recherches sur internet, je soupçonnais que cela avait quelque chose à voir avec la façon dont l'intention/broadcastReceiver pour l'état de téléphone/service a été tiré dans Android; comme le bouton bascule avait deux états qui ont effectivement empêché l'intention d'être diffusé à nouveau. Est-ce correct?? Si oui, quelle serait la bonne façon de basculer en mode avion en utilisant un bouton (par rapport à un bouton radio ou un bouton bascule)?Mon code bascule en mode avion en continu

/** Handler for the button. */ 
runToggleAirplaneModeServiceBtn.setOnClickListener(new OnClickListener() { 
@Override 
public void onClick(View v) { 
    startService(new Intent(SleepScheduleController.this, AirplaneModeService.class)); 
} 
}); 
/** Handler for the toggle button. */ 
airplaneModeToggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
@Override 
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
    startService(new Intent(SleepScheduleController.this, AirplaneModeService.class)); 
} 
}); 
/** In the same screen as the toggle button and the button. 
* Need this to update the state of the toggle button once 
* the toggling command is executed. 
*/ 
intentFilter = new IntentFilter("android.intent.action.SERVICE_STATE"); 
receiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     displayAirplaneMode(); 
    }}; 
registerReceiver(receiver, intentFilter); 

private void displayAirplaneMode() { 
    if(airplaneModeToggler.isInAirplaneMode()){ 
     airplaneModeToggleButton.setChecked(true); 
     airplaneModeTextView.setText(R.string.airplane_mode_on); 
    }else{ 
    airplaneModeToggleButton.setChecked(false); 
    airplaneModeTextView.setText(R.string.airplane_mode_off); 
    } 
} 

/** Code snippet in AirplaneModeService*/ 
@Override 
public void onCreate() { 
    airplaneModeToggler = new AirplaneModeToggler(this); 
    Thread mThread = new Thread(null, airplaneModeToggleTask, "AirplaneModeToggleTask"); 
    mThread.start(); 
} 

private Runnable airplaneModeToggleTask = new Runnable() { 
    @Override 
    public void run() { 
     airplaneModeToggler.toggle(null); 
     AirplaneModeService.this.stopSelf(); 
    } 
}; 

/** Code snippet in the Utility class used by AirplaneModeService.*/ 
public Boolean toggleAirplaneMode(Boolean enabling) { 
    boolean _enabling = enabling == null ? !isInAirplaneMode() : enabling.booleanValue(); 
Settings.System.putInt(mContext.getContentResolver(), 
      Settings.System.AIRPLANE_MODE_ON, 
      _enabling ? AIRPLANE_MODE_ON : AIRPLANE_MODE_OFF); 
    Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 
    intent.putExtra("state", _enabling); 
    mContext.sendBroadcast(intent); 
    return _enabling; 
} 
+0

Je suis revenu à mon code et ai programmé le mode avion par programme et il a commencé la même chose en boucle. Cela ne semblait pas faire de différence si j'utilisais un service d'arrière-plan ou utilisais directement ma classe d'utilité dans l'activité. Bien sûr, si je ne me suis pas inscrit à l'intention, cette boucle ne se produirait pas; mais alors mon interface utilisateur ne se mettra pas à jour pour refléter le fait que le mode Avion a changé: intentFilter = new IntentFilter ("android.intent.action.SERVICE_STATE"); – mobileTofu

Répondre

0

J'ai donc détecté le bogue. Il est provoqué par le OnCheckedChangeListener du toggleButton qui ré-exécute la commande dans mon code. Dites si la commande toggling était précédemment appelée par programme, ou en cliquant sur l'autre bouton, cela provoquerait le changement de l'état vérifié sur toggleButton, qui exécuterait par la suite la même commande toggling, ce qui entraînerait un autre changement d'état le toggleButton.