I have a screen (Activity) that does the following: it has a toggle button that toggles the airplane mode; it does it by using a service that spawn off a new Thread. It also has a button that does exactly the same thing in exactly the same way. There is really nothing fancy as the code snippets below show. While everything works as expected for the toggle button (airplane mode changes to "on" if currently the phone is not in airplane mode; changes to "off" if currently in airplane mode), when the button is clicked, the airplane mode toggles continuously (airplane mode toggles from "on" to "off" and back to "on" and then to "off"...) as if it falls into a loop. After some research on the internet, I suspected this had something to do with the way the intent/broadcastReceiver for the phone/service state was fired in Android; as the toggle button had two states which effectively prevented the intent from being broadcast again. Is this correct?? If so, what would be the right way of toggling airplane mode using a button (vs. a radiobutton or a togglebutton)?
/** 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;
}