2

I am making a calling app where users may or may not use headphones / a headset. On an incoming video call I am using react-native-incall-manager to turn the speaker on / allow speaker phone. The basic InCallManager.start({ media: 'video' }); method works and allows detection of a new audio device being plugged in such as headphones, and if this happens, the headphone and mic plugged in work as expected.

The problem comes in the case that headphones are already plugged in to the device before a call starts, because the InCallManager.setSpeakerphoneOn(true); method is called at that time. InCallManager.start({ media: 'video' }); doesn't account for devices already connected and the headphones do not work, the normal speaker does even though headphones are plugged in.

react-native-incall-manager recommends using DeviceEventEmitter from react-native to detect native events such as changes in connected audio devices, but this module is deprecated.

Here it is recommended to use NativeEventEmitter, but this seems very complex and seems to require the native Java (Android) modules to be written and used in conjunction with it.

How can I detect changes in connected audio devices in Android in React Native?

Mr. Robot
  • 1,334
  • 6
  • 27
  • 79

1 Answers1

1

Here it is recommended to use NativeEventEmitter, but this seems very complex and seems to require the native Java (Android) modules to be written and used in conjunction with it.

You don't need to write a native Java module for this job since NativeEventEmitter can pick up events that were sent through RCTDeviceEventEmitter.

So example from react-native-incall-manager README

import { DeviceEventEmitter } from 'react-native';

DeviceEventEmitter.addListener('Proximity', function (data) {
    // --- do something with events
});

can be easily rewritten to this

import { NativeEventEmitter, NativeModules } from 'react-native';

const eventEmitter = new NativeEventEmitter(NativeModules.InCallManager);
eventListener = eventEmitter.addListener('Proximity', event => {
  // do something with events
});

Just don't forget to clean up once you no longer need event listeners

eventListener.remove();

If you want to detect changes in connected audio devices you can subscribe to onAudioDeviceChanged event from react-native-incall-manager. It sends something like this whenever there is a change in connected audio devices or device that will output sound

{"availableAudioDeviceList": "[\"BLUETOOTH\",\"SPEAKER_PHONE\",\"EARPIECE\"]", "selectedAudioDevice": "EARPIECE"}
Konstantin
  • 24,271
  • 5
  • 48
  • 65