Intent.ACTION_HEADSET_PLUG получено, когда начинается действие

Я пытаюсь приостановить воспроизведение музыки, когда гарнитура отключена.

Я создал BroadcastReceiver, который прослушивает намерения ACTION_HEADSET_PLUG и действует на них, когда дополнительное состояние равно 0 (для неподключенного). Моя проблема в том, что мой BroadcastReceiver получает намерение ACTION_HEADSET_PLUG при каждом запуске действия. Это не то поведение, которого я бы ожидал. Я ожидаю, что Intent будет срабатывать только тогда, когда гарнитура подключена или отключена.

Есть ли причина, по которой намерение ACTION_HEADSET_PLUG перехватывается сразу после регистрации получателя в этом IntentFilter? Есть ли четкий способ, которым я могу работать с этой проблемой?

Я бы предположил, что, поскольку музыкальный проигрыватель по умолчанию реализует аналогичные функции, когда гарнитура отключена, это было бы возможно.

Что мне не хватает?

Это регистрационный код

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

Это определение HeadsetConnectionReceiver

public class HeadsetConnectionReceiver extends BroadcastReceiver {

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

}

3 ответа

Решение

Спасибо за ответ, Джейк. Я должен был обновить исходное сообщение, чтобы указать, что я обнаружил проблему, которая у меня была. После небольшого исследования я обнаружил, что намерение ACTION_HEADSET_PLUG транслируется с использованием метода sendStickyBroadcast в Context.

Важная информация удерживается системой после трансляции. Это намерение будет перехвачено всякий раз, когда новый BroadcastReceiver зарегистрирован для его получения. Он запускается сразу после регистрации, содержащей последнее обновленное значение. В случае гарнитуры полезно иметь возможность определить, что гарнитура уже подключена при первой регистрации приемника.

Это код, который я использовал для получения намерения 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;
         }
     }
 }

Я использую другой подход, чтобы остановить воспроизведение, когда гарнитура отключена. Я не хочу, чтобы вы использовали его, поскольку вы уже в порядке, но некоторые другие люди могут найти его полезным. Если вы получите контроль над аудио-фокусом, то Android отправит вам звук с шумом событий, поэтому если вы напишите приемник для этого события, он будет выглядеть

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

Я столкнулся с той же проблемой. Я не уверен, что является причиной этого, но, по крайней мере, в моем тестировании это кажется последовательным, что означает, что вы можете обойти это. Я сделал это, добавив переменную логического члена, которая начинается с true и устанавливается на false в первом onReceive(Context, Intent) вызов. Этот флаг затем контролирует, действительно ли я обрабатываю событие отключения или нет.

Для справки, вот код, который я использую для этого, который доступен здесь в контексте.

private boolean isFirst;

public void onReceive(Context context, Intent intent)
{
    if(!isFirst)
    {
        // Do stuff...
    }
    else
    {
        Log.d("Hearing Saver", "First run receieved.");
        isFirst = false;
    }
}
Другие вопросы по тегам