美文网首页Android开发经验谈Android开发Android技术知识
Android监听耳机插拔状态实现看视频插拔耳机暂停播放

Android监听耳机插拔状态实现看视频插拔耳机暂停播放

作者: VinPin | 来源:发表于2019-01-23 10:57 被阅读2次

    最近接到一个需求,需求的内容是:看视频时拔出耳机,视频暂停播放;插入耳机,视频继续播放。

    首先我们分析下这个需求,最重要是监听耳机的插拔状态。然后耳机又分为两种:有线耳机和蓝牙耳机,也就是我们要通过广播的方式监听这两种插拔状态,同时还要考虑着两种耳机同时连接时哪个优先收到音频声音呢?大家可以先想想。

    动态注册广播监听

    private var isRegisteredHeadsetReceiver = false
    
    override fun onResume() {
      super.onResume()
      //注册广播
      if (!isRegisteredHeadsetReceiver) {
        try {
          val filter = IntentFilter()
          //监听有线耳机的两种方式
          filter.addAction(Intent.ACTION_HEADSET_PLUG)
          filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY)
          //监听蓝牙耳机
          filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)
          registerReceiver(mReceiver, filter)
          isRegisteredHeadsetReceiver = true
        } catch (e: Exception) {
        }
      }
    }
    
    override fun onPause() {
      //注销广播
      if (isRegisteredHeadsetReceiver) {
        try {
          unregisterReceiver(mReceiver)
          isRegisteredHeadsetReceiver = false
        } catch (e: Exception) {
        }
      }
      super.onPause()
    }
    

    监听有线耳机的连接状态

    方式一:监听系统广播Intent.ACTION_HEADSET_PLUG

    通过这种方式,可以监听到耳机连接和断开的状态。

    private var isHeadsetOn = false
    
    private var mReceiver = object : BroadcastReceiver() {
           override fun onReceive(context: Context?, intent: Intent?) {
               val action = intent?.action
               if (TextUtils.equals(action, Intent.ACTION_HEADSET_PLUG)) {
                   if (intent?.hasExtra("state") == true) {
                       if (intent.getIntExtra("state", 2) == 0) {
                           if (isHeadsetOn) {
                               Toast.makeText(mContext, "有线耳机拔出", Toast.LENGTH_SHORT).show()
                               isHeadsetOn = false
                               ...
                           }
                       } else if (intent.getIntExtra("state", 2) == 1) {
                           if (!isHeadsetOn) {
                               Toast.makeText(mContext, "有线耳机插入", Toast.LENGTH_SHORT).show()
                               isHeadsetOn = true
                               ...
                           }
                       }
                   }
               }
           }
    }
    
    @Suppress("DEPRECATION")
    private fun isWiredHeadsetOn(): Boolean {
       val am = getSystemService(Context.AUDIO_SERVICE) as AudioManager
       return am.isWiredHeadsetOn
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
       ...
       isHeadsetOn = isWiredHeadsetOn()
       ...
    }
    
    方式二:监听系统广播AudioManager.ACTION_AUDIO_BECOMING_NOISY

    通过这种方式只能监听到有线和蓝牙耳机的断开的状态,不能监听其连接的状态。很显然满足不了我的需求。

    private var mReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                val action = intent?.action
                if (TextUtils.equals(AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
                    Toast.makeText(mContext, "有线耳机拔出", Toast.LENGTH_SHORT).show()
                    ...
                }
            }
    }
    

    监听蓝牙耳机的连接状态

    监听系统广播BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED,用于广播Headset配置文件的连接状态的更改。

    //首先需要蓝牙的权限,否则无法接收到。
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    
    private var mReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                val action = intent?.action
                if (TextUtils.equals(action, BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
                    val state = intent?.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)
                    when (state) {
                        BluetoothProfile.STATE_CONNECTED -> {
                            Toast.makeText(mContext, "蓝牙耳机连接", Toast.LENGTH_SHORT).show()
                            ...
                        }
                        BluetoothProfile.STATE_DISCONNECTED -> {
                            Toast.makeText(mContext, "蓝牙耳机未连接", Toast.LENGTH_SHORT).show()
                            ...
                        }
                    }
                }
            }
        }
    

    最后,两种耳机同时连接时哪个优先收到音频声音呢?上面的代码一测试你就会发现,有线耳机优先于蓝牙耳机。

    相关文章

      网友评论

        本文标题:Android监听耳机插拔状态实现看视频插拔耳机暂停播放

        本文链接:https://www.haomeiwen.com/subject/szfjjqtx.html