Skip to content

Instantly share code, notes, and snippets.

@halilozercan
Created January 16, 2020 13:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save halilozercan/d51c2d2b9e400e53ce62ed200c239b18 to your computer and use it in GitHub Desktop.
Save halilozercan/d51c2d2b9e400e53ce62ed200c239b18 to your computer and use it in GitHub Desktop.
private inner class BluetoothServiceListener : BluetoothProfile.ServiceListener {
// Called to notify the client when the proxy object has been connected to the service.
// Once we have the profile proxy object, we can use it to monitor the state of the
// connection and perform other operations that are relevant to the headset profile.
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
if (profile != BluetoothProfile.HEADSET || bluetoothState == State.UNINITIALIZED) {
return
}
// Android only supports one connected Bluetooth Headset at a time.
bluetoothHeadset = proxy as BluetoothHeadset
updateAudioDeviceState()
}
/**
Notifies the client when the proxy object has been disconnected from the service.
*/
override fun onServiceDisconnected(profile: Int) {
if (profile != BluetoothProfile.HEADSET || bluetoothState == State.UNINITIALIZED) {
return
}
stopScoAudio()
bluetoothHeadset = null
bluetoothDevice = null
bluetoothState = State.HEADSET_UNAVAILABLE
updateAudioDeviceState()
}
}
// Intent broadcast receiver which handles changes in Bluetooth device availability.
// Detects headset changes and Bluetooth SCO state changes.
private inner class BluetoothHeadsetBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (bluetoothState == State.UNINITIALIZED) {
return
}
val action = intent.action
// Change in connection state of the Headset profile. Note that the
// change does not tell us anything about whether we're streaming
// audio to BT over SCO. Typically received when user turns on a BT
// headset while audio is active using another audio device.
if (action == BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED) {
val state = intent.getIntExtra(
BluetoothHeadset.EXTRA_STATE,
BluetoothHeadset.STATE_DISCONNECTED
)
when (state) {
BluetoothHeadset.STATE_CONNECTED -> {
scoConnectionAttempts = 0
updateAudioDeviceState()
}
BluetoothHeadset.STATE_CONNECTING -> {
// No action needed.
}
BluetoothHeadset.STATE_DISCONNECTING -> {
// No action needed.
}
BluetoothHeadset.STATE_DISCONNECTED -> {
// Bluetooth is probably powered off during the call.
stopScoAudio()
updateAudioDeviceState()
}
}
} else if (action == BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED) {
// Change in the audio (SCO) connection state of the Headset profile.
// Typically received after call to startScoAudio() has finalized.
val state = intent.getIntExtra(
BluetoothHeadset.EXTRA_STATE,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED
)
if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
cancelTimer()
if (bluetoothState == State.SCO_CONNECTING) {
bluetoothState = State.SCO_CONNECTED
scoConnectionAttempts = 0
updateAudioDeviceState()
}
} else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
if (isInitialStickyBroadcast) {
return
}
updateAudioDeviceState()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment