diff --git a/android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsService.kt b/android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsService.kt index 7ea4ff4..f89f650 100644 --- a/android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsService.kt +++ b/android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsService.kt @@ -1468,39 +1468,36 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList ) { connectAudio(this@AirPodsService, device) justEnabledA2dp = true - val bluetoothAdapter = - this@AirPodsService.getSystemService( - BluetoothManager::class.java - ).adapter - bluetoothAdapter.getProfileProxy( - this@AirPodsService, - object : BluetoothProfile.ServiceListener { - override fun onServiceConnected( - profile: Int, - proxy: BluetoothProfile - ) { - if (profile == BluetoothProfile.A2DP) { - val connectedDevices = - proxy.connectedDevices - if (connectedDevices.isNotEmpty()) { - MediaController.sendPlay() - } + val a2dpConnectionStateReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action == "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED") { + val state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED) + val previousState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED) + val device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) + + Log.d("MediaController", "A2DP state changed: $previousState -> $state for device: ${device?.address}") + + if (state == BluetoothProfile.STATE_CONNECTED && + previousState != BluetoothProfile.STATE_CONNECTED && + device?.address == this@AirPodsService.device?.address) { + + Log.d("MediaController", "A2DP connected, sending play command") + MediaController.sendPlay() + MediaController.iPausedTheMedia = false + + context.unregisterReceiver(this) } - bluetoothAdapter.closeProfileProxy( - profile, - proxy - ) } - - override fun onServiceDisconnected( - profile: Int - ) { - } - }, - BluetoothProfile.A2DP - ) - + } + } + val a2dpIntentFilter = IntentFilter("android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED") + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + registerReceiver(a2dpConnectionStateReceiver, a2dpIntentFilter, RECEIVER_EXPORTED) + } else { + registerReceiver(a2dpConnectionStateReceiver, a2dpIntentFilter) + } } else if (newInEarData == listOf(false, false)) { + MediaController.sendPause(force = true) disconnectAudio(this@AirPodsService, device) } diff --git a/android/app/src/main/java/me/kavishdevar/librepods/utils/MediaController.kt b/android/app/src/main/java/me/kavishdevar/librepods/utils/MediaController.kt index ccc9ed4..38ab3af 100644 --- a/android/app/src/main/java/me/kavishdevar/librepods/utils/MediaController.kt +++ b/android/app/src/main/java/me/kavishdevar/librepods/utils/MediaController.kt @@ -82,7 +82,6 @@ object MediaController { if (configs != null && !iPausedTheMedia) { Log.d("MediaController", "Seems like the user changed the state of media themselves, now I won't play until the ear detection pauses it.") handler.postDelayed({ - iPausedTheMedia = !audioManager.isMusicActive userPlayedTheMedia = audioManager.isMusicActive }, 7) // i have no idea why android sends an event a hundred times after the user does something. } @@ -98,9 +97,9 @@ object MediaController { @Synchronized fun sendPause(force: Boolean = false) { - Log.d("MediaController", "Sending pause with iPausedTheMedia: $iPausedTheMedia, userPlayedTheMedia: $userPlayedTheMedia") - if ((audioManager.isMusicActive && !userPlayedTheMedia) || force) { - iPausedTheMedia = true + Log.d("MediaController", "Sending pause with iPausedTheMedia: $iPausedTheMedia, userPlayedTheMedia: $userPlayedTheMedia, isMusicActive: ${audioManager.isMusicActive}, force: $force") + if ((audioManager.isMusicActive) && (!userPlayedTheMedia || force)) { + iPausedTheMedia = if (force) audioManager.isMusicActive else true userPlayedTheMedia = false audioManager.dispatchMediaKeyEvent( KeyEvent(