3

I've been trying to look for a good solution to detect when headphones are connected in Android regardless of whether they are wired or wireless.

The case for wired headphones is fairly straight-forward. However, when detecting if a wireless headset is connected, the APIs I have been using require Manifest.permission.BLUETOOTH or Manifest.permission.BLUETOOTH_CONNECT.

For some time I've accepted that only if those permissions are granted will I know for sure if headphones are connected, but this is now increasingly becoming problematic.

Does anyone know of an alternative that would determine if a headset is connected without user-facing 'dangerous' permission prompts like the BluetoothHeadset solution does? Is there anything in the AudioManager that can be used instead?

Here is what I have today:

package ai.numbereight.sdk.platform.sensors

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothHeadset
import android.bluetooth.BluetoothProfile
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.util.Log

private val listener = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val connection = when (intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
                BluetoothHeadset.STATE_DISCONNECTED)) {
            BluetoothHeadset.STATE_CONNECTED -> "Connected"
            BluetoothHeadset.STATE_DISCONNECTED -> "Disconnected"
            else -> "Unknown"
        }

        Log.d("Connection", connection)
    }
}

fun register(context: Context) {
    // Register for changes - events will only be received
    // if Manifest.permission.BLUETOOTH (< Android 10)
    // or Manifest.permission.BLUETOOTH_CONNECT (>= Android 10)
    // are granted.
    val filter = IntentFilter()
    filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)
    context.registerReceiver(listener, filter)

    // Fire initial event - this API call requires the above Bluetooth permissions
    // For brevity I assume that the default adapter is not null
    val currentState = BluetoothAdapter.getDefaultAdapter()!!.getProfileConnectionState(BluetoothProfile.HEADSET)
    val initialIntent = Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)
    initialIntent.putExtra(BluetoothHeadset.EXTRA_STATE, currentState)
    listener.onReceive(context, initialIntent)
}
Chris Watts
  • 6,197
  • 7
  • 49
  • 98
  • Have you tried `isWiredHeadsetOn` from the `AudioManager`, e.g. `boolean isWiredHeadsetOn = mAudioManager.isWiredHeadsetOn();` – Mouaad Abdelghafour AITALI Jan 05 '23 at 16:43
  • I'm looking for wireless headphones but yes, I presume that would be another way to check wired headphones. It does appear to require a permission as well but I think it doesn't need user intervention so perhaps there's something there that works for wireless too. – Chris Watts Jan 05 '23 at 16:51

0 Answers0