react-native-incall-manager icon indicating copy to clipboard operation
react-native-incall-manager copied to clipboard

Unable to change from speaker to bluetooth device instead it is routing audio to phone earpiece

Open yashecosmob opened this issue 1 year ago • 8 comments

As I am using setAudioRoute to set back to bluetooth and I am not able to switch

await InCallManager.setAudioRoute(‘’,'BLUETOOTH').then((response) => {
})

iOS Native function

RCT_EXPORT_METHOD(setAudioRoute: (NSString *)uuid
                 inputName:(NSString *)inputName
                 resolver:(RCTPromiseResolveBlock)resolve
                 rejecter:(RCTPromiseRejectBlock)reject)
{
#ifdef DEBUG
   NSLog(@"[RNCallKeep][setAudioRoutesetAudioRoute] - inputName: %@", inputName);
#endif
   @try {
       NSError* err = nil;
       AVAudioSession* myAudioSession = [AVAudioSession sharedInstance];
       if ([inputName isEqualToString:@"Speaker"]) {
           BOOL isOverrided = [myAudioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&err];
           if(!isOverrided){
               [NSException raise:@"overrideOutputAudioPort failed" format:@"error: %@", err];
           }
           resolve(@"Speaker");
           return;
       }


       NSArray *ports = [RNInCallManager getAudioInputs];
       for (AVAudioSessionPortDescription *port in ports) {
           if ([port.portName isEqualToString:inputName]) {
               BOOL isSetted = [myAudioSession setPreferredInput:(AVAudioSessionPortDescription *)port error:&err];
               if(!isSetted){
                   [NSException raise:@"setPreferredInput failed" format:@"error: %@", err];
               }
               resolve(inputName);
               return;
           }
       }
   }
   @catch ( NSException *e ){
       NSLog(@"[RNCallKeep][setAudioRoute] exception: %@",e);
       reject(@"Failure to set audio route", e, nil);
   }
}

What I tried:

  • Setting the setAudioRoute directly
  • Setting the route to bluetooth directly from avaudiosessionListener

yashecosmob avatar May 08 '23 08:05 yashecosmob

Same here. Any updates?

gustavo-amaro avatar Jun 12 '23 12:06 gustavo-amaro

@yashecosmob @gustavo-amaro did you find a solution?

wilmxre avatar Nov 01 '23 20:11 wilmxre

In my case outgoing call. I must request bluetooth permission https://github.com/zoontek/react-native-permissions before. Note:

  • setAudioRoute only working in android.
  • For IOS, you can use function InCallManager.setForceSpeakerphoneOn(true/false); to switch audio. Note function setSpeakerphoneOn not working when connect bluetooth device.

anhquangtech avatar Jan 24 '24 02:01 anhquangtech

@anhquangtech Can you elaborate on how InCallManager.setForceSpeakerphoneOn(true/false) can be used to switch audio. Especially in iOS. I'm trying to connect to bluetooth in iOS and wasn't able to do so with this method. Is there documentation about the same?

zxar7 avatar Feb 15 '24 05:02 zxar7

InCallManager.setForceSpeakerphoneOn(true/false) is just to route the audio to the Speakers, it has no effect for Bluetooth. For Bluetooth, try InCallManager.chooseAudioRoute('BLUETOOTH'). Be aware that for incoming call, the call has to connect and only after you can route the audio to Bluetooth. So either way try calling the routing method with a button press after the call connection was already established, to test it, or just call it with a setTimeout of a few seconds.

wilmxre avatar Feb 15 '24 10:02 wilmxre

@wilmxre Does this mean that it needs to be set a few seconds after InCallManager.start()? Also InCallManager.chooseAudioRoute('BLUETOOTH') just returns the error TypeError: undefined is not a function. I'm not sure it works anymore.

zxar7 avatar Feb 15 '24 11:02 zxar7

Oddly enough in Android the InCallManager.start() alone seems to route it correctly between the phone's mic and bluetooth. But the same does not work for iOS.

zxar7 avatar Feb 15 '24 11:02 zxar7