最近接到一个需求,需求的内容是:看视频时拔出耳机,视频暂停播放;插入耳机,视频继续播放。
首先我们分析下这个需求,最重要是监听耳机的插拔状态。然后耳机又分为两种:有线耳机和蓝牙耳机,也就是我们要通过广播的方式监听这两种插拔状态,同时还要考虑着两种耳机同时连接时哪个优先收到音频声音呢?大家可以先想想。
动态注册广播监听
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()
...
}
}
}
}
}
最后,两种耳机同时连接时哪个优先收到音频声音呢?上面的代码一测试你就会发现,有线耳机优先于蓝牙耳机。