Embedded audio mode change to audio focus request
This commit is contained in:
@ -65,9 +65,7 @@ class BaresipService: Service() {
|
||||
|
||||
private var rt: Ringtone? = null
|
||||
private var rtTimer: Timer? = null
|
||||
private var audioFocusRequest: AudioFocusRequestCompat? = null
|
||||
private var origVolume = mutableMapOf<Int, Int>()
|
||||
private var btAdapter: BluetoothAdapter? = null
|
||||
private var linkAddresses = mutableMapOf<String, String>()
|
||||
private var activeNetwork: Network? = null
|
||||
private var allNetworks = mutableSetOf<Network>()
|
||||
@ -457,9 +455,7 @@ class BaresipService: Service() {
|
||||
val vidMode = intent.getIntExtra("video", Api.VIDMODE_OFF)
|
||||
stopRinging()
|
||||
stopMediaPlayer()
|
||||
if (am.mode != AudioManager.MODE_IN_COMMUNICATION)
|
||||
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||
requestAudioFocus(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
requestAudioFocus(am, AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
setCallVolume()
|
||||
proximitySensing(true)
|
||||
Api.ua_answer(uap, callp, vidMode)
|
||||
@ -637,7 +633,6 @@ class BaresipService: Service() {
|
||||
if (call!!.status == "transferring")
|
||||
break
|
||||
stopMediaPlayer()
|
||||
requestAudioFocus(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
setCallVolume()
|
||||
proximitySensing(true)
|
||||
return
|
||||
@ -879,7 +874,7 @@ class BaresipService: Service() {
|
||||
resetCallVolume()
|
||||
am.mode = AudioManager.MODE_NORMAL
|
||||
am.stopBluetoothSco()
|
||||
abandonAudioFocus()
|
||||
abandonAudioFocus(am)
|
||||
proximitySensing(false)
|
||||
}
|
||||
val missed = call.startTime == null && call.dir == "in" && !call.rejected
|
||||
@ -1173,57 +1168,8 @@ class BaresipService: Service() {
|
||||
return spannable
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun isBluetoothHeadsetConnected(): Boolean {
|
||||
return if (VERSION.SDK_INT < 31)
|
||||
btAdapter != null && btAdapter!!.isEnabled &&
|
||||
btAdapter!!.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothAdapter.STATE_CONNECTED
|
||||
else
|
||||
// getProfileConnectionState requires asking fot BLUETOOTH_CONNECT permission
|
||||
true
|
||||
}
|
||||
|
||||
private fun requestAudioFocus(type: Int) {
|
||||
if (audioFocusRequest != null) {
|
||||
if (audioFocusRequest!!.audioAttributesCompat.contentType == type)
|
||||
return
|
||||
else
|
||||
abandonAudioFocus()
|
||||
}
|
||||
val attributes = AudioAttributesCompat.Builder()
|
||||
.setUsage(AudioAttributesCompat.USAGE_VOICE_COMMUNICATION)
|
||||
.setContentType(type)
|
||||
.build()
|
||||
audioFocusRequest = AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN_TRANSIENT)
|
||||
.setAudioAttributes(attributes)
|
||||
.setOnAudioFocusChangeListener { }
|
||||
.build()
|
||||
if (AudioManagerCompat.requestAudioFocus(am, audioFocusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||
Log.d(TAG, "Audio focus granted")
|
||||
isAudioFocused = true
|
||||
if (isBluetoothHeadsetConnected() && !am.isBluetoothScoOn) {
|
||||
Log.d(TAG, "Starting Bluetooth SCO")
|
||||
am.startBluetoothSco()
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "Audio focus denied")
|
||||
audioFocusRequest = null
|
||||
isAudioFocused = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun abandonAudioFocus() {
|
||||
if (audioFocusRequest != null) {
|
||||
AudioManagerCompat.abandonAudioFocusRequest(am, audioFocusRequest!!)
|
||||
audioFocusRequest = null
|
||||
isAudioFocused = false
|
||||
Log.d(TAG, "Audio focus abandoned")
|
||||
}
|
||||
}
|
||||
|
||||
private fun startRinging() {
|
||||
requestAudioFocus(AudioAttributes.CONTENT_TYPE_MUSIC)
|
||||
requestAudioFocus(am, AudioAttributes.CONTENT_TYPE_MUSIC)
|
||||
am.mode = AudioManager.MODE_RINGTONE
|
||||
if (rt == null) {
|
||||
val rtUri = RingtoneManager.getActualDefaultRingtoneUri(applicationContext,
|
||||
@ -1248,7 +1194,7 @@ class BaresipService: Service() {
|
||||
|
||||
private fun stopRinging() {
|
||||
if (am.mode == AudioManager.MODE_RINGTONE)
|
||||
abandonAudioFocus()
|
||||
abandonAudioFocus(am)
|
||||
if (VERSION.SDK_INT < 28 && rtTimer != null) {
|
||||
rtTimer!!.cancel()
|
||||
rtTimer = null
|
||||
@ -1485,7 +1431,7 @@ class BaresipService: Service() {
|
||||
if (am.isBluetoothScoOn)
|
||||
am.stopBluetoothSco()
|
||||
am.mode = AudioManager.MODE_NORMAL
|
||||
abandonAudioFocus()
|
||||
abandonAudioFocus(am)
|
||||
stopRinging()
|
||||
stopMediaPlayer()
|
||||
uas.clear()
|
||||
@ -1541,6 +1487,59 @@ class BaresipService: Service() {
|
||||
val serviceEvent = MutableLiveData<Event<Long>>()
|
||||
val serviceEvents = mutableListOf<ServiceEvent>()
|
||||
|
||||
private var audioFocusRequest: AudioFocusRequestCompat? = null
|
||||
private var btAdapter: BluetoothAdapter? = null
|
||||
|
||||
fun requestAudioFocus(am: AudioManager, type: Int): Boolean {
|
||||
if (audioFocusRequest != null) {
|
||||
if (audioFocusRequest!!.audioAttributesCompat.contentType == type)
|
||||
return true
|
||||
else
|
||||
abandonAudioFocus(am)
|
||||
}
|
||||
val attributes = AudioAttributesCompat.Builder()
|
||||
.setUsage(AudioAttributesCompat.USAGE_VOICE_COMMUNICATION)
|
||||
.setContentType(type)
|
||||
.build()
|
||||
audioFocusRequest = AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN_TRANSIENT)
|
||||
.setAudioAttributes(attributes)
|
||||
.setOnAudioFocusChangeListener { }
|
||||
.build()
|
||||
if (AudioManagerCompat.requestAudioFocus(am, audioFocusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||
Log.d(TAG, "Audio focus granted")
|
||||
isAudioFocused = true
|
||||
if (isBluetoothHeadsetConnected() && !am.isBluetoothScoOn) {
|
||||
Log.d(TAG, "Starting Bluetooth SCO")
|
||||
am.startBluetoothSco()
|
||||
}
|
||||
if (type == AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||
} else {
|
||||
Log.d(TAG, "Audio focus denied")
|
||||
audioFocusRequest = null
|
||||
isAudioFocused = false
|
||||
}
|
||||
return isAudioFocused
|
||||
}
|
||||
|
||||
private fun abandonAudioFocus(am: AudioManager) {
|
||||
if (audioFocusRequest != null) {
|
||||
AudioManagerCompat.abandonAudioFocusRequest(am, audioFocusRequest!!)
|
||||
audioFocusRequest = null
|
||||
isAudioFocused = false
|
||||
Log.d(TAG, "Audio focus abandoned")
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun isBluetoothHeadsetConnected(): Boolean {
|
||||
return if (VERSION.SDK_INT < 31)
|
||||
btAdapter != null && btAdapter!!.isEnabled &&
|
||||
btAdapter!!.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothAdapter.STATE_CONNECTED
|
||||
else
|
||||
// getProfileConnectionState requires asking for BLUETOOTH_CONNECT permission
|
||||
true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import android.content.*
|
||||
import android.content.Intent.ACTION_CALL
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration.ORIENTATION_PORTRAIT
|
||||
import android.media.AudioAttributes
|
||||
import android.media.AudioDeviceInfo
|
||||
import android.media.AudioManager
|
||||
import android.net.Uri
|
||||
@ -1816,17 +1817,24 @@ class MainActivity : AppCompatActivity() {
|
||||
hangupButton.visibility = View.VISIBLE
|
||||
hangupButton.isEnabled = true
|
||||
if (Build.VERSION.SDK_INT < 31) {
|
||||
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||
callRunnable = Runnable {
|
||||
callRunnable = null
|
||||
if (!call(ua, uri)) {
|
||||
callButton.visibility = View.VISIBLE
|
||||
callButton.isEnabled = true
|
||||
hangupButton.visibility = View.INVISIBLE
|
||||
hangupButton.isEnabled = false
|
||||
if (!BaresipService.requestAudioFocus(am, AudioAttributes.CONTENT_TYPE_SPEECH)) {
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
"Audio focus denied",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
} else {
|
||||
callRunnable = Runnable {
|
||||
callRunnable = null
|
||||
if (!call(ua, uri)) {
|
||||
callButton.visibility = View.VISIBLE
|
||||
callButton.isEnabled = true
|
||||
hangupButton.visibility = View.INVISIBLE
|
||||
hangupButton.isEnabled = false
|
||||
}
|
||||
}
|
||||
callHandler.postDelayed(callRunnable!!, 1000)
|
||||
}
|
||||
callHandler.postDelayed(callRunnable!!, 1000)
|
||||
} else {
|
||||
audioModeChangedListener = AudioManager.OnModeChangedListener { mode ->
|
||||
if (mode == AudioManager.MODE_IN_COMMUNICATION) {
|
||||
@ -1849,7 +1857,12 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
am.addOnModeChangedListener(mainExecutor, audioModeChangedListener!!)
|
||||
Log.d(TAG, "Setting audio mode to MODE_IN_COMMUNICATION")
|
||||
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||
if (!BaresipService.requestAudioFocus(am, AudioAttributes.CONTENT_TYPE_SPEECH))
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
"Audio focus denied",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -969,4 +969,5 @@ object Utils {
|
||||
else
|
||||
setSpeakerPhone(executor, am, !am.isSpeakerphoneOn)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user