From c2cf2e5d6954b949685b29ceb07e75dbf1b7bdd1 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Fri, 20 Jan 2023 02:37:37 +0200 Subject: [PATCH] Turning on SpeakerPhone does not work in Android API >= 31 when audio mode is IN_COMMUNICATION --- .../com/tutpro/baresip/BaresipService.kt | 3 +- .../kotlin/com/tutpro/baresip/MainActivity.kt | 10 +++++-- .../main/kotlin/com/tutpro/baresip/Utils.kt | 30 +++++++++++++++++++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index c539b1b4..39cc8d28 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -41,7 +41,6 @@ import java.util.* import kotlin.collections.ArrayList import kotlin.concurrent.schedule import kotlin.math.roundToInt -import kotlin.system.exitProcess class BaresipService: Service() { @@ -880,7 +879,7 @@ class BaresipService: Service() { call.remove() if (Call.calls().size == 0) { resetCallVolume() - am.isSpeakerphoneOn = false + Utils.setSpeakerPhone(am, false) am.stopBluetoothSco() abandonAudioFocus() am.mode = AudioManager.MODE_NORMAL diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt index f3105c5f..bbff9c65 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt @@ -1144,8 +1144,12 @@ class MainActivity : AppCompatActivity() { if (acc.missedCalls) callsButton.setImageResource(R.drawable.calls_missed) } - if (speakerIcon != null) - speakerIcon!!.setIcon(R.drawable.speaker_off) + if (speakerIcon != null) { + if (am.isSpeakerphoneOn) + speakerIcon!!.setIcon(R.drawable.speaker_on) + else + speakerIcon!!.setIcon(R.drawable.speaker_off) + } if ((Build.VERSION.SDK_INT >= 22 && kgm.isDeviceLocked) || (Build.VERSION.SDK_INT < 22 && kgm.isKeyguardLocked && kgm.isKeyguardSecure)) Utils.setShowWhenLocked(this, false) @@ -1230,7 +1234,7 @@ class MainActivity : AppCompatActivity() { } R.id.speakerIcon -> { - am.isSpeakerphoneOn = !am.isSpeakerphoneOn + Utils.setSpeakerPhone(am, !am.isSpeakerphoneOn) if (am.isSpeakerphoneOn) item.setIcon(R.drawable.speaker_on) else diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt index 32dbfddd..ee400798 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt @@ -25,6 +25,8 @@ import android.view.View import android.view.WindowManager import android.widget.ImageView import android.widget.TextView +import android.media.AudioDeviceInfo +import android.media.AudioManager import androidx.activity.result.ActivityResultLauncher import androidx.annotation.RequiresApi import androidx.core.content.ContextCompat @@ -890,4 +892,32 @@ object Utils { return bitmap } + fun setSpeakerPhone(am: AudioManager, state: Boolean) { + // Currently at API levels 31+, speakerphone cannot be turned on during call + Log.d(TAG, "Speakerphone is ${am.isSpeakerphoneOn}") + if (state) { + if (Build.VERSION.SDK_INT >= 31 && am.mode != AudioManager.MODE_IN_COMMUNICATION) { + var speakerDevice: AudioDeviceInfo? = null + for (device in am.availableCommunicationDevices) + if (device.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) { + speakerDevice = device + break + } + if (speakerDevice != null) { + if (!am.setCommunicationDevice(speakerDevice)) + Log.e(TAG, "Could not turn on speaker device") + } + } else { + if (Build.VERSION.SDK_INT < 31) + am.isSpeakerphoneOn = true + } + } else { + if (Build.VERSION.SDK_INT >= 31) + am.clearCommunicationDevice() + else + am.isSpeakerphoneOn = false + } + Log.d(TAG, "Speakerphone is ${am.isSpeakerphoneOn}") + } + }