android: fix media not resuming when using single AirPod

This commit is contained in:
Kavish Devar
2026-04-30 01:00:15 +05:30
parent d80f2275a1
commit 7b81411417
2 changed files with 55 additions and 39 deletions

View File

@@ -1100,7 +1100,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
"AirPodsParser", "AirPodsParser",
"Audio source changed mac: ${aacpManager.audioSource?.mac}, type: ${aacpManager.audioSource?.type?.name}" "Audio source changed mac: ${aacpManager.audioSource?.mac}, type: ${aacpManager.audioSource?.type?.name}"
) )
if (aacpManager.audioSource?.type != AACPManager.Companion.AudioSourceType.NONE && aacpManager.audioSource?.mac != localMac) { if (localMac!="" && (aacpManager.audioSource?.type != AACPManager.Companion.AudioSourceType.NONE && aacpManager.audioSource?.mac != localMac)) {
Log.d( Log.d(
"AirPodsParser", "AirPodsParser",
"Audio source is another device, better to give up aacp control" "Audio source is another device, better to give up aacp control"
@@ -1256,6 +1256,14 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
disconnectAudio(this@AirPodsService, device) disconnectAudio(this@AirPodsService, device)
} }
} }
val wasNone = inEarData == listOf(false, false)
val nowSingle = newInEarData.count { it } == 1
if (wasNone && nowSingle) {
MediaController.sendPlay()
MediaController.iPausedTheMedia = false
return
}
if (inEarData.contains(false) && newInEarData == listOf(true, true)) { if (inEarData.contains(false) && newInEarData == listOf(true, true)) {
Log.d("AirPodsParser", "User put in both AirPods from just one.") Log.d("AirPodsParser", "User put in both AirPods from just one.")
@@ -2989,22 +2997,20 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
fun connectAudio(context: Context, device: BluetoothDevice?) { fun connectAudio(context: Context, device: BluetoothDevice?) {
val bluetoothAdapter = context.getSystemService(BluetoothManager::class.java).adapter val bluetoothAdapter = context.getSystemService(BluetoothManager::class.java).adapter
bluetoothAdapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener {
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) { bluetoothAdapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener {
if (profile == BluetoothProfile.A2DP) { override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
if (profile == BluetoothProfile.A2DP) {
if (context.checkSelfPermission("android.permission.BLUETOOTH_PRIVILEGED") == PackageManager.PERMISSION_GRANTED) {
try { try {
if (context.checkSelfPermission("android.permission.BLUETOOTH_PRIVILEGED") == PackageManager.PERMISSION_GRANTED) { val policyMethod = proxy.javaClass.getMethod(
val policyMethod = proxy.javaClass.getMethod( "setConnectionPolicy",
"setConnectionPolicy", BluetoothDevice::class.java,
BluetoothDevice::class.java, Int::class.java
Int::class.java )
) Log.d(TAG, "calling A2DP.setConnectionPolicy for ${device?.address} to 100")
Log.d(TAG, "calling A2DP.setConnectionPolicy for ${device?.address} to 100") policyMethod.invoke(proxy, device, 100)
policyMethod.invoke(proxy, device, 100)
}
else {
Log.d(TAG, "not setting connection policy for A2DP, no BLUETOOTH_PRIVILEGED permission")
}
val connectMethod = val connectMethod =
proxy.javaClass.getMethod("connect", BluetoothDevice::class.java) proxy.javaClass.getMethod("connect", BluetoothDevice::class.java)
connectMethod.invoke( connectMethod.invoke(
@@ -3019,30 +3025,35 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
} }
} }
} }
else {
val connectMethod =
proxy.javaClass.getMethod("connect", BluetoothDevice::class.java)
connectMethod.invoke(
proxy, device
)
Log.d(TAG, "not setting connection policy for A2DP, no BLUETOOTH_PRIVILEGED permission. just called connect")
}
} }
}
override fun onServiceDisconnected(profile: Int) {} override fun onServiceDisconnected(profile: Int) {}
}, BluetoothProfile.A2DP) }, BluetoothProfile.A2DP)
bluetoothAdapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener { bluetoothAdapter?.getProfileProxy(context, object : BluetoothProfile.ServiceListener {
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) { override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
if (profile == BluetoothProfile.HEADSET) { if (profile == BluetoothProfile.HEADSET) {
if (checkSelfPermission("android.permission.MODIFY_PHONE_STATE") == PackageManager.PERMISSION_GRANTED) {
try { try {
if (checkSelfPermission("android.permission.MODIFY_PHONE_STATE") == PackageManager.PERMISSION_GRANTED) { val policyMethod = proxy.javaClass.getMethod(
"setConnectionPolicy",
val policyMethod = proxy.javaClass.getMethod( BluetoothDevice::class.java,
"setConnectionPolicy", Int::class.java
BluetoothDevice::class.java, )
Int::class.java Log.d(
) TAG,
Log.d( "calling HEADSET.setConnectionPolicy for ${device?.address} to 100"
TAG, )
"calling HEADSET.setConnectionPolicy for ${device?.address} to 100" policyMethod.invoke(proxy, device, 100)
)
policyMethod.invoke(proxy, device, 100)
} else {
Log.d(TAG, "not setting connection policy for HEADSET, no MODIFIY_PHONE_STATE permission")
}
val connectMethod = val connectMethod =
proxy.javaClass.getMethod("connect", BluetoothDevice::class.java) proxy.javaClass.getMethod("connect", BluetoothDevice::class.java)
connectMethod.invoke(proxy, device) connectMethod.invoke(proxy, device)
@@ -3051,11 +3062,14 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
} finally { } finally {
bluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy) bluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy)
} }
} else {
Log.d(TAG, "not setting connection policy for HEADSET, no MODIFIY_PHONE_STATE permission")
} }
} }
}
override fun onServiceDisconnected(profile: Int) {} override fun onServiceDisconnected(profile: Int) {}
}, BluetoothProfile.HEADSET) }, BluetoothProfile.HEADSET)
} }
fun setName(name: String) { fun setName(name: String) {

View File

@@ -171,8 +171,10 @@ object MediaController {
} }
if (configs != null && !iPausedTheMedia) { if (configs != null && !iPausedTheMedia) {
val localMac = ServiceManager.getService()?.localMac ?: return
if (localMac == "") return
ServiceManager.getService()?.aacpManager?.sendMediaInformataion( ServiceManager.getService()?.aacpManager?.sendMediaInformataion(
ServiceManager.getService()?.localMac ?: return, localMac,
isActive isActive
) )
Log.d("MediaController", "User changed media state themselves; will wait for ear detection pause before auto-play") Log.d("MediaController", "User changed media state themselves; will wait for ear detection pause before auto-play")