mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-02-10 19:52:24 +00:00
improve media control logic
This commit is contained in:
@@ -459,6 +459,7 @@ class AirPodsService: Service() {
|
|||||||
)
|
)
|
||||||
var justEnabledA2dp = false
|
var justEnabledA2dp = false
|
||||||
earReceiver = object : BroadcastReceiver() {
|
earReceiver = object : BroadcastReceiver() {
|
||||||
|
@SuppressLint("NewApi")
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
val data = intent.getByteArrayExtra("data")
|
val data = intent.getByteArrayExtra("data")
|
||||||
if (data != null && earDetectionEnabled) {
|
if (data != null && earDetectionEnabled) {
|
||||||
@@ -516,15 +517,41 @@ class AirPodsService: Service() {
|
|||||||
disconnectAudio(this@AirPodsService, device)
|
disconnectAudio(this@AirPodsService, device)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inEarData.contains(false) && newInEarData == listOf(
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Log.d("AirPods Parser", "User put in both AirPods from just one.")
|
||||||
|
MediaController.userPlayedTheMedia = false
|
||||||
|
}
|
||||||
|
if (newInEarData.contains(false) && inEarData == listOf(
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Log.d("AirPods Parser", "User took one of two out.")
|
||||||
|
MediaController.userPlayedTheMedia = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newInEarData.sorted() == inEarData.sorted()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
inEarData = newInEarData
|
inEarData = newInEarData
|
||||||
|
|
||||||
if (inEar == true) {
|
if (inEar == true) {
|
||||||
if (!justEnabledA2dp) {
|
if (!justEnabledA2dp) {
|
||||||
justEnabledA2dp = false
|
justEnabledA2dp = false
|
||||||
|
// if (audioManager.activePlaybackConfigurations.any { it.audioDeviceInfo?.address == device.address }) {
|
||||||
MediaController.sendPlay()
|
MediaController.sendPlay()
|
||||||
|
MediaController.iPausedTheMedia = false
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MediaController.sendPause()
|
// if (audioManager.activePlaybackConfigurations.any { it.audioDeviceInfo?.address == device.address }) {
|
||||||
|
MediaController.sendPause()
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,21 +20,43 @@
|
|||||||
package me.kavishdevar.aln.utils
|
package me.kavishdevar.aln.utils
|
||||||
|
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
|
import android.media.AudioPlaybackConfiguration
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
|
|
||||||
object MediaController {
|
object MediaController {
|
||||||
private var initialVolume: Int? = null // Nullable to track the unset state
|
private var initialVolume: Int? = null
|
||||||
private lateinit var audioManager: AudioManager // Declare AudioManager
|
private lateinit var audioManager: AudioManager
|
||||||
|
var iPausedTheMedia = false
|
||||||
|
var userPlayedTheMedia = false
|
||||||
|
|
||||||
// Initialize the singleton with the AudioManager instance
|
|
||||||
fun initialize(audioManager: AudioManager) {
|
fun initialize(audioManager: AudioManager) {
|
||||||
this.audioManager = audioManager
|
this.audioManager = audioManager
|
||||||
|
audioManager.registerAudioPlaybackCallback(cb, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
val cb = object : AudioManager.AudioPlaybackCallback() {
|
||||||
|
override fun onPlaybackConfigChanged(configs: MutableList<AudioPlaybackConfiguration>?) {
|
||||||
|
super.onPlaybackConfigChanged(configs)
|
||||||
|
Log.d("MediaController", "Playback config changed, iPausedTheMedia: $iPausedTheMedia")
|
||||||
|
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(Looper.getMainLooper()).postDelayed({
|
||||||
|
iPausedTheMedia = !audioManager.isMusicActive
|
||||||
|
userPlayedTheMedia = audioManager.isMusicActive
|
||||||
|
}, 7) // i have no idea why, but android sends a pause event a hundred times after the user does something.
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun sendPause() {
|
fun sendPause() {
|
||||||
if (audioManager.isMusicActive) {
|
Log.d("MediaController", "Sending pause with iPausedTheMedia: $iPausedTheMedia, userPlayedTheMedia: $userPlayedTheMedia")
|
||||||
|
if (audioManager.isMusicActive && !userPlayedTheMedia) {
|
||||||
|
iPausedTheMedia = true
|
||||||
|
userPlayedTheMedia = false
|
||||||
audioManager.dispatchMediaKeyEvent(
|
audioManager.dispatchMediaKeyEvent(
|
||||||
KeyEvent(
|
KeyEvent(
|
||||||
KeyEvent.ACTION_DOWN,
|
KeyEvent.ACTION_DOWN,
|
||||||
@@ -52,7 +74,10 @@ object MediaController {
|
|||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun sendPlay() {
|
fun sendPlay() {
|
||||||
if (!audioManager.isMusicActive) {
|
Log.d("MediaController", "Sending play with iPausedTheMedia: $iPausedTheMedia")
|
||||||
|
if (iPausedTheMedia) {
|
||||||
|
Log.d("MediaController", "Sending play and setting userPlayedTheMedia to false")
|
||||||
|
userPlayedTheMedia = false
|
||||||
audioManager.dispatchMediaKeyEvent(
|
audioManager.dispatchMediaKeyEvent(
|
||||||
KeyEvent(
|
KeyEvent(
|
||||||
KeyEvent.ACTION_DOWN,
|
KeyEvent.ACTION_DOWN,
|
||||||
@@ -76,8 +101,7 @@ object MediaController {
|
|||||||
Log.d("MediaController", "Initial Volume Set: $initialVolume")
|
Log.d("MediaController", "Initial Volume Set: $initialVolume")
|
||||||
audioManager.setStreamVolume(
|
audioManager.setStreamVolume(
|
||||||
AudioManager.STREAM_MUSIC,
|
AudioManager.STREAM_MUSIC,
|
||||||
audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) * 1 / 12, // Set to a lower volume when speaking starts
|
audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) * 1 / 12, 0
|
||||||
0
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Log.d("MediaController", "Initial Volume: $initialVolume")
|
Log.d("MediaController", "Initial Volume: $initialVolume")
|
||||||
@@ -91,4 +115,5 @@ object MediaController {
|
|||||||
initialVolume = null // Reset to null after restoring the volume
|
initialVolume = null // Reset to null after restoring the volume
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[versions]
|
[versions]
|
||||||
accompanistPermissions = "0.36.0"
|
accompanistPermissions = "0.36.0"
|
||||||
agp = "8.7.2"
|
agp = "8.7.3"
|
||||||
hiddenapibypass = "4.3"
|
hiddenapibypass = "4.3"
|
||||||
kotlin = "2.0.0"
|
kotlin = "2.0.0"
|
||||||
coreKtx = "1.15.0"
|
coreKtx = "1.15.0"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#Mon Oct 07 22:30:36 IST 2024
|
#Mon Oct 07 22:30:36 IST 2024
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
Reference in New Issue
Block a user