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 rt: Ringtone? = null
|
||||||
private var rtTimer: Timer? = null
|
private var rtTimer: Timer? = null
|
||||||
private var audioFocusRequest: AudioFocusRequestCompat? = null
|
|
||||||
private var origVolume = mutableMapOf<Int, Int>()
|
private var origVolume = mutableMapOf<Int, Int>()
|
||||||
private var btAdapter: BluetoothAdapter? = null
|
|
||||||
private var linkAddresses = mutableMapOf<String, String>()
|
private var linkAddresses = mutableMapOf<String, String>()
|
||||||
private var activeNetwork: Network? = null
|
private var activeNetwork: Network? = null
|
||||||
private var allNetworks = mutableSetOf<Network>()
|
private var allNetworks = mutableSetOf<Network>()
|
||||||
@@ -457,9 +455,7 @@ class BaresipService: Service() {
|
|||||||
val vidMode = intent.getIntExtra("video", Api.VIDMODE_OFF)
|
val vidMode = intent.getIntExtra("video", Api.VIDMODE_OFF)
|
||||||
stopRinging()
|
stopRinging()
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
if (am.mode != AudioManager.MODE_IN_COMMUNICATION)
|
requestAudioFocus(am, AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||||
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
|
||||||
requestAudioFocus(AudioAttributes.CONTENT_TYPE_SPEECH)
|
|
||||||
setCallVolume()
|
setCallVolume()
|
||||||
proximitySensing(true)
|
proximitySensing(true)
|
||||||
Api.ua_answer(uap, callp, vidMode)
|
Api.ua_answer(uap, callp, vidMode)
|
||||||
@@ -637,7 +633,6 @@ class BaresipService: Service() {
|
|||||||
if (call!!.status == "transferring")
|
if (call!!.status == "transferring")
|
||||||
break
|
break
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
requestAudioFocus(AudioAttributes.CONTENT_TYPE_SPEECH)
|
|
||||||
setCallVolume()
|
setCallVolume()
|
||||||
proximitySensing(true)
|
proximitySensing(true)
|
||||||
return
|
return
|
||||||
@@ -879,7 +874,7 @@ class BaresipService: Service() {
|
|||||||
resetCallVolume()
|
resetCallVolume()
|
||||||
am.mode = AudioManager.MODE_NORMAL
|
am.mode = AudioManager.MODE_NORMAL
|
||||||
am.stopBluetoothSco()
|
am.stopBluetoothSco()
|
||||||
abandonAudioFocus()
|
abandonAudioFocus(am)
|
||||||
proximitySensing(false)
|
proximitySensing(false)
|
||||||
}
|
}
|
||||||
val missed = call.startTime == null && call.dir == "in" && !call.rejected
|
val missed = call.startTime == null && call.dir == "in" && !call.rejected
|
||||||
@@ -1173,57 +1168,8 @@ class BaresipService: Service() {
|
|||||||
return spannable
|
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() {
|
private fun startRinging() {
|
||||||
requestAudioFocus(AudioAttributes.CONTENT_TYPE_MUSIC)
|
requestAudioFocus(am, AudioAttributes.CONTENT_TYPE_MUSIC)
|
||||||
am.mode = AudioManager.MODE_RINGTONE
|
am.mode = AudioManager.MODE_RINGTONE
|
||||||
if (rt == null) {
|
if (rt == null) {
|
||||||
val rtUri = RingtoneManager.getActualDefaultRingtoneUri(applicationContext,
|
val rtUri = RingtoneManager.getActualDefaultRingtoneUri(applicationContext,
|
||||||
@@ -1248,7 +1194,7 @@ class BaresipService: Service() {
|
|||||||
|
|
||||||
private fun stopRinging() {
|
private fun stopRinging() {
|
||||||
if (am.mode == AudioManager.MODE_RINGTONE)
|
if (am.mode == AudioManager.MODE_RINGTONE)
|
||||||
abandonAudioFocus()
|
abandonAudioFocus(am)
|
||||||
if (VERSION.SDK_INT < 28 && rtTimer != null) {
|
if (VERSION.SDK_INT < 28 && rtTimer != null) {
|
||||||
rtTimer!!.cancel()
|
rtTimer!!.cancel()
|
||||||
rtTimer = null
|
rtTimer = null
|
||||||
@@ -1485,7 +1431,7 @@ class BaresipService: Service() {
|
|||||||
if (am.isBluetoothScoOn)
|
if (am.isBluetoothScoOn)
|
||||||
am.stopBluetoothSco()
|
am.stopBluetoothSco()
|
||||||
am.mode = AudioManager.MODE_NORMAL
|
am.mode = AudioManager.MODE_NORMAL
|
||||||
abandonAudioFocus()
|
abandonAudioFocus(am)
|
||||||
stopRinging()
|
stopRinging()
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
uas.clear()
|
uas.clear()
|
||||||
@@ -1541,6 +1487,59 @@ class BaresipService: Service() {
|
|||||||
val serviceEvent = MutableLiveData<Event<Long>>()
|
val serviceEvent = MutableLiveData<Event<Long>>()
|
||||||
val serviceEvents = mutableListOf<ServiceEvent>()
|
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.Intent.ACTION_CALL
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Configuration.ORIENTATION_PORTRAIT
|
import android.content.res.Configuration.ORIENTATION_PORTRAIT
|
||||||
|
import android.media.AudioAttributes
|
||||||
import android.media.AudioDeviceInfo
|
import android.media.AudioDeviceInfo
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
@@ -1816,7 +1817,13 @@ class MainActivity : AppCompatActivity() {
|
|||||||
hangupButton.visibility = View.VISIBLE
|
hangupButton.visibility = View.VISIBLE
|
||||||
hangupButton.isEnabled = true
|
hangupButton.isEnabled = true
|
||||||
if (Build.VERSION.SDK_INT < 31) {
|
if (Build.VERSION.SDK_INT < 31) {
|
||||||
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 {
|
||||||
callRunnable = Runnable {
|
callRunnable = Runnable {
|
||||||
callRunnable = null
|
callRunnable = null
|
||||||
if (!call(ua, uri)) {
|
if (!call(ua, uri)) {
|
||||||
@@ -1827,6 +1834,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
callHandler.postDelayed(callRunnable!!, 1000)
|
callHandler.postDelayed(callRunnable!!, 1000)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
audioModeChangedListener = AudioManager.OnModeChangedListener { mode ->
|
audioModeChangedListener = AudioManager.OnModeChangedListener { mode ->
|
||||||
if (mode == AudioManager.MODE_IN_COMMUNICATION) {
|
if (mode == AudioManager.MODE_IN_COMMUNICATION) {
|
||||||
@@ -1849,7 +1857,12 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
am.addOnModeChangedListener(mainExecutor, audioModeChangedListener!!)
|
am.addOnModeChangedListener(mainExecutor, audioModeChangedListener!!)
|
||||||
Log.d(TAG, "Setting audio mode to MODE_IN_COMMUNICATION")
|
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 {
|
} else {
|
||||||
|
|||||||
@@ -969,4 +969,5 @@ object Utils {
|
|||||||
else
|
else
|
||||||
setSpeakerPhone(executor, am, !am.isSpeakerphoneOn)
|
setSpeakerPhone(executor, am, !am.isSpeakerphoneOn)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user