Tintef / react-native-headphone-detection

React Native headphone detection, both audio jack and bluetooth devices!
MIT License
45 stars 19 forks source link

Ios Listener is repeating non stop #14

Open AbdulmalickDimnang opened 3 years ago

AbdulmalickDimnang commented 3 years ago

Hello, My is does use webRTC as well as react-native-incall-manager to control media call. So, I wanted to have a listener whenever a bluetooth or wired is connected to a device and I came across react-native-headphone-detection. But I'm having issues with the listener on ios devices where it rapidly executing the listener function over and over again which freezes the app completely. You can find the following sample code of the issue where it logs the listener rapidly without stopping.

P.S. the wired thing is that when I remove InCallManager.setSpeakerphoneOn() from the listener.. the listener only run once which is fine, but when I add this function from InCallManager it runs non stopping. I have used react-native-switch-audio-output to control speaker instead of using react-native-incall-manager and still the issue occurs. This issue only occurs on iOS devices (I have tested on real ios device SE). Although Android works fine but it seems the listener runs twice whenever I connect/disconnect with a wired/bluetooth headset

import React, { PureComponent } from 'react';
import {
  View,
  Text,
  StyleSheet,
} from 'react-native';
import InCallManager from 'react-native-incall-manager';
import HeadphoneDetection from 'react-native-headphone-detection';

export default class Playground extends PureComponent {
  constructor() {
    super();

    this.state = {
      bluetoothAudio: false,
      wireAudio: false,
    };

    this.onHeadphoneChanged = this.onHeadphoneChanged.bind(this);
  }

  componentDidMount = () => {
    HeadphoneDetection.isAudioDeviceConnected().then((data) => {
      const { audioJack, bluetooth } = data;
      this.setState({
        bluetoothAudio: bluetooth,
        wireAudio: audioJack,
      });
    });
    HeadphoneDetection.addListener(this.onHeadphoneChanged);
  }

  onHeadphoneChanged = (data) => {
    const { audioJack, bluetooth } = data;
    this.setState({
      bluetoothAudio: bluetooth,
      wireAudio: audioJack,
    });
    if (bluetooth || audioJack) {
      InCallManager.setSpeakerphoneOn(false);
    } else {
      InCallManager.setSpeakerphoneOn(true);
    }
    console.log({
      bluetoothAudio: bluetooth,
      wireAudio: audioJack,
    });
  }

  render() {
    return (
      <View style={styles.container}>
        <Text>{`Bluetooth Status: ${this.state.bluetoothAudio}`}</Text>
        <Text>{`Wired Status: ${this.state.wireAudio}`}</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

react-native: v0.63.3 react-native-headphone-detection: v1.3.0 react-native-incall-manager: v3.3.0 react-native-switch-audio-output: v1.1.2

ghost commented 3 years ago

@AbdulmalickDimnang react-native-headphone-detection on iOS using AVAudioSession for listeners, I think maybe you're using packages that also using AVAudioSession call that's why it's repeating. I also face that problem because I use EZAudio and it use AVAudioSession to check microphone whenever it changes.