Skip to content

The Speaker icon is removed, while switching the route from Bluetooth or Microphone to Speaker from the call kit screen. #759

Open

Description

@Aayushi-Mashru

Bug report

  • I've checked the example to reproduce the issue.

  • Reproduced on:

  • Android

  • iOS

Description

I am using RNCallKeep and react-native-incall-manager to handle the audio routing from the application UI, during VOIP calls.
While switching the route from Bluetooth or Microphone to Speaker from the call kit screen, the Speaker icon is visible for a split second then it changes back to the previous route icon (Bluetooth / Microphone). However, the route stays on Speaker.
Although switching back to Bluetooth / Microphone works fine and the icon is also updated accordingly.

I am receiving the audio route change notification for "Speaker" in the following method in onAudioRouteChange method in RNCallKeep.m. Also, on the JS side, I am getting the Event as well as shown in bold in the below logs, however on the callkit screen the icon changes to Bluetooth again.

Steps to Reproduce

  • Connect a Bluetooth headset to your iOS device
  • Initiate or receive a VOIP call
  • When the route is set to Bluetooth/Microphone
  • Now switch the route to Speaker from the Callkit screen (issue is reproduced here)
  • Now again switching the route to Microphone or Bluetooth also works fine.
RPReplay_Final1706193054.MP4

Versions

- Callkeep: 4.3.12
- React Native: 0.72.9
- iOS: all
- Phone model: iPhone 7 plus

Logs

Bluetooth_logs.zip

2024-01-25 18:13:08.970367+0530 [864:288247] RNInCallManager.start() start InCallManager. media=audio, type=audio, mode=AVAudioSessionModeVoiceChat
2024-01-25 18:13:08.970608+0530 [864:288247] RNInCallManager.storeOriginalAudioSetup(): origAudioCategory=AVAudioSessionCategoryPlayAndRecord, origAudioMode=AVAudioSessionModeDefault
2024-01-25 18:13:08.974912+0530 [864:288247] RNInCallManager.startAudioSessionNotification() starting...
2024-01-25 18:13:08.975025+0530 [864:288247] RNInCallManager.startAudioSessionInterruptionNotification()
2024-01-25 18:13:08.975299+0530 [864:288247] RNInCallManager.startAudioSessionRouteChangeNotification()
2024-01-25 18:13:08.975354+0530 [864:288247] RNInCallManager.startAudioSessionMediaServicesWereLostNotification()
2024-01-25 18:13:08.975435+0530 [864:288247] RNInCallManager.startAudioSessionMediaServicesWereResetNotification()
2024-01-25 18:13:08.975465+0530 [864:288247] RNInCallManager.startAudioSessionSilenceSecondaryAudioHintNotification()
2024-01-25 18:13:08.975839+0530 [864:288247] RNInCallManager.start:auto:ringbackUriType:: audioSession.setCategory: AVAudioSessionCategoryPlayAndRecord, withOptions: 0 success
2024-01-25 18:13:08.976143+0530 [864:288247] RNInCallManager.start:auto:ringbackUriType:: audioSession.setMode(AVAudioSessionModeVoiceChat) success
2024-01-25 18:13:08.979351+0530 [864:288247] RNInCallManager.start:auto:ringbackUriType:: audioSession.setActive(YES), withOptions: 0 success
2024-01-25 18:13:08.979435+0530 [864:288247] RNInCallManager.startProximitySensor()
2024-01-25 18:13:08.979533+0530 [864:288247] RNInCallManager.setKeepScreenOn(): enable: YES

2024-01-25 18:13:09.614664+0530 [864:288020] [RNCallKeep][CXProviderDelegate][provider:didActivateAudioSession]
2024-01-25 18:13:09.614908+0530 [864:288020] RNInCallManager.AudioSessionInterruptionNotification: Ended
2024-01-25 18:13:09.614949+0530 [864:288020] [RNCallKeep][configureAudioSession] Activating audio session

2024-01-25 18:13:09.746392+0530 [864:288020] [RNCallKeep] sendEventWithNameWrapper: RNCallKeepDidActivateAudioSession, hasListeners : YES

2024-01-25 18:13:09.847646+0530 [864:288020] RNInCallManager.AVAudioSessionSilenceSecondaryAudioHintNotification: End
2024-01-25 18:13:09.878653+0530 [864:288249] [javascript] Inside Event Listener RNCallKeep didChangeAudioRoute
2024-01-25 18:13:09.878762+0530 [864:288249] [javascript] Receiver


2024-01-25 18:13:09.973877+0530 [864:288020] RNInCallManager.updateAudioRoute(): did NOT overrideOutputAudioPort()
2024-01-25 18:13:09.985134+0530 [864:288020] RNInCallManager.updateAudioRoute() did NOT change audio category
2024-01-25 18:13:09.985216+0530 [864:288020] RNInCallManager.updateAudioRoute() did NOT change audio mode
2024-01-25 18:13:09.985249+0530 [864:288020] RNInCallManager.AudioRouteChange.SilenceSecondaryAudioHint: End
2024-01-25 18:13:09.985276+0530 [864:288020] RNInCallManager.AudioRouteChange.SilenceSecondaryAudioHint: Unknow Value


2024-01-25 18:13:11.843002+0530 [864:288020] RNInCallManager.AudioRouteChange.Reason: CategoryChange. category=AVAudioSessionCategoryPlayAndRecord mode=AVAudioSessionModeVoiceChat
2024-01-25 18:13:11.843219+0530 [864:288020] RNInCallManager.updateAudioRoute(): [Enter] forceSpeakerOn flag=0 media=audio category=AVAudioSessionCategoryPlayAndRecord mode=AVAudioSessionModeVoiceChat
2024-01-25 18:13:11.844413+0530 [864:288020] RNInCallManager.updateAudioRoute(): did NOT overrideOutputAudioPort()
2024-01-25 18:13:11.844540+0530 [864:288020] RNInCallManager.updateAudioRoute() did NOT change audio category
2024-01-25 18:13:11.844576+0530 [864:288020] RNInCallManager.updateAudioRoute() did NOT change audio mode
2024-01-25 18:13:11.844609+0530 [864:288020] RNInCallManager.AudioRouteChange.SilenceSecondaryAudioHint: End
2024-01-25 18:13:11.844637+0530 [864:288020] RNInCallManager.AudioRouteChange.SilenceSecondaryAudioHint: Unknow Value

2024-01-25 18:13:15.427909+0530 [864:288249] [javascript] Printing Before Audio Routes in ComponenetDidMount iOS
2024-01-25 18:13:15.430607+0530 [864:288524] [RNCallKeep][getAudioRoutes]
2024-01-25 18:13:15.590945+0530 [864:288249] [javascript] Printing Audio Routes in ComponenetDidMount iOS
2024-01-25 18:13:15.591650+0530 [864:288249] [javascript] [ { name: 'Speaker', type: 'Speaker' },
  { name: 'iPhone Microphone', selected: true, type: 'Phone' },
  { name: 'Rockerz 238 Pro', type: 'Bluetooth' } ]
2024-01-25 18:13:15.593427+0530 [864:288524] [RNCallKeep][getAudioRoutes]
2024-01-25 18:13:15.599402+0530 [864:288249] [javascript] Audio Route SetTImeOut changed
2024-01-25 18:13:15.599523+0530 [864:288249] [javascript] Getting route
2024-01-25 18:13:15.600062+0530 [864:288249] [javascript] [ { name: 'Speaker', type: 'Speaker' },
  { name: 'iPhone Microphone', selected: true, type: 'Phone' },
  { name: 'Rockerz 238 Pro', type: 'Bluetooth' } ]
2024-01-25 18:13:15.651189+0530 [864:288249] [javascript] Bluetooth:AudioRoute
2024-01-25 18:13:15.750667+0530 [864:288249] [javascript] 'ChangeRoute: ios :: ', 'Bluetooth'
2024-01-25 18:13:15.750962+0530 [864:288249] [javascript] 'ChangeRoute: this.state.routeName: ', 'Rockerz 238 Pro'

2024-01-25 18:13:15.752629+0530 [864:288525] [RNCallKeep][setAudioRoute] - inputName: Rockerz 238 Pro

2024-01-25 18:13:16.123263+0530 [864:288020] RNInCallManager.AudioRouteChange.Reason: Override
2024-01-25 18:13:16.123347+0530 [864:288020] RNInCallManager.AudioRouteChange.SilenceSecondaryAudioHint: End
2024-01-25 18:13:16.123375+0530 [864:288020] RNInCallManager.AudioRouteChange.SilenceSecondaryAudioHint: Unknow Value
2024-01-25 18:13:16.180331+0530 [864:288249] [javascript] Inside Event Listener RNCallKeep didChangeAudioRoute
2024-01-25 18:13:16.180445+0530 [864:288249] [javascript] BluetoothHFP
2024-01-25 18:13:20.651713+0530 [864:288633] [RNCallKeep][getAudioRoutes]
2024-01-25 18:13:20.759155+0530 [864:288249] [javascript] Audio Route SetTImeOut changed
2024-01-25 18:13:20.759796+0530 [864:288249] [javascript] Getting route
2024-01-25 18:13:20.761072+0530 [864:288249] [javascript] [ { name: 'Speaker', type: 'Speaker', selected: true },
  { name: 'iPhone Microphone', type: 'Phone' },
  { name: 'Rockerz 238 Pro', type: 'Bluetooth' } ]
2024-01-25 18:13:20.777916+0530 [864:288020] RNInCallManager.AudioRouteChange.Reason: Override
2024-01-25 18:13:20.778024+0530 [864:288020] RNInCallManager.AudioRouteChange.SilenceSecondaryAudioHint: End
2024-01-25 18:13:20.778059+0530 [864:288020] RNInCallManager.AudioRouteChange.SilenceSecondaryAudioHint: Unknow Value
**2024-01-25 18:13:20.987289+0530 [864:288249] [javascript] Inside Event Listener RNCallKeep didChangeAudioRoute
2024-01-25 18:13:20.987796+0530 [864:288249] [javascript] Speaker**
2024-01-25 18:13:22.546169+0530 [864:288249] [javascript] Thu Jan 25 2024 18:13:22 GMT+0530 | sip.Transport | Sending WebSocket message:
2024-01-25 18:13:25.678314+0530 [864:288249] [javascript] Inside Event Listener RNCallKeep didChangeAudioRoute
2024-01-25 18:13:25.678435+0530 [864:288249] [javascript] Receiver
2024-01-25 18:13:25.679460+0530 [864:288020] RNInCallManager.AudioRouteChange.Reason: CategoryChange. category=AVAudioSessionCategoryPlayAndRecord mode=AVAudioSessionModeVoiceChat
2024-01-25 18:13:25.679736+0530 [864:288020] RNInCallManager.updateAudioRoute(): [Enter] forceSpeakerOn flag=0 media=audio category=AVAudioSessionCategoryPlayAndRecord mode=AVAudioSessionModeVoiceChat
2024-01-25 18:13:25.680968+0530 [864:288020] RNInCallManager.updateAudioRoute(): did NOT overrideOutputAudioPort()
2024-01-25 18:13:25.681411+0530 [864:288020] RNInCallManager.updateAudioRoute() did NOT change audio category
2024-01-25 18:13:25.681478+0530 [864:288020] RNInCallManager.updateAudioRoute() did NOT change audio mode
2024-01-25 18:13:25.681513+0530 [864:288020] RNInCallManager.AudioRouteChange.SilenceSecondaryAudioHint: End
2024-01-25 18:13:25.681540+0530 [864:288020] RNInCallManager.AudioRouteChange.SilenceSecondaryAudioHint: Unknow Value
2024-01-25 18:13:25.993789+0530 [864:288525] [RNCallKeep][getAudioRoutes]
2024-01-25 18:13:26.002005+0530 [864:288249] [javascript] Audio Route SetTImeOut changed
2024-01-25 18:13:26.002414+0530 [864:288249] [javascript] Getting route
2024-01-25 18:13:26.003373+0530 [864:288249] [javascript] [ { name: 'Speaker', type: 'Speaker' },
  { name: 'iPhone Microphone', selected: true, type: 'Phone' },
  { name: 'Rockerz 238 Pro', type: 'Bluetooth' } ]


Activity

  1. jikseyres16 commented on Apr 18, 2024

    @jikseyres16

    Do you have any solution here? I'm experiencing this too, my workaround is use the RN-InCall Manager to go into Speaker Mode but doing so moving from Speaker -> Earpiece / BT -> Earpiece always redirects to BT device.

  2. wilkinsonj commented on Sep 25, 2024

    @wilkinsonj

    This is a legitimate issue. Hitting the speaker icon causes the audio to go into speaker mode, but it immediately turns off on the Apple interface

  3. L65FREAD commented on Apr 22, 2025

    @L65FREAD

    Any updates here? I am also having this issue.

  4. LarsDanau commented on May 26, 2025

    @LarsDanau

    +1

    This issue still persists for me. I've tried changing from AVAudioSessionModeDefault to AVAudioSessionModeVoiceChat.
    I've also tried adding options such as AVAudioSessionCategoryOptionAllowBluetoothA2DP, AVAudioSessionCategoryOptionDuckOthers, AVAudioSessionCategoryOptionMixWithOthers but without any luck.

  5. NCSmit commented on Nov 3, 2025

    @NCSmit

    Any updates? I am experiencing this issue too.

  6. malekmajzoubFC commented on Apr 13, 2026

    @malekmajzoubFC

    I am facing the same issue. Did anyone find a solution for this please?

  7. octaviotastico commented on Jul 31, 2026

    @octaviotastico

    We saw a very similar route state problem in an Expo SDK 56 application using React Native 0.85.3.

    During a CallKit call, route changes could be emitted in quick succession. The native route was changed successfully, but a later event could make the CallKit UI show the previous route again. In our local fix, application-level route requests are queued until didActivateAudioSession and only the latest request is applied after activation.

    We also made the iOS route handling use the route type for the built-in Phone route, rather than relying only on the displayed name. This helped keep the native state and the UI consistent across physical iPhones.

    Separately, PR #845 fixes a crash that occurred when one of these route operations failed and RNCallKeep passed an NSException directly to a Promise rejection. This issue is useful context for the broader audio route reliability work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions