Started work on Bluetooth improvements for API leve 31+
This commit is contained in:
@@ -10,8 +10,10 @@ import android.content.BroadcastReceiver
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.database.ContentObserver
|
import android.database.ContentObserver
|
||||||
import android.media.*
|
import android.media.*
|
||||||
|
import android.media.AudioManager.MODE_NORMAL
|
||||||
import android.media.AudioManager.RINGER_MODE_SILENT
|
import android.media.AudioManager.RINGER_MODE_SILENT
|
||||||
import android.net.*
|
import android.net.*
|
||||||
import android.net.wifi.WifiManager
|
import android.net.wifi.WifiManager
|
||||||
@@ -28,9 +30,9 @@ import android.widget.RemoteViews
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.ColorRes
|
import androidx.annotation.ColorRes
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
@@ -41,10 +43,10 @@ import java.io.File
|
|||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
import kotlin.concurrent.schedule
|
import kotlin.concurrent.schedule
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
class BaresipService: Service() {
|
class BaresipService: Service() {
|
||||||
|
|
||||||
internal lateinit var intent: Intent
|
internal lateinit var intent: Intent
|
||||||
@@ -244,19 +246,22 @@ class BaresipService: Service() {
|
|||||||
when (state) {
|
when (state) {
|
||||||
BluetoothHeadset.STATE_CONNECTED -> {
|
BluetoothHeadset.STATE_CONNECTED -> {
|
||||||
Log.d(TAG, "Bluetooth headset is connected")
|
Log.d(TAG, "Bluetooth headset is connected")
|
||||||
if (audioFocusRequest != null)
|
if (audioFocusRequest != null) {
|
||||||
// Without delay, SCO_AUDIO_STATE_CONNECTING ->
|
//Handler(Looper.getMainLooper()).postDelayed({
|
||||||
// SCO_AUDIO_STATE_DISCONNECTED
|
//am.startBluetoothSco()
|
||||||
Timer("Sco", false).schedule(1000) {
|
startBluetoothSco(am, 1000L)
|
||||||
Log.d(TAG, "Starting Bluetooth SCO")
|
|
||||||
am.startBluetoothSco()
|
//}, 1000)
|
||||||
}
|
}
|
||||||
|
//Timer("Sco", false).schedule(1000) {
|
||||||
|
// startBluetoothSco(am)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
BluetoothHeadset.STATE_DISCONNECTED -> {
|
BluetoothHeadset.STATE_DISCONNECTED -> {
|
||||||
Log.d(TAG, "Bluetooth headset is disconnected")
|
Log.d(TAG, "Bluetooth headset is disconnected")
|
||||||
if (am.isBluetoothScoOn) {
|
if (isBluetoothScoOn(am)) {
|
||||||
Log.d(TAG, "Stopping Bluetooth SCO")
|
Log.d(TAG, "Stopping Bluetooth SCO")
|
||||||
am.stopBluetoothSco()
|
stopBluetoothSco(am)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,12 +276,10 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
BluetoothHeadset.STATE_AUDIO_DISCONNECTED -> {
|
BluetoothHeadset.STATE_AUDIO_DISCONNECTED -> {
|
||||||
Log.d(TAG, "Bluetooth headset audio is disconnected")
|
Log.d(TAG, "Bluetooth headset audio is disconnected")
|
||||||
if (am.isBluetoothScoOn) {
|
if (isBluetoothScoOn(am)) {
|
||||||
Log.d(TAG, "Stopping Bluetooth SCO")
|
stopBluetoothSco(am)
|
||||||
am.stopBluetoothSco()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED -> {
|
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED -> {
|
||||||
@@ -468,7 +471,7 @@ class BaresipService: Service() {
|
|||||||
val vidMode = intent.getIntExtra("video", Api.VIDMODE_OFF)
|
val vidMode = intent.getIntExtra("video", Api.VIDMODE_OFF)
|
||||||
stopRinging()
|
stopRinging()
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
requestAudioFocus(am, AudioAttributes.CONTENT_TYPE_SPEECH)
|
//requestAudioFocus(applicationContext, am, AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||||
setCallVolume()
|
setCallVolume()
|
||||||
proximitySensing(true)
|
proximitySensing(true)
|
||||||
Api.ua_answer(uap, callp, vidMode)
|
Api.ua_answer(uap, callp, vidMode)
|
||||||
@@ -886,9 +889,8 @@ class BaresipService: Service() {
|
|||||||
call.remove()
|
call.remove()
|
||||||
if (Call.calls().size == 0) {
|
if (Call.calls().size == 0) {
|
||||||
resetCallVolume()
|
resetCallVolume()
|
||||||
am.mode = AudioManager.MODE_NORMAL
|
|
||||||
am.stopBluetoothSco()
|
|
||||||
abandonAudioFocus(am)
|
abandonAudioFocus(am)
|
||||||
|
Utils.clearCommunicationDevice(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
|
||||||
@@ -1188,11 +1190,12 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun startRinging() {
|
private fun startRinging() {
|
||||||
requestAudioFocus(am, AudioAttributes.CONTENT_TYPE_MUSIC)
|
requestAudioFocus(applicationContext, am, AudioAttributes.CONTENT_TYPE_MUSIC)
|
||||||
am.mode = AudioManager.MODE_RINGTONE
|
|
||||||
if (rt == null) {
|
if (rt == null) {
|
||||||
val rtUri = RingtoneManager.getActualDefaultRingtoneUri(applicationContext,
|
val rtUri = RingtoneManager.getActualDefaultRingtoneUri(
|
||||||
RingtoneManager.TYPE_RINGTONE)
|
applicationContext,
|
||||||
|
RingtoneManager.TYPE_RINGTONE
|
||||||
|
)
|
||||||
rt = RingtoneManager.getRingtone(applicationContext, rtUri)
|
rt = RingtoneManager.getRingtone(applicationContext, rtUri)
|
||||||
}
|
}
|
||||||
if (VERSION.SDK_INT >= 28) {
|
if (VERSION.SDK_INT >= 28) {
|
||||||
@@ -1251,8 +1254,6 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun stopRinging() {
|
private fun stopRinging() {
|
||||||
if (am.mode == AudioManager.MODE_RINGTONE)
|
|
||||||
abandonAudioFocus(am)
|
|
||||||
if (VERSION.SDK_INT < 28 && rtTimer != null) {
|
if (VERSION.SDK_INT < 28 && rtTimer != null) {
|
||||||
rtTimer!!.cancel()
|
rtTimer!!.cancel()
|
||||||
rtTimer = null
|
rtTimer = null
|
||||||
@@ -1307,13 +1308,10 @@ class BaresipService: Service() {
|
|||||||
if (callVolume != 0 && origVolume.isEmpty()) {
|
if (callVolume != 0 && origVolume.isEmpty()) {
|
||||||
for (streamType in listOf(AudioManager.STREAM_MUSIC, AudioManager.STREAM_VOICE_CALL)) {
|
for (streamType in listOf(AudioManager.STREAM_MUSIC, AudioManager.STREAM_VOICE_CALL)) {
|
||||||
origVolume[streamType] = am.getStreamVolume(streamType)
|
origVolume[streamType] = am.getStreamVolume(streamType)
|
||||||
am.setStreamVolume(
|
val maxVolume = am.getStreamMaxVolume(streamType)
|
||||||
streamType,
|
am.setStreamVolume(streamType, (callVolume * 0.1 * maxVolume).roundToInt(), 0)
|
||||||
(callVolume * 0.1 * am.getStreamMaxVolume(streamType)).roundToInt(),
|
Log.d(TAG, "Orig/new/max $streamType volume is " +
|
||||||
0
|
"${origVolume[streamType]}/${am.getStreamVolume(streamType)}/$maxVolume")
|
||||||
)
|
|
||||||
Log.d(TAG, "Orig/new $streamType volume is " +
|
|
||||||
"${origVolume[streamType]}/${am.getStreamVolume(streamType)}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1490,11 +1488,8 @@ class BaresipService: Service() {
|
|||||||
if (!isServiceClean) {
|
if (!isServiceClean) {
|
||||||
this.unregisterReceiver(bluetoothReceiver)
|
this.unregisterReceiver(bluetoothReceiver)
|
||||||
this.unregisterReceiver(hotSpotReceiver)
|
this.unregisterReceiver(hotSpotReceiver)
|
||||||
if (am.isBluetoothScoOn)
|
|
||||||
am.stopBluetoothSco()
|
|
||||||
am.mode = AudioManager.MODE_NORMAL
|
|
||||||
abandonAudioFocus(am)
|
|
||||||
stopRinging()
|
stopRinging()
|
||||||
|
abandonAudioFocus(am)
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
uas.clear()
|
uas.clear()
|
||||||
callHistory.clear()
|
callHistory.clear()
|
||||||
@@ -1552,14 +1547,17 @@ class BaresipService: Service() {
|
|||||||
private var audioFocusRequest: AudioFocusRequestCompat? = null
|
private var audioFocusRequest: AudioFocusRequestCompat? = null
|
||||||
private var btAdapter: BluetoothAdapter? = null
|
private var btAdapter: BluetoothAdapter? = null
|
||||||
|
|
||||||
fun requestAudioFocus(am: AudioManager, type: Int): Boolean {
|
fun requestAudioFocus(ctx: Context, am: AudioManager, type: Int): Boolean {
|
||||||
Log.d(TAG, "Requesting audio focus of type $type")
|
Log.d(TAG, "Requesting audio focus of type $type")
|
||||||
if (audioFocusRequest != null) {
|
if (audioFocusRequest != null) {
|
||||||
if (audioFocusRequest!!.audioAttributesCompat.contentType == type)
|
if (audioFocusRequest!!.audioAttributesCompat.contentType == type) {
|
||||||
|
Log.d(TAG, "Already focused")
|
||||||
|
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||||
return true
|
return true
|
||||||
else
|
} else {
|
||||||
abandonAudioFocus(am)
|
abandonAudioFocus(am)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
val attributes = AudioAttributesCompat.Builder()
|
val attributes = AudioAttributesCompat.Builder()
|
||||||
.setUsage(AudioAttributesCompat.USAGE_VOICE_COMMUNICATION)
|
.setUsage(AudioAttributesCompat.USAGE_VOICE_COMMUNICATION)
|
||||||
.setContentType(type)
|
.setContentType(type)
|
||||||
@@ -1571,12 +1569,13 @@ class BaresipService: Service() {
|
|||||||
if (AudioManagerCompat.requestAudioFocus(am, audioFocusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
if (AudioManagerCompat.requestAudioFocus(am, audioFocusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||||
Log.d(TAG, "Audio focus granted")
|
Log.d(TAG, "Audio focus granted")
|
||||||
isAudioFocused = true
|
isAudioFocused = true
|
||||||
if (isBluetoothHeadsetConnected() && !am.isBluetoothScoOn) {
|
if (isBluetoothHeadsetConnected(ctx) /* && !am.isBluetoothScoOn */) {
|
||||||
Log.d(TAG, "Starting Bluetooth SCO")
|
Log.d(TAG, "Starting Bluetooth SCO")
|
||||||
am.startBluetoothSco()
|
startBluetoothSco(am, 0L)
|
||||||
}
|
}
|
||||||
if (type == AudioAttributes.CONTENT_TYPE_SPEECH)
|
|
||||||
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||||
|
//if (type == AudioAttributes.CONTENT_TYPE_SPEECH || isBluetoothHeadsetConnected(ctx))
|
||||||
|
//am.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "Audio focus denied")
|
Log.i(TAG, "Audio focus denied")
|
||||||
audioFocusRequest = null
|
audioFocusRequest = null
|
||||||
@@ -1587,23 +1586,62 @@ class BaresipService: Service() {
|
|||||||
|
|
||||||
private fun abandonAudioFocus(am: AudioManager) {
|
private fun abandonAudioFocus(am: AudioManager) {
|
||||||
if (audioFocusRequest != null) {
|
if (audioFocusRequest != null) {
|
||||||
|
Log.d(TAG, "Abandoning audio focus")
|
||||||
AudioManagerCompat.abandonAudioFocusRequest(am, audioFocusRequest!!)
|
AudioManagerCompat.abandonAudioFocusRequest(am, audioFocusRequest!!)
|
||||||
audioFocusRequest = null
|
audioFocusRequest = null
|
||||||
isAudioFocused = false
|
isAudioFocused = false
|
||||||
Log.d(TAG, "Audio focus abandoned")
|
stopBluetoothSco(am)
|
||||||
|
Utils.clearCommunicationDevice(am)
|
||||||
|
am.mode = MODE_NORMAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
private fun isBluetoothHeadsetConnected(): Boolean {
|
private fun isBluetoothHeadsetConnected(ctx: Context): Boolean {
|
||||||
return if (VERSION.SDK_INT < 31)
|
return if (ActivityCompat.checkSelfPermission(ctx, Manifest.permission.BLUETOOTH_CONNECT) ==
|
||||||
|
PackageManager.PERMISSION_GRANTED)
|
||||||
btAdapter != null && btAdapter!!.isEnabled &&
|
btAdapter != null && btAdapter!!.isEnabled &&
|
||||||
btAdapter!!.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothAdapter.STATE_CONNECTED
|
btAdapter!!.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothAdapter.STATE_CONNECTED
|
||||||
else
|
else
|
||||||
// getProfileConnectionState requires asking for BLUETOOTH_CONNECT permission
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isBluetoothScoOn(am: AudioManager): Boolean {
|
||||||
|
return if (VERSION.SDK_INT < 31)
|
||||||
|
am.isBluetoothScoOn
|
||||||
|
else
|
||||||
|
if (am.communicationDevice != null)
|
||||||
|
am.communicationDevice!!.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO
|
||||||
|
else
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startBluetoothSco(am: AudioManager, delay: Long) {
|
||||||
|
Log.d(TAG, "Starting Bluetooth SCO")
|
||||||
|
Handler(Looper.getMainLooper()).postDelayed({
|
||||||
|
if (VERSION.SDK_INT < 35)
|
||||||
|
am.startBluetoothSco()
|
||||||
|
else
|
||||||
|
Utils.setCommunicationDevice(am, AudioDeviceInfo.TYPE_BLUETOOTH_SCO)
|
||||||
|
if (!isBluetoothScoOn(am)) {
|
||||||
|
Log.d(TAG, "Trying to start Bluetooth SCO again")
|
||||||
|
Handler(Looper.getMainLooper()).postDelayed({
|
||||||
|
am.startBluetoothSco()
|
||||||
|
}, delay)
|
||||||
|
}
|
||||||
|
}, delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopBluetoothSco(am: AudioManager) {
|
||||||
|
Log.d(TAG, "Stopping Bluetooth SCO")
|
||||||
|
Handler(Looper.getMainLooper()).postDelayed({
|
||||||
|
if (VERSION.SDK_INT < 35)
|
||||||
|
am.stopBluetoothSco()
|
||||||
|
else
|
||||||
|
am.clearCommunicationDevice()
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.tutpro.baresip
|
package com.tutpro.baresip
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
import android.Manifest.permission.*
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
@@ -80,6 +81,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
private var speakerIcon: MenuItem? = null
|
private var speakerIcon: MenuItem? = null
|
||||||
private lateinit var swipeRefresh: SwipeRefreshLayout
|
private lateinit var swipeRefresh: SwipeRefreshLayout
|
||||||
private lateinit var requestPermissionLauncher: ActivityResultLauncher<String>
|
private lateinit var requestPermissionLauncher: ActivityResultLauncher<String>
|
||||||
|
private lateinit var requestPermissionsLauncher: ActivityResultLauncher<Array<String>>
|
||||||
private lateinit var accountsRequest: ActivityResultLauncher<Intent>
|
private lateinit var accountsRequest: ActivityResultLauncher<Intent>
|
||||||
private lateinit var chatRequests: ActivityResultLauncher<Intent>
|
private lateinit var chatRequests: ActivityResultLauncher<Intent>
|
||||||
private lateinit var configRequest: ActivityResultLauncher<Intent>
|
private lateinit var configRequest: ActivityResultLauncher<Intent>
|
||||||
@@ -676,6 +678,22 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requestPermissionsLauncher =
|
||||||
|
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { isGranted: Map<String, Boolean> ->
|
||||||
|
Log.e(TAG, "********** isGranted $isGranted")
|
||||||
|
if (firstRun && isGranted.isEmpty()) {
|
||||||
|
with(MaterialAlertDialogBuilder(this, R.style.AlertDialogTheme)) {
|
||||||
|
setTitle("Permissions")
|
||||||
|
setMessage(getString(R.string.mic_and_bluetooth))
|
||||||
|
setPositiveButton(getString(R.string.ok)) { dialog, _ ->
|
||||||
|
requestPermissionsLauncher.launch(arrayOf(RECORD_AUDIO, BLUETOOTH_CONNECT))
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Preferences(applicationContext).displayTheme != AppCompatDelegate.getDefaultNightMode()) {
|
if (Preferences(applicationContext).displayTheme != AppCompatDelegate.getDefaultNightMode()) {
|
||||||
AppCompatDelegate.setDefaultNightMode(Preferences(applicationContext).displayTheme)
|
AppCompatDelegate.setDefaultNightMode(Preferences(applicationContext).displayTheme)
|
||||||
delegate.applyDayNight()
|
delegate.applyDayNight()
|
||||||
@@ -685,11 +703,35 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
Log.d(TAG, "Main onStart")
|
Log.e(TAG, "Main onStart")
|
||||||
|
|
||||||
if (!Utils.checkPermissions(this, arrayOf(Manifest.permission.RECORD_AUDIO)))
|
if (!Utils.checkPermissions(this, arrayOf(RECORD_AUDIO, BLUETOOTH_CONNECT)))
|
||||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.RECORD_AUDIO),
|
if (ActivityCompat.shouldShowRequestPermissionRationale(this, RECORD_AUDIO) ||
|
||||||
MIC_PERMISSION_REQUEST_CODE)
|
ActivityCompat.shouldShowRequestPermissionRationale(this, BLUETOOTH_CONNECT)) {
|
||||||
|
layout.showSnackBar(
|
||||||
|
binding.root,
|
||||||
|
if (!Utils.checkPermissions(this, arrayOf(RECORD_AUDIO)) &&
|
||||||
|
!Utils.checkPermissions(this, arrayOf(BLUETOOTH_CONNECT)))
|
||||||
|
getString(R.string.mic_and_bluetooth)
|
||||||
|
else if (!Utils.checkPermissions(this, arrayOf(RECORD_AUDIO)))
|
||||||
|
getString(R.string.no_calls)
|
||||||
|
else
|
||||||
|
getString(R.string.no_bluetooth),
|
||||||
|
Snackbar.LENGTH_INDEFINITE,
|
||||||
|
getString(R.string.ok)
|
||||||
|
) {
|
||||||
|
requestPermissionsLauncher.launch(arrayOf(RECORD_AUDIO, BLUETOOTH_CONNECT))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
requestPermissionsLauncher.launch(
|
||||||
|
arrayOf(
|
||||||
|
RECORD_AUDIO,
|
||||||
|
BLUETOOTH_CONNECT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Log.e(TAG, "********** all permissions granted")
|
||||||
|
|
||||||
val action = intent.getStringExtra("action")
|
val action = intent.getStringExtra("action")
|
||||||
if (action != null) {
|
if (action != null) {
|
||||||
@@ -1817,7 +1859,7 @@ 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) {
|
||||||
if (!BaresipService.requestAudioFocus(am, AudioAttributes.CONTENT_TYPE_SPEECH)) {
|
if (!BaresipService.requestAudioFocus(this, am, AudioAttributes.CONTENT_TYPE_SPEECH)) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.string.audio_focus_denied,
|
R.string.audio_focus_denied,
|
||||||
@@ -1856,7 +1898,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
am.addOnModeChangedListener(mainExecutor, audioModeChangedListener!!)
|
am.addOnModeChangedListener(mainExecutor, audioModeChangedListener!!)
|
||||||
if (!BaresipService.requestAudioFocus(am, AudioAttributes.CONTENT_TYPE_SPEECH))
|
if (!BaresipService.requestAudioFocus(this, am, AudioAttributes.CONTENT_TYPE_SPEECH))
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.string.audio_focus_denied,
|
R.string.audio_focus_denied,
|
||||||
|
|||||||
@@ -921,7 +921,7 @@ object Utils {
|
|||||||
}
|
}
|
||||||
if (current != speakerDevice.type) {
|
if (current != speakerDevice.type) {
|
||||||
if (speakerDevice.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE) {
|
if (speakerDevice.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE) {
|
||||||
am.clearCommunicationDevice()
|
clearCommunicationDevice(am)
|
||||||
Log.d(TAG, "Setting com device to TYPE_BUILTIN_EARPIECE")
|
Log.d(TAG, "Setting com device to TYPE_BUILTIN_EARPIECE")
|
||||||
if (!am.setCommunicationDevice(speakerDevice))
|
if (!am.setCommunicationDevice(speakerDevice))
|
||||||
Log.e(TAG, "Could not set com device")
|
Log.e(TAG, "Could not set com device")
|
||||||
@@ -973,4 +973,24 @@ object Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setCommunicationDevice(am: AudioManager, type: Int) {
|
||||||
|
val current = am.communicationDevice!!.type
|
||||||
|
Log.d(TAG, "Current com dev/mode $current/${am.mode}")
|
||||||
|
for (device in am.availableCommunicationDevices)
|
||||||
|
if (device.type == type) {
|
||||||
|
am.setCommunicationDevice(device)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
Log.d(TAG, "New com dev/mode ${am.communicationDevice!!.type}/${am.mode}")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearCommunicationDevice(am: AudioManager) {
|
||||||
|
if (Build.VERSION.SDK_INT >= 31) {
|
||||||
|
am.clearCommunicationDevice()
|
||||||
|
} else {
|
||||||
|
if (am.isSpeakerphoneOn)
|
||||||
|
am.isSpeakerphoneOn = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -508,8 +508,9 @@
|
|||||||
</string>
|
</string>
|
||||||
<string name="no_notifications">You are not able to use this application without \"Notifications\"
|
<string name="no_notifications">You are not able to use this application without \"Notifications\"
|
||||||
permission.</string>
|
permission.</string>
|
||||||
<string name="no_calls">You are not able to make or answer calls without \"Microphone\"
|
<string name="no_calls">baresip needs \"Microphone\" permission for voice calls.</string>
|
||||||
permission.</string>
|
<string name="no_bluetooth">baresip is not able to detect Bluetooth connectivity without
|
||||||
|
\"Nearby devices\" permission.</string>
|
||||||
<string name="no_video_calls">Grant \"Camera\" permission to make or answer video calls.</string>
|
<string name="no_video_calls">Grant \"Camera\" permission to make or answer video calls.</string>
|
||||||
<string name="no_backup">You are not able create backup without \"Storage\" permission.</string>
|
<string name="no_backup">You are not able create backup without \"Storage\" permission.</string>
|
||||||
<string name="no_restore">You are not able restore backup without \"Storage\" permission.</string>
|
<string name="no_restore">You are not able restore backup without \"Storage\" permission.</string>
|
||||||
@@ -519,4 +520,6 @@
|
|||||||
<string name="show_password">Show Password</string>
|
<string name="show_password">Show Password</string>
|
||||||
<string name="no_network">No network connection!</string>
|
<string name="no_network">No network connection!</string>
|
||||||
<string name="audio_focus_denied">Audio focus denied!</string>
|
<string name="audio_focus_denied">Audio focus denied!</string>
|
||||||
|
<string name="mic_and_bluetooth">baresip needs \"Microphone\" permission for calls and
|
||||||
|
\"Nearby devices\" permission for Bluetooth detection.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user