Driversnote-Dev / react-native-kontaktio

React Native (iOS and Android) library for Kontakt.io beacons (and all other beacons)
MIT License
112 stars 48 forks source link

Not working listeners #108

Open ssshopyak opened 1 year ago

ssshopyak commented 1 year ago
const Ibeacon = () => {
const linkvalue = items.location.identifiers.map(({ value }) => value)
const [loaded, setLoaded] = useState(true)

const requestLocationPermission = async () => {
  try {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
      {
        title: 'Location Permission',
        message:
          'This example app needs to access your location in order to use bluetooth beacons.',
        buttonNeutral: 'Ask Me Later',
        buttonNegative: 'Cancel',
        buttonPositive: 'OK',
      }
    );
    if (granted === PermissionsAndroid.RESULTS.GRANTED) {
      return true;
    } else {
      // permission denied
      return false;
    }
  } catch (err) {
    console.warn(err);
    return false;
  }
};

const beaconSetup = async () => {
  if (isAndroid) {
    // Android
    const granted = await requestLocationPermission()
    if (granted) {
      await connect()
      await startScanning()
      console.log('finding')
    } else {
      Alert.alert(
        'Permission error',
        'Location permission not granted. Cannot scan for beacons',
        [{ text: 'OK', onPress: () => console.log('OK Pressed') }],
        { cancelable: false },
      )
    }
  } else {
    // iOS
    await init()
    await startRangingBeaconsInRegion()
  }

  // Add beacon listener
  if (isAndroid) {
    DeviceEventEmitter.addListener(
      'beaconsDidUpdate',
      ({ beacons, region }) => {
        console.log('beaconsDidUpdate', beacons, region)
        //setBeacons(beacons)
        console.log(beacons[0].uuid)
        console.log('ANDROID DISCOVERED BEACON')
        if (linkvalue.includes(beacons[0].uuid)) {
          console.log('true')
          if (items.state === 'available' && loaded) {
            api
              .post('events/subtask_started', {
                id: items.id,
              })
              .finally(() => {
                setLoaded(false)
                setIdentVisible(false)
                setBeaconVisible(false)
                stopScanning()
                getSubtask()
              })
          }
        } else {
          onToggleSnackBar('Beacon UUID неправильный')
        }
      },
    )
  } else {
    kontaktEmitter.addListener('didRangeBeacons', ({ beacons, region }) => {
      console.log('didRangeBeacons', beacons)
      console.log('IOS DISCOVERED BEACON')
      if (linkvalue.includes(beacons[0].uuid)) {
        console.log('true')
        if (items.state === 'available' && loaded) {
          api
            .post('events/subtask_started', {
              id: items.id,
            })
            .finally(() => {
              setLoaded(false)
              stopRangingBeaconsInRegion()
              setIdentVisible(false)
              setBeaconVisible(false)
              getSubtask()
            })
        }
      } else {
        onToggleSnackBar('Beacon UUID неправильный')
      }
    })
  }
}
useEffect(() => {
  Promise.resolve().then(beaconSetup);

return () => {
  // remove event listeners
  if (isAndroid) {
    kontaktEmitter.removeAllListeners('beaconsDidUpdate');
  } else {
    kontaktEmitter.removeAllListeners('didDiscoverDevices');
    kontaktEmitter.removeAllListeners('didRangeBeacons');
  }
};
}, [])

Its my code when it was on 3.1.0 version all works only on 7 android, but not on 12. Now after update to 4.0.0 its not working on 7 and 12 all permisions is allowed. It`s very important for me please may someone help me? also RN: 0.69.5

JonasWho commented 1 year ago

Can you post your manifest file as well?

ssshopyak commented 1 year ago

not actually. switched to react-native-beacon-manager

yhanssens commented 1 year ago

Got the same problem. Here's my manifest.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="my.projects.package">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="com.google.android.gms.permission.AD_ID"/>

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
        android:screenOrientation="portrait"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <service android:name="com.kontakt.sdk.android.ble.service.ProximityService" android:exported="false"/>
    </application>
</manifest>
JonasWho commented 1 year ago

My best guess is that you need to add these permissions (or some of them):

    <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
yhanssens commented 1 year ago

I have tried that before, without result unfortunately. But I'll give it another go, thanks!

gladiuscode commented 1 year ago

Hi all! First of all, thank you for this amazing library, on iOS it is working smoothly.

I've got the same issues on android tho, scanning listeners are not working. The only strange error that I can see popping up in my Logcat is the following one:

unable to parse scan record: [30, 3, 18, -94, 77, 46, -2, 20, 72, -114, -109, -46, 23, 60, -3, 2, 48, -128, -53, -38, -100, -92, -122, -100, 82, 28, 64, 0, 0, 0, 0]
2022-12-07 11:43:52.406  5358-6644  ScanRecord              pid-5358                             E  unable to parse scan record: [30, 3, 18, -94, 77, 46, -2, 20, 72, -114, -109, -46, 23, 60, -3, 2, 48, -128, -53, -38, -100, -92, -122, -100, 82, 28, 64, 0, 0, 0, 0]
2022-12-07 11:43:52.406  5358-6644  ScanRecord              pid-5358                             E  unable to parse scan record: [30, 3, 18, -94, 77, 46, -2, 20, 72, -114, -109, -46, 23, 60, -3, 2, 48, -128, -53, -38, -100, -92, -122, -100, 82, 28, 64, 0, 0, 0, 0]
2022-12-07 11:43:52.406  7119-7197  BluetoothServiceJni     pid-7119                             E  An exception was thrown by callback 'btgattc_scan_result_cb'.
2022-12-07 11:43:52.407  7119-7197  BluetoothServiceJni     pid-7119                             E  java.lang.ArrayIndexOutOfBoundsException: length=31; index=31
                                                                                                     at com.android.bluetooth.gatt.GattService.parseUuids(GattService.java:3746)
                                                                                                     at com.android.bluetooth.gatt.GattService.onScanResult(GattService.java:1137)

Information:

  1. react-native version 0.67.5;
  2. react-native-kontaktio version latest;

Targets configuration:

minSdkVersion = 23
compileSdkVersion = 33
targetSdkVersion = 33

Android Manifest:

  1. Proximity service added inside <application tag: <service android:name="com.kontakt.sdk.android.ble.service.ProximityService" android:exported="false"/>
  2. Permissions:

    <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30"/>
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

I've also followed Kontaktio quick setup guide, so I've added their sdk as a dependency: implementation "io.kontakt.mvn:sdk:7.0.12.1"

I'm using Beacons Simulator app to emulate a bunch of beacons (IBeacons) and it is installed in another device, different from the one i'm developing on.

I've tried in my App.tsx, after all permissions requests granted through react-native-permissions, with the following setup:

useEffect(() => {
    const testBeacons = async () => {
      try {
        await Kontakt.connect();
        await Kontakt.startScanning();
        DeviceEventEmitter.addListener('beaconInitStatus', params => console.log('[Beacons] [initStatus] - params: ', params));
        DeviceEventEmitter.addListener('scanStatus', params => console.log('[Beacons] [scanStatus] - params: ', params));
        DeviceEventEmitter.addListener('beaconDidAppear', params => console.log('[Beacons] [beaconDidAppear] - params: ', params));
        DeviceEventEmitter.addListener('beaconsDidAppear', params => console.log('[Beacons] [beaconsDidUpdate] - params: ', params));
      } catch (error) {
        console.log('[Beacons] [testBeacons] - error: ', error);
      }
    }
    testBeacons();
  }, []);

Let me know if you need anything else, i'll gladly help, unfortunately my knowledge with native side is limited.

Thanks!

Malin88 commented 1 year ago

Similar issue here. I have created demo from README minimal setup instructions and no listeners works. I also used the code from gladiuscode nad here is the result:

 LOG  [Beacons] [scanStatus] - params:  {"status": "START"}
 LOG  [Beacons] [scanStatus] - params:  {"status": "ERROR"}
 LOG  [Beacons] [scanStatus] - params:  {"status": "STOP"}

EDIT: end this is errror: com.kontakt.sdk.android.ble.exception.ScanError@f9eb529

Android version 13

claudiumatei commented 1 year ago

For Android 12+ you must ask following permissions in order to make it work (if compileSDKVersion is 31 or higher): Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.ACCESS_FINE_LOCATION

After asking these permissions things are working as expected on latest version of the library

nickoliveira23 commented 1 year ago

It worked for me. For Android 12+ you just need to add to you manifest the permissions like that:

`

`

Beyond that, in your code, I recommend you to handle the BLUETOOTH_SCAN and BLUETOOTH_CONNECT, they're only for SDK 31+ so you only ask for these permissions after check that the current SDK is >= 31 (You can use Platform.Version to do it). If the current SDK you are workin on is less than 31, you keep asking only for ACCESS_FINE_LOCATION. (Remember to check in your device if both Bluetooth and Location are enabled).