【问题标题】:Intent.ACTION_HEADSET_PLUG is received when activity starts活动开始时收到 Intent.ACTION_HEADSET_PLUG
【发布时间】:2010-11-03 23:03:28
【问题描述】:

我正在尝试暂停拔下耳机时正在播放的音乐。

我创建了一个 BroadcastReceiver,它监听 ACTION_HEADSET_PLUG 意图,并在 state extra 为 0(用于拔出)时对其进行操作。我的问题是,每当活动开始时,我的 BroadcastReceiver 都会收到 ACTION_HEADSET_PLUG 意图。这不是我所期望的行为。我希望只有在插入或拔出耳机时才会触发 Intent。

是否有理由在使用该 IntentFilter 注册接收器后立即捕获 ACTION_HEADSET_PLUG Intent?有没有明确的方法可以解决这个问题?

我认为,由于默认音乐播放器在拔下耳机时会实现类似的功能,因此这是可能的。

我错过了什么?

这是注册码

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");
    }

}

【问题讨论】:

    标签: android


    【解决方案1】:

    感谢杰克的回复。我应该更新原始帖子以表明我发现了我遇到的问题。经过一番研究,我发现 ACTION_HEADSET_PLUG Intent 是使用 Context 中的sendStickyBroadcast 方法广播的。

    Sticky Intent 在广播后由系统持有。每当注册一个新的 BroadcastReceiver 以接收它时,就会捕获该 Intent。它在包含最后更新值的注册后立即触发。对于耳机,这有助于在您首次注册接收器时确定耳机是否已插入。

    这是我用来接收 ACTION_HEADSET_PLUG Intent 的代码:

     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;
             }
         }
     }
    

    【讨论】:

    • 另一种解决方案是使用 removeStickyBroadcast() 方法,用于在服务正在播放时不能忽略命令的情况。
    • 我认为更好的解决方案是在您的接收器中使用isInitialStickyBroadcast()。这不需要定义删除粘性广播的权限,并且不会对其他应用程序造成副作用。
    • 你好,道格。我可能误解了这个意图,android 拥有的接收器系统。但是您如何访问 isPlaying,我会认出它们在您的原始活动中? :-)
    • Anders:很抱歉,我花了这么长时间才找到您的问题。我在服务中定义我的 HeadsetBroadcastReceiver。 isPlaying 方法在 Service 中定义。
    • Doug 我已经解决了检查 isInitialStickyBroadcast() 的问题 :) 无论如何感谢这个问题
    【解决方案2】:

    当耳机拔出时,我使用不同的方法来停止播放。我不希望你使用它,因为你已经很好了,但其他一些人可能会觉得它很有用。如果你控制了音频焦点,那么 Android 会向你发送一个事件音频变得嘈杂,所以如果你为这个事件编写一个接收器,它看起来像

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

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。我不确定是什么原因造成的,但至少在我的测试中它似乎是一致的,这意味着你可以解决它。我通过添加一个布尔成员变量来做到这一点,该变量以 true 开头,并在第一次 onReceive(Context, Intent) 调用时设置为 false。然后,此标志控制我是否实际处理拔出事件。

      供您参考,这是我用来执行此操作的代码,可在上下文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;
          }
      }
      

      【讨论】:

      • 按照另一条评论的建议,更好地使用 isInitialStickyBroadcast()。
      猜你喜欢
      • 2016-12-23
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 2018-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多