kenjdavidson / react-native-bluetooth-classic

⚛ Bluetooth classic Android(Bluetooth)/IOS(ExternalAccessory) module for serial communication
https://kenjdavidson.github.io/react-native-bluetooth-classic
MIT License
250 stars 94 forks source link

Auto Linking Not Working Properly #289

Closed KartikDevarde2601 closed 10 months ago

KartikDevarde2601 commented 10 months ago

Device: Android OS: API22 Application Environment

React Native version: v0.71.0 RN Bluetooth Classic version: ^1.60.0-rc.30"

useEffect(() => {
    setTimeout(() => connect(), 0);
  }, []);

  const connect = async () => {
    try {
      let connection = await item.isConnected();
      connection.log(`connection: ${connection}`);
    } catch (error) {
      console.log(`connect error:${error}`);
    }
  };

Describe the bug The provided code snippet checking similar to example repo to connect to a Bluetooth device using item.isConnected(), but an error occurs with the message ERROR :: "TypeError: undefined is not a function". Upon investigating, it was found that the necessary dependency for the react-native-bluetooth-classic library was missing from the Gradle files. my be The issue related to autolinking, as the implementation (':react-native-bluetooth-classic') dependency is not present in the code.

dependencies {
    ...
    implementation project(':react-native-bluetooth-classic')
    ...
} //present in example repo not in my code

but the const enabled = await RNBluetoothClassic.isBluetoothEnabled(); i getting pair devices state:

{
  "devices": [
    {
      "_bluetoothModule": {
        "_nativeModule": {},
        "_eventEmitter": {
          "_nativeModule": {}
        }
      },
      "_nativeDevice": {
        "extra": {},
        "id": "B4:9A:95:D6:FB:D4",
        "deviceClass": {
          "majorClass": 1024,
          "deviceClass": 1028
        },
        "address": "B4:9A:95:D6:FB:D4",
        "bonded": true,
        "name": "realme Buds Wireless 2 Neo"
      },
      "name": "realme Buds Wireless 2 Neo",
      "address": "B4:9A:95:D6:FB:D4",
      "id": "B4:9A:95:D6:FB:D4",
      "bonded": true,
      "deviceClass": {
        "majorClass": 1024,
        "deviceClass": 1028
      },
      "extra": {}
    }
  ]
}

pls help i stuck i have to resolve this issue i not understand it problem with auto-linking or any thing else

To Reproduce Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior A clear and concise description of what you expected to happen.

Screenshots If applicable, add screenshots to help explain your problem.

Additional context Add any other context about the problem here.

kenjdavidson commented 10 months ago

So the library is working as

const enabled = await RNBluetoothClassic.isBluetoothEnabled();

works but making requests against the device is not working?

let connection = await item.isConnected();

What is undefined on that line?

If this is a linking issue, then you'll need to look into that yourself. You can either:

KartikDevarde2601 commented 10 months ago

thank you so much for replying [kenjdavidson] item? Where is item getting set? items/pairDevice/Bonded is getting into from calling " const devices = await RNBluetoothClassic.getBondedDevices()"; i getting pair devices list then i render the list . pair device list then onclick i try to connect device. const device = await RNBluetoothClassic.connectToDevice(stringAddress); work it connected to device but i not able to send anything What is undefined on that line?

export const fetchPairedDevices = createAsyncThunk(
  'fetchPairedDevices',
  async () => {
    const devices = await RNBluetoothClassic.getBondedDevices();
    const serializableData = JSON.parse(JSON.stringify(devices));

    return serializableData;
  },
);   // i am using redux
const pairDevice = () => {
    if (isEnabled) {
      dispatch(fetchPairedDevices());
      console.log('action dispatch');
    }
  };

useEffect(() => { async function checkBluetoothEnabled() { const enabled = await RNBluetoothClassic.isBluetoothEnabled(); setIsEnabled(enabled); console.log(phone Bluetooth is ON/OFF: ${enabled});

  if (enabled) {
    pairDevice();
  } else {
    ToastAndroid.show(
      'Bluetooth is OFF, please turn it ON',
      ToastAndroid.SHORT,
    );
  }
}
` useEffect(() => {
    setTimeout(() => connect(), 0);
  }, []);

  const connect = async () => {
    try {
      let connection = await item.isConnected();
       if(!connection){
        connection = await this.props.device.connect();
        console.log(connection)
       }
    } catch (error) {
      console.log(`connect error:${error}`); 
    }
  };` 

let connection = await item.isConnected(); this line getting error LOG connect error:TypeError: undefined is not a function. isConnected check the device is connect or not ?

autoLink? so to verify auto-link working or not i have to check in the app/gradle and gradle.setting etc right may be i am wrong just learn the app development.

kenjdavidson commented 10 months ago

You'll need to debug to provide more information on this comment. If you're getting item is undefined, then you'll have to find out WHY item is undefined. If the undefined it somewhere deeper in isConnected then you'll need to figure out where it's undefined. Need substantially more info than just the error message,

let connection = await item.isConnected(); this line getting error LOG connect error:TypeError: undefined is not a function. isConnected check the device is connect or not ?

Autolinking is working, since you're able to use the library. If Auto linking wasn't working, then you would be getting an undefined when attempting to use RNBluetoothClassic.ANYTHING.

KartikDevarde2601 commented 10 months ago
const ConnectionScreen = ({navigation}) => {
  const [isEnabled, setIsEnabled] = useState(false);
  const state = useSelector(state => state.devices);
  const dispatch = useDispatch();

  const RenderItem = ({item}) => {
    console.log(`item: ${JSON.stringify(item)}`);
    return (
      <TouchableOpacity
        onPress={() => navigation.navigate('communication', {item})}>
        <View style={styles.Itemcontainer}>
          <View style={styles.icon}>
            {item.deviceClass.majorClass === 1024 ? (
              <FontAwesomeIcon icon={faHeadset} size={25} color="#808080" />
            ) : (
              <FontAwesomeIcon icon={faMicrochip} size={25} color="#808080" />
            )}
          </View>
          <View style={styles.deviceNameWrap}>
            <Text style={styles.deviceName}>
              {item.name ? item.name : item.id}
            </Text>
            <Text style={styles.deviceAddress}>{item.address}</Text>
          </View>
        </View>
      </TouchableOpacity>
    );
  };

  const pairDevice = () => {
    if (isEnabled) {
      dispatch(fetchPairedDevices());
      console.log('action dispatch');
    }
  };

  useEffect(() => {
    async function checkBluetoothEnabled() {
      const enabled = await RNBluetoothClassic.isBluetoothEnabled();
      setIsEnabled(enabled);
      console.log(`phone Bluetooth is ON/OFF: ${enabled}`);

      if (enabled) {
        pairDevice();
      } else {
        ToastAndroid.show(
          'Bluetooth is OFF, please turn it ON',
          ToastAndroid.SHORT,
        );
      }
    }

    checkBluetoothEnabled();
  }, [isEnabled]);

  const startScanning = async () => {
    try {
      console.log('start scanning');
      const DiscoverDevices = await RNBluetoothClassic.startDiscovery();
      console.log(`DiscoverDevices: ${JSON.stringify(DiscoverDevices)}`);
      // Do something with the discovered devices
    } catch (error) {
      console.error(error);
    } finally {
      await RNBluetoothClassic.cancelDiscovery();
    }
  }; // connetion screen 
const CommunicationScreen = ({navigation, route}) => {
  // Hook to get route object
  const [text, setText] = useState('');
  const {item} = route.params; // Get the connected device from route params
  console.log(`item:${item}`);

  useEffect(() => {
    setTimeout(() => connect(), 0);
  }, []);

  const connect = async () => {
    try {
      let connection = await item.isConnected();
       if(!connection){
        connection = await this.props.device.connect();
        console.log(connection)
       }
    } catch (error) {
      console.log(`connect error:${error}`);
    }
  };

state:{"devices":[{"_bluetoothModule":{"_nativeModule":{},"_eventEmitter":{"_nativeModule":{}}},"_nativeDevice":{"extra":{},"id":"B4:9A:95:D6:FB:D4","deviceClass":{"majorClass":1024,"deviceClass":1028},"address":"B4:9A:95:D6:FB:D4","bonded":true,"name":"realme Buds Wireless 2 Neo"},"name":"realme Buds Wireless 2 Neo","address":"B4:9A:95:D6:FB:D4","id":"B4:9A:95:D6:FB:D4","bonded":true,"deviceClass":{"majorClass":1024,"deviceClass":1028},"extra":{}},{"_bluetoothModule":{"_nativeModule":{},"_eventEmitter":{"_nativeModule":{}}},"_nativeDevice":{"extra":{},"id":"41:42:99:2C:65:06","deviceClass":{"majorClass":1024,"deviceClass":1048},"address":"41:42:99:2C:65:06","bonded":true,"name":"TWS"},"name":"TWS","address":"41:42:99:2C:65:06","id":"41:42:99:2C:65:06")

KartikDevarde2601 commented 10 months ago

https://github.com/KartikDevarde2601/blu can you please check my repo if any thing wrong i am doing

kenjdavidson commented 10 months ago

I think this is a little suspect

  const {item} = route.params; // Get the connected device from route params

Using route params to pass the full device object might not be wise. There could be some copying or some other internal functionality that removes some of the needed content (for example the Native Module internals). I would suggest against doing this, I haven't done this in the sample app and cannot confirm it should work.

KartikDevarde2601 commented 10 months ago

so any other way to pass the object/data to one screen to another ? in redux i getting no-serializable data error so i serials by


export const fetchPairedDevices = createAsyncThunk(
  'fetchPairedDevices',
  async () => {
    const devices = await RNBluetoothClassic.getBondedDevices();
    const serializableData = JSON.parse(JSON.stringify(devices));

    return serializableData;
  },
);
```  this is not remove the  Native Module internals or i change this also
kenjdavidson commented 10 months ago

This is for you to decide, there are a number of ways:

Going to close this as it's not a library issue, but a React design issue.

Good luck.

KartikDevarde2601 commented 10 months ago

thank you so much for helping..