How to play audio through earpiece in android 12?

Viewed 1112

I am developing a voice call app for android using PeerJS and WebView. And I want the audio to play through the earpiece. Here is my code,

private fun initAudio(){
  am = getSystemService(AUDIO_SERVICE) as AudioManager
  volumeControlStream = AudioManager.STREAM_VOICE_CALL
  am.mode = AudioManager.MODE_IN_COMMUNICATION
  am.isSpeakerphoneOn = false//<= not working in android 12
}

private fun toggleSpeakerMode(){
  am.isSpeakerphoneOn = !am.isSpeakerphoneOn // <= final value is always true in android 12
}

The above code works fine on older versions of android, but not in android 12 (emulator). am.isSpeakerphoneOn is always true in android 12. Am I doing something wrong here? Or is it a bug in the emulator?

UPDATE

This problem only occurs after the webRTC stream gets started on the WebView (I'm able to toggle the loudspeaker before the stream).

2 Answers

there is a new API call in Android 12/S/API 31, setCommunicationDevice(AudioDeviceInfo). for switching between speaker an built-in earpiece now we can use:

ArrayList<Integer> targetTypes = new ArrayList<>();
if (earpieceMode) {
    targetTypes.add(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);
} else { // play out loud
    targetTypes.add(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
}
// more targetTypes may be added in some cases
// set up will pick and first available, so order matters

List<AudioDeviceInfo> devices = audioManager.getAvailableCommunicationDevices();
outer:
for (Integer targetType : targetTypes) {
    for (AudioDeviceInfo device : devices) {
        if (device.getType() == targetType) {
            boolean result = audioManager.setCommunicationDevice(device);
            Log.i("AUDIO_MANAGER", "setCommunicationDevice type:" + targetType + " result:" + result);
            if (result) break outer;
        }
    }
}

mode change isn't needed (but for voip calls is strongly suggested) and my streams are AudioManager.STREAM_VOICE_CALL type (where applicable)

By default webrtc uses earpiece for voice playing. However,alternatively You can call the setSpeakerphoneOn(false) that is defined in the AudioManager.java class.

Just pass false in this function parameter and it will disable the speaker phone in the call and earpiece will be used. I have also tested it on the android 12 phones and it is working fine.

If issue still persist then you have some bug in your emulator.

Related