2010-11-26 18 views
0

Ich habe einen Bildschirm (Activity), der Folgendes ausführt: Er hat eine Umschalttaste, die den Flugzeugmodus umschaltet; es tut es, indem es einen Dienst verwendet, der einen neuen Thread spawnt. Es hat auch einen Knopf, der auf genau die gleiche Weise genau dasselbe tut. Es gibt wirklich nichts Besonderes, wie die Code-Schnipsel unten zeigen. Während alles wie erwartet für die Umschalttaste funktioniert (Flugzeugmodus wechselt zu "Ein", wenn sich das Telefon derzeit nicht im Flugzeugmodus befindet, ändert sich im Flugzeugmodus auf "Aus"), wenn die Schaltfläche angeklickt wird, wechselt der Flugzeugmodus kontinuierlich (Flugzeugmodus wechselt von "Ein" zu "Aus" und zurück zu "Ein" und dann zu "Aus" ...) als ob es in eine Schleife fällt. Nach einigen Recherchen im Internet vermutete ich, dass dies etwas mit der Art und Weise zu tun hatte, wie der Intent/broadcastReceiver für den Telefon-/Dienststatus in Android gefeuert wurde. Der Umschaltknopf hatte zwei Zustände, die effektiv verhinderten, dass die Absicht erneut gesendet wurde. Ist das richtig?? Wenn ja, was wäre der richtige Weg, um den Flugzeugmodus mittels einer Taste (im Gegensatz zu einem Radiobutton oder einem Togglebutton) umzuschalten?Mein Code schaltet den Flugzeugmodus kontinuierlich um

/** 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

Ich ging zurück zu meinem Code und programmierte den Flugzeugmodus programmgesteuert und es begann die gleiche verrückte Sache. Es schien keinen Unterschied zu machen, ob ich einen Hintergrunddienst verwendete oder meine Dienstklasse direkt in der Aktivität verwendete. Natürlich, wenn ich mich nicht für die Absicht registrieren würde, würde diese Schleife nicht passieren; aber dann wird meine Benutzeroberfläche nicht aktualisiert, um die Tatsache widerzuspiegeln, dass sich der Flugzeugmodus geändert hat: intentionFilter = new IntentFilter ("android.intent.action.SERVICE_STATE"); – mobileTofu

Antwort

0

So verfolgt ich den Bug nach unten. Es wird verursacht, indem der OnCheckedChangeListener des ToggleButton den Befehl in meinem Code erneut ausführt. Wenn der Umschaltbefehl zuvor programmgesteuert aufgerufen wurde oder wenn auf die andere Schaltfläche geklickt wurde, führte dies zu einer Änderung des aktivierten Status im ToggleButton, wodurch derselbe Toggle-Befehl ausgeführt wurde, was wiederum zu einer weiteren Überprüfung der Statusänderung führte der toggleButton.

Verwandte Themen