private async Task <List <BluetoothDeviceProximityDatum> > CreateBluetoothData(CancellationToken cancellationToken) { List <BluetoothDeviceProximityDatum> bluetoothDeviceProximityData = new List <BluetoothDeviceProximityDatum>(); // copy list of peripherals to read. note that the same device may be reported more than once. read each once. List <AndroidBluetoothDevice> le = _bluetoothScannerCallback.GetDiscoveredDevices(); List <AndroidBluetoothDevice> classic = _bluetoothBroadcastReceiver.GetDiscoveredDevices(); List <IGrouping <string, AndroidBluetoothDevice> > scanResults = le.Union(classic) .GroupBy(scanResult => scanResult.Device.Address) .ToList(); ReadAttemptCount += scanResults.Count; // read characteristic from each peripheral foreach (IGrouping <string, AndroidBluetoothDevice> deviceGroup in scanResults) { if (cancellationToken.IsCancellationRequested) { break; } AndroidBluetoothClientGattCallback readCallback = null; try { readCallback = new AndroidBluetoothClientGattCallback(_deviceIdService, _deviceIdCharacteristic); BluetoothGatt gatt = deviceGroup.First().Device.ConnectGatt(Application.Context, false, readCallback); string deviceId = await readCallback.ReadCharacteristicValueAsync(cancellationToken); if (DiscoverAll || deviceId != null) { DateTimeOffset timestamp = deviceGroup.Min(x => x.Timestamp); string address = deviceGroup.Key; string name = deviceGroup.FirstOrDefault(x => x.Device.Name != null)?.Device.Name; int rssi = deviceGroup.Min(x => x.Rssi); bool paired = deviceGroup.Any(x => x.Device.BondState != Bond.None); bluetoothDeviceProximityData.Add(new BluetoothDeviceProximityDatum(timestamp, deviceId, address, name, rssi, paired, deviceId != null)); ReadSuccessCount++; } } catch (Exception ex) { SensusServiceHelper.Get().Logger.Log("Exception while reading peripheral: " + ex, LoggingLevel.Normal, GetType()); } finally { readCallback?.DisconnectPeripheral(); } } return(bluetoothDeviceProximityData); }
public async Task <List <Tuple <string, DateTimeOffset> > > ReadPeripheralCharacteristicValuesAsync(CancellationToken cancellationToken) { List <Tuple <string, DateTimeOffset> > characteristicValueTimestamps = new List <Tuple <string, DateTimeOffset> >(); // copy list of peripherals to read. note that the same device may be reported more than once. read each once. List <ScanResult> scanResults; lock (_scanResults) { scanResults = _scanResults.GroupBy(scanResult => scanResult.Device.Address).Select(group => group.First()).ToList(); } _probe.ReadAttemptCount += scanResults.Count; // read characteristic from each peripheral foreach (ScanResult scanResult in scanResults) { if (cancellationToken.IsCancellationRequested) { break; } AndroidBluetoothClientGattCallback readCallback = null; try { readCallback = new AndroidBluetoothClientGattCallback(_service, _characteristic); scanResult.Device.ConnectGatt(global::Android.App.Application.Context, false, readCallback); string characteristicValue = await readCallback.ReadCharacteristicValueAsync(cancellationToken); if (characteristicValue != null) { long msSinceEpoch = Java.Lang.JavaSystem.CurrentTimeMillis() - SystemClock.ElapsedRealtime() + scanResult.TimestampNanos / 1000000; DateTimeOffset encounterTimestamp = new DateTimeOffset(1970, 1, 1, 0, 0, 0, new TimeSpan()).AddMilliseconds(msSinceEpoch); characteristicValueTimestamps.Add(new Tuple <string, DateTimeOffset>(characteristicValue, encounterTimestamp)); _probe.ReadSuccessCount++; } } catch (Exception ex) { SensusServiceHelper.Get().Logger.Log("Exception while reading peripheral: " + ex, LoggingLevel.Normal, GetType()); } finally { readCallback?.DisconnectPeripheral(); } } return(characteristicValueTimestamps); }