2010-11-03 12 views
10

Estoy intentando poner en pausa la música que se está reproduciendo cuando el auricular está desenchufado.Intent.ACTION_HEADSET_PLUG se recibe cuando comienza la actividad

He creado un BroadcastReceiver que escucha los intentos de ACTION_HEADSET_PLUG y actúa sobre ellos cuando el estado adicional es 0 (para desenchufado). Mi problema es que un intento ACTION_HEADSET_PLUG es recibido por mi BroadcastReceiver cada vez que se inicia la actividad. Este no es el comportamiento que esperaría. Esperaría que la intención se dispare solo cuando el auricular esté enchufado o desenchufado.

¿Hay alguna razón por la cual la intención ACTION_HEADSET_PLUG se detecta inmediatamente después de registrar un receptor con ese IntentFilter? ¿Hay una manera clara de que pueda trabajar con este problema?

Supongo que dado que el reproductor de música predeterminado implementa una funcionalidad similar cuando el auricular está desenchufado, sería posible.

¿Qué me estoy perdiendo?

Este es el código de registro

registerReceiver(new HeadsetConnectionReceiver(), 
       new IntentFilter(Intent.ACTION_HEADSET_PLUG)); 

Ésta es la definición de HeadsetConnectionReceiver

public class HeadsetConnectionReceiver extends BroadcastReceiver { 

    public void onReceive(Context context, Intent intent) { 
     Log.w(TAG, "ACTION_HEADSET_PLUG Intent received"); 
    } 

} 

Respuesta

15

Gracias por la respuesta Jake. Debería haber actualizado la publicación original para indicar que descubrí el problema que estaba teniendo. Después de investigar un poco, descubrí que el intento ACTION_HEADSET_PLUG se transmite usando el método sendStickyBroadcast en contexto.

Intentos persistentes son retenidos por el sistema después de ser transmitidos. Esa intención se detectará cada vez que se registre un nuevo BroadcastReceiver para recibirlo. Se activa inmediatamente después del registro que contiene el último valor actualizado. En el caso de los auriculares, esto es útil para poder determinar que los auriculares ya están enchufados cuando registra por primera vez su receptor.

Este es el código que he utilizado para recibir la Intención ACTION_HEADSET_PLUG:

private boolean headsetConnected = false; 

public void onReceive(Context context, Intent intent) { 
    if (intent.hasExtra("state")){ 
     if (headsetConnected && intent.getIntExtra("state", 0) == 0){ 
      headsetConnected = false; 
      if (isPlaying()){ 
       stopStreaming(); 
      } 
     } else if (!headsetConnected && intent.getIntExtra("state", 0) == 1){ 
      headsetConnected = true; 
     } 
    } 
} 
+0

Una solución alternativa sería utilizar el método removeStickyBroadcast(), para los casos en los que no puede simplemente ignorar los comandos cuando se está ejecutando su servicio. – greg7gkb

+16

Creo que una solución aún mejor es usar [isInitialStickyBroadcast()] (http://developer.android.com/reference/android/content/BroadcastReceiver.html#isInitialStickyBroadcast%28%29) en su receptor. Esto no requiere la definición del permiso para eliminar difusiones adhesivas, y no causará efectos secundarios a otras aplicaciones. – amram99

+0

Hola otra vez Doug. Pude haber malinterpretado algo acerca de este intento, el sistema receptor que tiene Android. Pero, ¿cómo tienes acceso a EsPlaying, reconocería que están en tu actividad original? :-) –

-2

me encontré con el mismo problema. No estoy seguro de qué lo causa, pero al menos en mis pruebas parece ser consistente, lo que significa que puede evitarlo. Hice exactamente eso agregando una variable de miembro booleana que comienza como verdadera, y se establece en falso en la primera llamada onReceive(Context, Intent). Este indicador luego controla si realmente proceso el evento de desconexión o no.

Para su referencia, aquí está el código que uso para hacer precisamente eso, que está disponible en el contexto here.

private boolean isFirst; 

public void onReceive(Context context, Intent intent) 
{ 
    if(!isFirst) 
    { 
     // Do stuff... 
    } 
    else 
    { 
     Log.d("Hearing Saver", "First run receieved."); 
     isFirst = false; 
    } 
} 
+1

Mejor uso isInitialStickyBroadcast() como se sugiere en otro comentario. –

0

utilizo un enfoque diferente para detener la reproducción cuando el auricular se desconecte. No quiero que lo uses porque ya estás bien, pero otras personas pueden encontrarlo útil. Si se obtiene un control de foco de audio, a continuación, Android le enviará un evento de audio convertirse en ruidoso, así que si usted escribe un receptor para este evento que se verá como

public void onReceive(Context context, Intent intent) { 
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) { 
     if (isPlaying()){ 
      stopStreaming(); 
     } 
    } 
} 
Cuestiones relacionadas