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