Estimote / react-native-proximity

React Native wrapper for Estimote Proximity SDK
Apache License 2.0
61 stars 38 forks source link

React native Estimote wrapper 0.4.1 crashes only on android #36

Open ohmadmin opened 5 years ago

ohmadmin commented 5 years ago

Hi, i am using estimote proximity beacons to detect entry and exit. i have location services turned on and bluetooth turned on. i am using react native bundle(https://github.com/Estimote/react-native-proximity) version 0.4.1. in IOS it starts up fine and i dont see any issues but in android as soon as i startup the app, location services permission is showing up and then the app freezes for few seconds and if you try to interact with the app it says app is not responding, so you can either wait or tap OK. if i tap wait, it is waiting for sometime and then working normally. if you tap ok the app is crashing. here is the bugsnag crash report. this is happening every single time i trigger the location permission logic. i came to this forum to understand if there is any known issues that i need to be aware of... Android Version 8.1 Api - 27

ANR · Application did not respond for at least 5000 ms
Raw
BluetoothLeScanner.java:212android.bluetooth.le.BluetoothLeScanner.startScan
BluetoothLeScanner.java:133android.bluetooth.le.BluetoothLeScanner.startScan
PostLollipopEstimoteScanner.kt:38com.estimote.scanning_plugin.packet_provider.scanner.PostLollipopEstimoteScanner$scan$1.subscribe
ObservableCreate.java:40io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual
Observable.java:10903io.reactivex.Observable.subscribe
ObservableFilter.java:30io.reactivex.internal.operators.observable.ObservableFilter.subscribeActual
Observable.java:10903io.reactivex.Observable.subscribe
ObservableMap.java:33io.reactivex.internal.operators.observable.ObservableMap.subscribeActual
Observable.java:10903io.reactivex.Observable.subscribe
ObservableMap.java:33io.reactivex.internal.operators.observable.ObservableMap.subscribeActual
Observable.java:10903io.reactivex.Observable.subscribe

ObservableFlatMap.java:162io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner

ObservableFlatMap.java:139io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext

ObservableFromArray.java:107io.reactivex.internal.operators.observable.ObservableFromArray$FromArrayDisposable.run

ObservableFromArray.java:36io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableFlatMap.java:55io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableMap.java:33io.reactivex.internal.operators.observable.ObservableMap.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableMap.java:33io.reactivex.internal.operators.observable.ObservableMap.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableFlatMap.java:162io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner

ObservableFlatMap.java:139io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext

ObservableFromArray.java:107io.reactivex.internal.operators.observable.ObservableFromArray$FromArrayDisposable.run

ObservableFromArray.java:36io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableFlatMap.java:55io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableFlatMap.java:162io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner

ObservableFlatMap.java:139io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext

ObservableFromArray.java:107io.reactivex.internal.operators.observable.ObservableFromArray$FromArrayDisposable.run

ObservableFromArray.java:36io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableFlatMap.java:55io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableGroupBy.java:48io.reactivex.internal.operators.observable.ObservableGroupBy.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableFlatMap.java:55io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableMap.java:33io.reactivex.internal.operators.observable.ObservableMap.subscribeActual

Observable.java:10903io.reactivex.Observable.subscribe

ObservableFlatMap.java:162io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.subscribeInner

ObservableFlatMap.java:139io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext

ObservableRefCount.java:139io.reactivex.internal.operators.observable.ObservableRefCount$ConnectionObserver.onNext

NotificationLite.java:246io.reactivex.internal.util.NotificationLite.accept

ObservableReplay.java:553io.reactivex.internal.operators.observable.ObservableReplay$UnboundedReplayBuffer.replay

ObservableReplay.java:404io.reactivex.internal.operators.observable.ObservableReplay$ReplayObserver.replay

ObservableReplay.java:371io.reactivex.internal.operators.observable.ObservableReplay$ReplayObserver.onNext

ObservableCreate.java:67io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onNext

PacketProviderWrapperServiceHelper.kt:41com.estimote.scanning_plugin.packet_provider.service.PacketProviderWrapperServiceHelper$createServiceConnection$1.onServiceConnected

LoadedApk.java:1660android.app.LoadedApk$ServiceDispatcher.doConnected

LoadedApk.java:1689android.app.LoadedApk$ServiceDispatcher$RunConnection.run

Handler.java:794android.os.Handler.handleCallback

Handler.java:99android.os.Handler.dispatchMessage

Looper.java:176android.os.Looper.loop

ActivityThread.java:6651android.app.ActivityThread.main

Method.java:-2java.lang.reflect.Method.invoke

RuntimeInit.java:547com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run

ZygoteInit.java:824com.android.internal.os.ZygoteInit.main
heypiotr commented 5 years ago

Does this only happen on some specific smartphone + Android version combo? Or are you able to reproduce it with different devices?

ohmadmin commented 5 years ago

we see this issue in every android phone we tested so far..

Phone | Version


Redmi6 | Android 8.1 | Redmi4 | Android 7.1.2 | Honor 9 Lite | Android 8.0.0 |   One Plus 6 | Android 9 | Red mi 5 | Android 7.1.2 |

heypiotr commented 5 years ago

Mhmm, I can't reproduce this on my Androids, so this could be something specific to your app. Mind sharing the bits of the code where you setup and start the proximity observer?

ohmadmin commented 5 years ago

I Exactly copied the example code: let me know if you need more details.. Set up code:


"use strict";
import * as RNEP from "@estimote/react-native-proximity";
import { beaconConfig } from '../../common/config/beacon';

const startProximityObserver = () => {

  // generate Estimote Cloud credentials for your app at:
  // https://cloud.estimote.com/#/apps/add/your-own-app

  const ESTIMOTE_APP_ID = beaconConfig.ESTIMOTE_APP_ID;
  const ESTIMOTE_APP_TOKEN = beaconConfig.ESTIMOTE_APP_TOKEN;

  // will trigger when the user is within ~ 5 m of any beacon with tag "lobby"
  // you can add tags to your beacons on https://cloud.estimote.com, in Beacon Settings
  const zone1 = new RNEP.ProximityZone(5, "TV");
  zone1.onEnterAction = context => {
    // context properties are:
    // - attachments: all the key-value attachments assigned in Estimote Cloud to the beacon that triggered the action
    // - tag: the tag used when defining the zone, repeated here for convenience
    // - deviceIdentifier: Estimote-specific device identifier of the beacon that triggered the action
    console.log("zone1 onEnter", context);
  };
  zone1.onExitAction = context => {
    console.log("zone1 onExit", context);
  };
  zone1.onChangeAction = contexts => {
    // onChange event gives you granular data about which exact beacons are in range
    //
    // imagine there are 2 beacons tagged "lobby", to help cover the entire lobby area; here's an example sequence of events:
    //
    // 1. when you enter the range of the 1st one, you'll get:
    // lobby onEnter
    // lobby onChange with array [beacon1's context]
    //
    // 2. when you enter the range of the 2nd one, and are still in range of the 1st one:
    // lobby onChange with array [beacon1's context, beacon2's context]
    //
    // 3. when you exit the range of the 1st one, but are still in range of the 2nd one:
    // lobby onChange with array [beacon2's context]
    //
    // 4. when you finally exit the range of the 2nd one:
    // lobby onChange with empty array []
    // lobby onExit
    console.log("zone1 onChange", contexts);
  };

  const zone2 = new RNEP.ProximityZone(5, "conf-room");
  zone2.onEnterAction = context => {
    console.log("zone2 onEnter", context);
  };
  zone2.onExitAction = context => {
    console.log("zone2 onExit", context);
  };
  zone2.onChangeAction = contexts => {
    console.log("zone2 onChange", contexts);
  };

  // detecting proximity to Bluetooth beacons gives you information about the user's location, and so
  // on both iOS and Android it's required to ask the user for permission to do that
  //
  // - on iOS, the user can choose between "never", "only when using the app" and "always" (background)
  //   - however, background support also requires that you enable the "Uses Bluetooth LE accessories"
  //     Background Mode for your app
  //   - you can do that in Xcode project settings, on the Capabilities tab
  //   - you might also need to explain/defend your app's background usage during the App Store review
  //
  // - on Android, it'll be a simple "yes/no" popup, which is equivalent to "never" and "always"
  //   - however, to have it work in the background, you're also required to show a notification, so
  //     that the user knows that the app keeps running/detecting beacons even if they close it
  //   - see the `config` section below for how to enable/configure such notification
  //
  // see also: "Location permission" and "Background support" sections in the README
  RNEP.locationPermission.request().then(
    permission => {
      // `permission` will be one of RNEP.locationPermission.DENIED, .ALWAYS, or .WHEN_IN_USE
      console.log(`location permission: ${permission}`);

      if (permission !== RNEP.locationPermission.DENIED) {
        const credentials = new RNEP.CloudCredentials(
          ESTIMOTE_APP_ID,
          ESTIMOTE_APP_TOKEN
        );

        const config = {
          // modern versions of Android require a notification informing the user that the app is active in the background
          // if you don't need proximity observation to work in the background, you can omit the entire `notification` config
          //
          // see also: "Background support" section in the README
          notification: {
            title: "Exploration mode is on",
            text: "We'll notify you when you're next to something interesting.",
            //icon: 'my_drawable', // if omitted, will default to the app icon (i.e., mipmap/ic_launcher)

            // in apps targeting Android API 26, notifications must specify a channel
            // https://developer.android.com/guide/topics/ui/notifiers/notifications#ManageChannels
            channel: {
              id: "exploration-mode",
              name: "Exploration Mode"
            }
          }
        };

        RNEP.proximityObserver.initialize(credentials, config);
        RNEP.proximityObserver.startObservingZones([zone1, zone2]);
      }
    },
    error => {
      console.error("Error when trying to obtain location permission", error);
    }
  );

};

const stopProximityObserver = () => { RNEP.proximityObserver.stopObservingZones(); };

export {startProximityObserver, stopProximityObserver};

Trigger/Start Code:


import { startProximityObserver } from "../components/beacon/beacon";

.
.
componentDidMount() {
  .
startProximityObserver();
.
    }
ohmadmin commented 5 years ago

also one more thing... if i comment out RNEP.proximityObserver.startObservingZones([zone1, zone2]); then the app is not Freezing but at the same time there is no notification too.

heypiotr commented 5 years ago

And what Android device and version is that?

Can you try some other app that uses Bluetooth Low Energy scanning? For example, nRF Connect. Just trying to rule out some problem with the Bluetooth stack in that device.

ohmadmin commented 5 years ago

@heypiotr here is the device/version details. Xiaomi Redmi 4, Android 7.1.2

nRF connect is now installed on the same device. do you have a flow that you want us to try. it did not crash so far..

gurzoni commented 5 years ago

I'm having the same issue. The example app crashes after start.

ohmadmin commented 5 years ago

@gurzoni can you pls add os version, device type?

tws9797 commented 5 years ago

Is this issue still live? I have encounter the similar problem as well. I couldn't run the app on an my S9 device. The app just keep crashing.

heypiotr commented 5 years ago

I couldn't reproduce it so far. I think we have an S9 somewhere in the office, so if you experience this problem on S9, that's actually great news for me (: I'll try to test it later this week.

tws9797 commented 5 years ago

It's ok I have solved the problem by adding

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

to my manifest.

heypiotr commented 5 years ago

Oh, ok, that was a different problem then. Bad new for me, since I guess this means S9 might not actually be affected by the ANR crash ^_^