public ScanEventSource() { ScanResults = Observable.FromEvent<ScanResult>(h => OnDeviceDetected += h, h => OnDeviceDetected -= h); var appContext = Application.Context; var builder = new ScanSettings.Builder(); builder.SetReportDelay(0); builder.SetScanMode(ScanMode.LowLatency); var manager = (BluetoothManager)appContext.GetSystemService(Context.BluetoothService); var adapter = manager.Adapter; bluetoothLeScanner = adapter.BluetoothLeScanner; var simpleScanCallback = new SimpleScanCallback(result => { var payload = result.ScanRecord.GetBytes(); var majorId = payload[26]; if (payload[5] == 76 && majorId == Constants.MajorId) { var txPower = 255 - payload[29]; var minorId = (payload[27] << 8) + payload[28]; var deviceId = new DeviceIdentifier(new Guid(), majorId, minorId); var data = new ScanResult(deviceId, result.Rssi, txPower); OnDeviceDetected?.Invoke(data); } }); // taken from https://www.pubnub.com/blog/2015-04-15-build-android-beacon-ibeacon-detector/ , but not detecting our beacons //bluetoothLeScanner.StartScan(new List<ScanFilter> {CreateScanFilter()}, CreateScanSettings(), simpleScanCallback); bluetoothLeScanner.StartScan(simpleScanCallback); }
private ScanSettings CreateScanSettings() { ScanSettings.Builder mBuilder = new ScanSettings.Builder(); mBuilder.SetReportDelay(0); mBuilder.SetScanMode(ScanMode.LowPower); return mBuilder.Build(); }
private async void StartLeScan(Guid[] serviceUuids) { if (_isScanning) { Mvx.Trace("Adapter: Already scanning."); return; } _isScanning = true; // clear out the list _discoveredDevices = new List<IDevice>(); if (serviceUuids == null || !serviceUuids.Any()) { if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop) { Mvx.Trace("Adapter < 21: Starting a scan for devices."); //without filter _adapter.StartLeScan(this); } else { Mvx.Trace("Adapter >= 21: Starting a scan for devices."); if (_adapter.BluetoothLeScanner != null) { _adapter.BluetoothLeScanner.StartScan(_api21ScanCallback); } else { Mvx.Trace("Adapter >= 21: Scan failed. Bluetooth is probably off"); } } } else { if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop) { var uuids = serviceUuids.Select(u => UUID.FromString(u.ToString())).ToArray(); Mvx.Trace("Adapter < 21: Starting a scan for devices."); _adapter.StartLeScan(uuids, this); } else { Mvx.Trace("Adapter >=21: Starting a scan for devices with service ID {0}.", serviceUuids.First()); var scanFilters = new List<ScanFilter>(); foreach (var serviceUuid in serviceUuids) { var sfb = new ScanFilter.Builder(); sfb.SetServiceUuid(ParcelUuid.FromString(serviceUuid.ToString())); scanFilters.Add(sfb.Build()); } var ssb = new ScanSettings.Builder(); //ssb.SetCallbackType(ScanCallbackType.AllMatches); if (_adapter.BluetoothLeScanner != null) { _adapter.BluetoothLeScanner.StartScan(scanFilters, ssb.Build(), _api21ScanCallback); } else { Mvx.Trace("Adapter >= 21: Scan failed. Bluetooth is probably off"); } } } // in ScanTimeout seconds, stop the scan _cancellationTokenSource = new CancellationTokenSource(); try { await Task.Delay(ScanTimeout, _cancellationTokenSource.Token); Mvx.Trace("Adapter: Scan timeout has elapsed."); StopScan(); TryDisposeToken(); _isScanning = false; //important for this to be caled after _isScanning = false; ScanTimeoutElapsed(this, new EventArgs()); } catch (TaskCanceledException) { Mvx.Trace("Adapter: Scan was cancelled."); StopScan(); TryDisposeToken(); _isScanning = false; } }