Example #1
0
        void StartLocationUpdates()
        {
            if (locationUpdatesStarted)
            {
                return;
            }
            else
            {
                locationUpdatesStarted = true;
            }

            if (indoorManager != null)
            {
                Log.Debug("app", "indoorManager already initialized, starting position updates");

                indoorManager.StartPositioning();

                return;
            }

            // starting with Android 8.0, the most reliable way to keep
            // Bluetooth scanning active when the user leaves the app is through
            // a foreground service, and for that to work we're required to show
            // a notification that informs the user about the activity
            //
            // read more about it on:
            // https://developer.android.com/guide/components/services.html#Foreground

            var channelId = "indoor_location";

            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                // Android 8.0 and up require a channel for the notifications
                var channel             = new NotificationChannel(channelId, "Bluetooth activity", NotificationImportance.Low);
                var notificationManager = this.GetSystemService(Context.NotificationService) as NotificationManager;
                notificationManager.CreateNotificationChannel(channel);
            }
            var notification = new NotificationCompat.Builder(this, channelId)
                               .SetSmallIcon(global::Android.Resource.Drawable.IcDialogInfo)
                               .SetContentTitle("Indoor Location")
                               .SetContentText("Indoor Location updates are running")
                               .Build();

            var creds = new EstimoteCloudCredentials(APP_ID, APP_TOKEN);

            var getLocationHandler = new GetLocationHandler();

            getLocationHandler.GetLocationSuccess += (location) =>
            {
                Log.Debug("app", $"Successfully fetched location from Estimote Cloud: {location}");
                Log.Debug("app", "Initializing indoorManager and starting position updates");

                locationView.SetLocation(location);

                indoorManager = new IndoorLocationManagerBuilder(this, location, creds)

                                // see the longer comment above about the foreground service and
                                // the notification
                                //
                                // if you only intend to use beacons while the app is open, you
                                // can safely remove this line
                                .WithScannerInForegroundService(notification)

                                .Build();

                indoorManager.SetOnPositionUpdateListener(new PositionUpdateHandler(locationView));
                indoorManager.StartPositioning();
            };
            getLocationHandler.GetLocationFailure += (error) =>
            {
                Log.Error("app", $"Failed to fetch the location from Estimote Cloud: {error}");
            };

            Log.Debug("app", $"Fetching location '{LOCATION_ID}' from Estimote Cloud...");
            new IndoorCloudManagerFactory()
            .Create(this, creds)
            .GetLocation(LOCATION_ID, getLocationHandler);
        }
        protected override async Task StartListeningAsync()
        {
            await base.StartListeningAsync();

            Notification notification = (SensusContext.Current.Notifier as AndroidNotifier).CreateNotificationBuilder(AndroidNotifier.SensusNotificationChannel.ForegroundService)
                                        .SetSmallIcon(Resource.Drawable.notification_icon_background)
                                        .SetContentTitle("Beacon Scan")
                                        .SetContentText("Scanning...")
                                        .SetOngoing(true)
                                        .Build();

            if (Beacons.Count > 0)
            {
                _proximityObserver = new ProximityObserverBuilder(Application.Context, new Estimote.Android.Proximity.EstimoteCloudCredentials(EstimoteCloudAppId, EstimoteCloudAppToken))
                                     .WithBalancedPowerMode()
                                     .WithScannerInForegroundService(notification)
                                     .OnError(new ProximityErrorHandler())
                                     .Build();

                List <IProximityZone> zones = new List <IProximityZone>();

                foreach (EstimoteBeacon beacon in Beacons)
                {
                    IProximityZone zone = new ProximityZoneBuilder()
                                          .ForTag(beacon.Tag)
                                          .InCustomRange(beacon.ProximityMeters)
                                          .OnEnter(new ProximityHandler(this, beacon, EstimoteBeaconProximityEvent.Entered))
                                          .OnExit(new ProximityHandler(this, beacon, EstimoteBeaconProximityEvent.Exited))
                                          .Build();

                    zones.Add(zone);
                }

                _proximityObservationHandler = _proximityObserver.StartObserving(zones);
            }

            if (Location != null)
            {
                Estimote.Android.Indoor.EstimoteCloudCredentials credentials = new Estimote.Android.Indoor.EstimoteCloudCredentials(EstimoteCloudAppId, EstimoteCloudAppToken);

                IIndoorCloudManager indoorCloudManager           = new IndoorCloudManagerFactory().Create(Application.Context, credentials);
                AndroidEstimoteIndoorCloudCallback cloudCallback = new AndroidEstimoteIndoorCloudCallback();
                indoorCloudManager.GetLocation(Location.Identifier, cloudCallback);
                Estimote.Android.Indoor.Location cloudLocation = await cloudCallback.GetValueAsync();

                _indoorLocationManager = new IndoorLocationManagerBuilder(Application.Context, cloudLocation, credentials)
                                         .WithPositionUpdateInterval(IndoorLocationUpdateIntervalMS)
                                         .WithOnErrorAction(new IndoorErrorHandler())
                                         .WithScannerInForegroundService(notification)
                                         .Build();

                AndroidEstimoteIndoorPositionUpdateListener indoorPositionUpdateListener = new AndroidEstimoteIndoorPositionUpdateListener();
                indoorPositionUpdateListener.UpdatedPositionAsync += async(estimoteLocation) =>
                {
                    EstimoteIndoorLocationDatum datum = null;

                    if (estimoteLocation != null)
                    {
                        datum = new EstimoteIndoorLocationDatum(DateTimeOffset.UtcNow, estimoteLocation.GetX(), estimoteLocation.GetY(), estimoteLocation.Orientation, EstimoteIndoorLocationAccuracy.Unknown, Location.Name, Location.Identifier, cloudLocation, estimoteLocation);
                    }

                    await StoreDatumAsync(datum);
                };

                _indoorLocationManager.SetOnPositionUpdateListener(indoorPositionUpdateListener);
                _indoorLocationManager.StartPositioning();
            }
        }