3
votes

My audio player app is currently listening for ACTION_ACL_DISCONNECTED events, examining the intent for BluetoothDevice.EXTRA_DEVICE, and checking the class of the device to see if it is a BluetoothClass.Device.Major.AUDIO_VIDEO device. If so, then I want to pause playback. Basically, pause when Bluetooth headphones or a car connection disconnects.

However, I'm finding that this is firing for some users who are actually listening some other way. For example, pair to a Bluetooth speaker and listen for a while. Then plug in wired headphones; playback doesn't miss a beat, the Bluetooth speaker is no longer receiving the audio but it IS still connected. If I lose that Bluetooth connection (turn off the speaker or walk out of range), my playback is pausing but I don't want it to because the STREAM_MUSIC audio is actually going to the wired headset.

When I receive an ACTION_ACL_DISCONNECTED, how can I tell if that device is the thing currently receiving the music stream? Is there something on the BluetoothDevice class? Can I query the AudioManager or some other system service to learn which device is receiving the audio stream and compare it to the device I just received a disconnection broadcast for? Any ideas?

UPDATE:

I see AudioManager provides isBluetoothA2dpOn(), isBluetoothScoOn(), isSpeakerphoneOn(), and isWiredHeadsetOn().

This works for my example. if the user has switched from Bluetooth speaker to wired headset, isBluetoothA2dpOn returns False so I can disregard the disconnect event. But what if the user changed from one Bluetooth connection to another? isBluetoothA2dpOn will return True but the ACTION_ACL_DISCONNECTED might be for the device that isn't receiving audio?

1
Thanks for the edit.Robert Nekic

1 Answers

0
votes

You could also instead register a broadcast receiver and play/pause music. Here's my kotlin implementation of my music app used in the car

class BluetoothConnectionStateReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
            val intentAction = intent.action ?: return
            // only interested in BT connection state regardless of other STATE_CHANGED
            BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED -> {
                when (intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, -1)) {
                    BluetoothAdapter.STATE_DISCONNECTED -> {
                        logMessage("STATE_DISCONNECTED")
                        // pause music
                    }
                    BluetoothAdapter.STATE_CONNECTED -> {
                        logMessage("STATE_CONNECTED")
                        // auto play music
                    }
                }
            }
        }
    }
}

Then declare your receiver in your manifest

<receiver
    android:name=".music.player.BluetoothConnectionStateReceiver"
    android:enabled="true">
    <intent-filter>
        <action android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
    </intent-filter>
</receiver>