Pregunta

Tengo un (Actividad) que hace lo siguiente pantalla: tiene un botón de activación que activa o desactiva el modo avión; lo hace mediante el uso de un servicio que desovan fuera un nuevo hilo. También tiene un botón que hace exactamente lo mismo exactamente de la misma manera. Realmente no hay nada elegante como los fragmentos de código siguientes muestran. Mientras que todo funciona como se espera para el botón de activación (modo avión cambia a "on" si actualmente el teléfono no está en modo avión, cambios en "off" si actualmente en modo avión), cuando se hace clic en el botón, se alternará modo avión continuamente (cambia el modo de avión de "on" a "off" y volver a "ON" y luego en "off" ...) como si se cae en un bucle. Después de algunas investigaciones en el Internet, sospeché esto tuvo algo que ver con la forma en que la intención / BroadcastReceiver para el estado del teléfono / servicio fue despedido en Android; como el botón de activación tenía dos estados que en la práctica impiden la intención de ser transmitido de nuevo. ¿¿Es esto correcto?? Si es así, ¿cuál sería la forma correcta de alternar el modo avión mediante un botón (frente a un botón de radio o una 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;
}
¿Fue útil?

Solución

Así que rastreó el fallo. Es causada por el OnCheckedChangeListener del ToggleButton re-excuting el comando en mi código. Por ejemplo si el comando de conmutación era conocida anteriormente mediante programación, o haciendo clic en el otro botón, entonces estos causaría el cambio de estado marcado en el ToggleButton, el cual posteriormente ejecutar el mismo comando conmutación, lo que resultaría en una nueva ronda de cambio de estado registrado en la ToggleButton.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top