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 in Android Version 12 and Above #121

Open dev-abhinavsinghHP opened 10 months ago

dev-abhinavsinghHP commented 10 months ago

it works fine in Android version 11 , for 12 and 13 Beacons did not register beacons are not shown in Range Anyone Please help me with this issue

I use latest Package

KaiValar commented 6 months ago

You need to ask for BLUETOOTH_SCAN and BLUETOOTH_CONNECT permissions too for that newer versions.

jkaos92 commented 2 months ago

@KaiValar even with BLUETOOTH_SCAN and BLUETOOTH_CONNECT it is not working in Android 14. There is any other advice?

KaiValar commented 2 months ago

@KaiValar even with BLUETOOTH_SCAN and BLUETOOTH_CONNECT it is not working in Android 14. There is any other advice?

Have you a repo to check it out? I have an app running it with this lib on Android 14, but I cannot share the code beacuse isn't really mine, I'm only an employee ^^'

You need to add permissions and the service from Kontakt SDK on Manifest, add the SDK on your build.gradle dependencies (I used 7.1.8 version) and initialize it on MainApplication.java, then you can ask for the permissions to user and finally use the lib. On iOS is more painful, but atm on Android works fine.

jkaos92 commented 2 months ago

@KaiValar thanks for the fast reply. Can't post the whole repo (for the same reason), we followed the guide. It works on iOS for us, but it doesn't work on Android 14 (it works on android 12 tho).

Our Manifest:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<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"/>

and this:

<service android:name="com.kontakt.sdk.android.ble.service.ProximityService" android:exported="false"/>

this in the build.gradle:

implementation("io.kontakt.mvn:sdk:7.1.8")`

And this is the listener that doesn't work on Android 14 (but works on Android 12).

kontaktEmitter.addListener('beaconsDidUpdate', async (res)=> {
      console.log('beaconsDidUpdate', res);
      //basically "res" is undefined on Android 14
      //it returns the correct array in Android 12 (with beacons and regions) 
  });

The initialize onCreate in MainApplication.java is not needed for us because we don't use the API Key (or at least, it doesn't work without an API key).

Also we followed everything in this guide: https://github.com/Driversnote-Dev/react-native-kontaktio/tree/master

Any recommendation is appreciated. Thanks in advance!

KaiValar commented 2 months ago

Weird, at least I remember you have more or less the same than us. The unique differences I see are: we initialize the SDK in the onCreate just keeping a empty string ("") as a param and our function handler for the event insn't asyncronous, we call async functions inside the handler:

        kontaktEmitter.addListener("beaconDidAppear", ({ beacon, region }) => {
          handlerFunction(beacon, region); // We do our stuff in it
        });

Maybe with the code front of me I can give you some extra info. Tomorrow, I'll try to got some time to see our code for got sure.

jkaos92 commented 2 months ago

@KaiValar After many many attempts, we found the solution on a comment of another bluetooth library with similar issue here, where Android 12 worked fine, on Android 14 didn't.

<uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:remove="android:usesPermissionFlags" />

Basically this saved the day!


The problem was that by adding this (mandatory for Android 12+, api 31+):

<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

The merged Manifest resulted in this:

 <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation"/>

If android:usesPermissionFlags=neverForLocation is added in your android manifest, some BLE beacons are filtered out from the scan results. The Android documentation says:

Include "neverForLocation" only if you can strongly assert that your app never derives physical location from Bluetooth scan results. If you include neverForLocation in your android:usesPermissionFlags, some BLE beacons are filtered from the scan results.

Basically the automatically added "neverForLocation" was filtering out some BLE beacons...

KaiValar commented 2 months ago

Glad to read you solve that :D

Yeah, that change was added because if we detect a beacon, we can know you are on the same location of the beacon, so we can know where are you through the Bluetooth :P

KaiValar commented 2 months ago

Btw, @jkaos92 if you are thinking to use this in background, I used a Foreground Service ;)

jkaos92 commented 2 months ago

@KaiValar Tomorrow will check if it works in BG. Will keep you updated regarding the FG Service, but thanks for the advice!