dotintent / react-native-ble-plx

React Native BLE library
Apache License 2.0
3.05k stars 513 forks source link

#Issue While connecting Bluetooth device with react native android application paring pop-up appearing twice issue #1113

Open SatyendraM1990 opened 1 year ago

SatyendraM1990 commented 1 year ago

Prerequisites

Expected Behavior

I am working in react native application. In this application I am have integrated react-native ble-plx library. I have gone through with the related documents integrated successfully. But the issue is while pairing with the Bluetooth device with application paring pop-up appearing twice/trice in android device

While the same code is working fine with IOS platform Android version 13 Mobile : Motorola, google pixel, samsung Here are the specification : react-native version: installed: 0.68.2

react-native ble-plx: installed version : 3.0.0 (recently updated version) With older version also the same (V 2.0.3)

Current Behavior

Following steps:

  1. Bluetooth hardware device has serial no and pass key which written on it
  2. So in application fields to enter these details and connect is button to navigate to pair screen.
  3. In pair screen just need to switch on the device and click on pair button that used to call scanDevice() function from BleManager constructor.
  4. Provided all the permission location and all also while pairing the device also checking all permission.
  5. So after clicking on pair button create a bluetooth instance and shows the pop-up pair a device
  6. once we click on pair a device in middle another pop to click pair
  7. This pair a device and other pop is appearing three time then pairing successful
  8. It should ask one time and should pair in one event only

This application and feature is working fine for IOS device , problem is in android application. android 12/13 both version I have checked

Library version

V 3.0.0

Device

Moto G 13, google Pixel 4,

Environment info

System:
  OS: Windows 10 10.0.22621
  CPU: (8) x64 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
  Memory: 3.12 GB / 19.78 GB
Binaries:
  Node:
    version: 18.17.1
    path: C:\Program Files\nodejs\node.EXE
  Yarn: Not Found
  npm:
    version: 9.6.7
    path: C:\Program Files\nodejs\npm.CMD
  Watchman: Not Found
SDKs:
  Android SDK: Not Found
  Windows SDK: Not Found
IDEs:
  Android Studio: AI-223.8836.35.2231.10671973
  Visual Studio: Not Found
Languages:
  Java: 11.0.19
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 17.0.2
    wanted: 17.0.2
  react-native:
    installed: 0.68.2
    wanted: 0.68.2
  react-native-windows: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: false
  newArchEnabled: false
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

Steps to reproduce

Following steps:

  1. Bluetooth hardware device has serial no and pass key which written on it
  2. So in application fields to enter these details and connect is button to navigate to pair screen.
  3. In pair screen just need to switch on the device and click on pair button that used to call scanDevice() function from BleManager constructor.
  4. Provided all the permission location and all also while pairing the device also checking all permission.
  5. So after clicking on pair button create a bluetooth instance and shows the pop-up pair a device
  6. once we click on pair a device in middle another pop to click pair
  7. This pair a device and other pop is appearing three time then pairing successful
  8. It should ask one time and should pair in one event only

This application and feature is working fine for IOS device , problem is in android application. android 12/13 both version I have checked

Formatted code sample or link to a repository

this.bleManager
        .connectToDevice(blueHaleDevice.id, {
          refreshGatt: 'OnConnected',
          autoConnect: Platform.OS === 'ios',
        })
        .then(async device => {
          this.timeStampWhenConnected = new Date();
          this.connectedDevice = device;
          this.deviceStatus.DeviceId = device.id;
          this.deviceStatus.DeviceName = device.name;
          this.deviceStatus.SerialNumber = this.hexStringToCreds(
            this.serialNumber,
          );
          await this.discoverServicesAndCharacterstics();
          this.messageStream.push(`Connected device - ${blueHaleDevice.id}`);
          this.writeCharacteristics(BluHaleCommand.Authenticate);
          if (!this.isConnectionRequired) {
            this.bindDisconnectEvent();
          }
          this.isConnectionRequired = true;
          if (!isPairing) {
            await this.startSyncDevice();
          }
        })
        .catch(err => {
          console.log(`Error in connectDevice: ${JSON.stringify(err)}`);
          if ([0, 2, 103, 3, 201, 200, 203, 102].includes(err.errorCode)) {
            if ([2].includes(err.errorCode)) {
              console.log('new instance and rety ******');
              this.getNewBleInstance();
              this.startScanner({...this.paramsForScanner});
            } else if ([103, 3, 201, 200, 203, 102].includes(err.errorCode)) {
              this.startScanner(this.paramsForScanner);
            }
            return;
          }
          this.callback(err);
        });

Relevant log output

In  log it is returning ID of device

Additional information

No response

dominik-czupryna-withintent commented 1 year ago

First of all, thank you for the extensive description of the problem. ❤️

The problem may be related to slightly different handling of multiple connectToDevice calls between iOS and Android. In the case of iOS, you can call the scenario connect device -> find services -> connect device -> find services, and nothing wrong will happen. In the case of Android, if you execute the same scenario, the device will be disconnected and then reconnected. In your error handling, I see that another connection is being made. I suspect this issue is causing an error loop.

I would like to ask if you could set up an error listener eg.

  const setupOnDeviceDisconnected = (deviceId: DeviceId) => {
    this.manager.onDeviceDisconnected(deviceId, disconnectedListener)
  }

  const disconnectedListener = (error: BleError | null, device: Device | null) => {
    if (error) {
      console.error('onDeviceDisconnected')
      console.error(JSON.stringify(error, null, 4))
    }
    if (device) {
      console.info(JSON.stringify(device, null, 4))
    }
  }

after the device connect and show logs from the iOS and Android to confirm or negate my guess

SatyendraM1990 commented 1 year ago

@dominik-czupryna-withintent Thanks for supporting Before pairing device I am checking with connection isConnectionRequired condition based on calling the below function

bindDisconnectEvent() { if (this.onDeviceDisconnected) { this.onDeviceDisconnected.remove(); } this.onDeviceDisconnected = this.bleManager.onDeviceDisconnected( this.connectedDevice?.id, (error, device) => { if (error) { this.callback(error); return; }

    if (this.timeStampWhenConnected && Platform.OS == 'android') {
      this.rescanifForgotTheBluetooth();
      return;
    }

    this.totalEventBytesExpected = 0;
    if (this.isConnectionRequired) {
      clearTimeout(this.prevTimeOut);
      this.prevTimeOut = setTimeout(async () => {
        await this.connectDevice();
      }, 15000);
    }

    this.messageStream.push(`Disconnected device - ${device.id}`);
    this.callback(null, device.id, 'disconnected', this.messageStream);
  },
);

}

dominik-czupryna-withintent commented 1 year ago

In 3.1.0 we fixed the bug mentioned above. Could you confirm whether the bug still occurs?

SatyendraM1990 commented 1 year ago

In 3.1.0 we fixed the bug mentioned above. Could you confirm whether the bug still occurs?

Hey @dominik-czupryna-withintent It works for me , but still one persist like earlier pairing pop-up appearing trice but now it is appearing twice.

nicks78 commented 1 year ago

I am using v3.1.0, I was wondering if there is a way to block the system popup tu appear because it is BLE so we do not need to pair the device to actually work. In my case my application must connect to a bike via BLE, on android when the system popup Pairing appear and I click on 'Pair' I lost the connection but I do not click and just wait the process continue (while the popup is still on the screen).

Is there any way to disabled the system popup or to control it ?

SatyendraM1990 commented 12 months ago

First time paring pop-up appearing and I click to pair, immediately another pop- up appearing I think that used to disconnect the paired device. Is that correct ? I f click first time pair pop up and wait do not click again pop-up pair that connect my device,

dominik-czupryna-withintent commented 12 months ago

@SatyendraM1990 I tried recreate your error in example but the code snippet you sent is undebuggable for me. Most of errors are handled by creating new instance (I'm guessing by the name of the function). I have no idea if you destroyed previous one (only one instance is allowed). The code snippet in the first comment generates an infinite loop of repeated queries in my example so can you provide bigger code snippet? E.g. when you get 203 error (DeviceAlreadyConnected) you destroying everything and starts over again whole process but you have connected device. Potentially, there may be a race condition and so on in this code. Additionally, you keep mentioning pop-ups but i can't see any pop-ups in your code.

Could you create a repo reproducing your error? Unfortunately, I can't help you with the current data 😞

dominik-czupryna-withintent commented 12 months ago

@nicks78 If you are asking about native bluetooth permissions, you won't be able to use bluetooth without them. You have to ask about them.

marvynorourkeTT commented 11 months ago

Hello,

I also have the problem on my project, I come to bring some information that may be interesting. I also reproduce the appearance of a double modal when pairing the module, the second modal is very similar to the first one except that there is on it the access key to connect to a protected device. When I've finished with the first modal and paired up my module, the second appears.

The problem seems to occur systematically when I connect my device with the package, whereas when I try to connect with the classic Android Bluetooth, I only get one modal displayed (the one with the access key).

I've tried adding the listener to see if the module disconnect but it doesn't seem to.

I'm using the latest version of the package: 3.1.0, I use a Samsung S20 FE / Huawei P20 Pro and I have Android 13 / Android 12.

dominik-czupryna-withintent commented 10 months ago

Could you show me screenshots of what exactly you mean?

Feeh03114 commented 8 months ago

desabilitar o pop-up

I'm having the same problem

marvynorourkeTT commented 7 months ago

Hello @dominik-czupryna-withintent ,

You can find a video where the problem occurs https://github.com/dotintent/react-native-ble-plx/assets/101122547/54aae289-3939-4ad1-86f0-4a6662713168

HoangThiKimPhung commented 5 months ago

I'm having the same problem with v3.1.2 and Pixel 6 Pro, S24 Ultra, S21 Ultra Does anyone have a solution to help me?

nvtc98 commented 2 months ago

I'm having the same issue on react-native-ble-plx 3.2.1

allxie commented 2 weeks ago

Same problem with react-native-ble-plx 3.2.1. Using an android BLU G53 running Android 13.