public AndroidBluetoothDeviceProximityProbe()
        {
            _bluetoothScannerCallback = new AndroidBluetoothScannerCallback(this);

            _bluetoothScannerCallback.DeviceIdEncountered += (sender, bluetoothDeviceProximityDatum) =>
            {
                lock (EncounteredDeviceData)
                {
                    EncounteredDeviceData.Add(bluetoothDeviceProximityDatum);
                }
            };

            _bluetoothAdvertiserCallback = new AndroidBluetoothAdvertisingCallback(this);
        }
        protected sealed override IEnumerable <Datum> Poll(System.Threading.CancellationToken cancellationToken)
        {
            // restart the scan. on android this will cause the thread to sleep while data accumate. we need to sleep in order
            // to keep the cpu alive, as we're holding a wakelock for the poll. this is not allowed on ios, where we have a
            // limited amount of time to return from the poll. thus, on ios, we just start the scan and return immediately
            // without waiting for results to accumulate.

            try
            {
                SensusServiceHelper.Get().Logger.Log("Stopping scan.", LoggingLevel.Normal, GetType());
                StopScan();
            }
            catch (Exception ex)
            {
                SensusServiceHelper.Get().Logger.Log("Exception while stopping scan:  " + ex, LoggingLevel.Normal, GetType());
            }

            try
            {
                SensusServiceHelper.Get().Logger.Log("Starting scan.", LoggingLevel.Normal, GetType());
                StartScan();
            }
            catch (Exception ex)
            {
                SensusServiceHelper.Get().Logger.Log("Exception while starting scan:  " + ex, LoggingLevel.Normal, GetType());
            }

            // create a new list to return any data that have accumulated -- this only plays a role in android, where we
            // wait for data to accumulate while holding a wakelock. on ios, data are added directly via Probe.StoreDatumAsync
            // because we're not allowed to wait for data to accumulate (background time expiration).
            List <BluetoothDeviceProximityDatum> dataToReturn;

            lock (EncounteredDeviceData)
            {
                dataToReturn = EncounteredDeviceData.ToList();
                EncounteredDeviceData.Clear();
            }

            // if we have no new data, return a null datum to signal to the storage system that the poll ran successfully (null won't actually be stored).
            if (dataToReturn.Count == 0)
            {
                dataToReturn.Add(null);
            }

            return(dataToReturn);
        }