'setSpeakerphoneOn from AudioManager is not changing speakerphone value on android 12, it always remains false. Why?

fun toggleSpeaker(context: Context) {
        isSpeakerPhoneSelected.value?.let {
            val audioManager: AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
            audioManager.setSpeakerphoneOn = !it
            isSpeakerPhoneSelected.value = !it
            logDebug(context, it.toString().plus(audioManager.isSpeakerphoneOn.toString()))
        }
    }

The logger shows that the isSpeakerPhoneSelected value is toggling between true and false but isSpeakerphoneOn always returns false. This stopped working as of Android 12.

These are the versions in our build.gradle:

        buildToolsVersion = "29.0.3"
        minSdkVersion = 23
        compileSdkVersion = 30
        targetSdkVersion = 30
        supportLibVersion = "28.0.0"

What is causing the isSpeakerphoneOn value not to change and how to fix this? I've been beating my head against the wall over this for some time now so I appreciate any suggestions :p Thanks!



Solution 1:[1]

I've come across the same issue earlier when I set the targetSDKLevel to android 12. I'd a call screen over which I provided a speaker button through which user can turn on/off the speaker.

I used AudioDeviceInfo API for android 12 to set the communication device on audioManager.

public void switchSpeakerState() {
        if (isSpeakerOn) {
            isSpeakerOn = false;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
                Utils.getInstance().setCommunicationDevice(getContext(), AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);
            } else {
                audioManager.setSpeakerphoneOn(false);
            }
            ivSpeaker.setImageResource(R.drawable.speaker_outline);
        } else {
            isSpeakerOn = true;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
                Utils.getInstance().setCommunicationDevice(getContext(), AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
            } else {
                audioManager.setSpeakerphoneOn(true);
            }
            ivSpeaker.setImageResource(R.drawable.speaker_filled);
        }
    }

Utils.java

@RequiresApi(api = Build.VERSION_CODES.S)
public void setCommunicationDevice(Context context, Integer targetDeviceType) {
    AudioManager audioManager = (AudioManager) context.getSystemService(AUDIO_SERVICE);
    List < AudioDeviceInfo > devices = audioManager.getAvailableCommunicationDevices();
    for (AudioDeviceInfo device: devices) {
        if (device.getType() == targetDeviceType) {
            boolean result = audioManager.setCommunicationDevice(device);
            Log.d("result: ", result);
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ammar Abdullah