예제 #1
0
        private void StartScanningNew(Guid[] serviceUuids, ManufacturerData[] manufacturerDataFilters)
        {
            var hasFilter = serviceUuids?.Any() ?? false;
            List <ScanFilter> scanFilters = null;

            if (hasFilter)
            {
                scanFilters = new List <ScanFilter>();
                foreach (var serviceUuid in serviceUuids)
                {
                    var sfb = new ScanFilter.Builder();
                    sfb.SetServiceUuid(ParcelUuid.FromString(serviceUuid.ToString()));
                    scanFilters.Add(sfb.Build());
                }
                foreach (var manufacturerData in manufacturerDataFilters)
                {
                    var sfb = new ScanFilter.Builder();
                    sfb.SetManufacturerData(manufacturerData.Id, manufacturerData.Data);
                    scanFilters.Add(sfb.Build());
                }
            }

            var ssb = new ScanSettings.Builder();

            ssb.SetScanMode(ScanMode.ToNative());
            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                // enable Bluetooth 5 Advertisement Extensions on Android 8.0 and above
                ssb.SetLegacy(false);
            }
            //ssb.SetCallbackType(ScanCallbackType.AllMatches);

            if (_bluetoothAdapter.BluetoothLeScanner != null)
            {
                Trace.Message($"Adapter >=21: Starting a scan for devices. ScanMode: {ScanMode}");
                if (hasFilter)
                {
                    Trace.Message($"ScanFilters: {string.Join(", ", serviceUuids)}");
                }
                _bluetoothAdapter.BluetoothLeScanner.StartScan(scanFilters, ssb.Build(), _api21ScanCallback);
            }
            else
            {
                Trace.Message("Adapter >= 21: Scan failed. Bluetooth is probably off");
            }
        }
예제 #2
0
        public async void StartScanningForDevices(int timeOutSeconds = 10, string serviceUuid = null)
        {
            Console.WriteLine("Adapter: Starting a scan for devices.");

            // clear out the list
            this._discoveredDevices = new List <IDevice> ();

            // start scanning
            this._isScanning = true;

            var scanFilterBuilder = new ScanFilter.Builder();

            if (!string.IsNullOrWhiteSpace(serviceUuid))
            {
                scanFilterBuilder.SetServiceUuid(ParcelUuid.FromString(serviceUuid));
            }
            var filter = scanFilterBuilder.Build();

            var filterList = new List <ScanFilter>()
            {
                filter
            };

            var scanSettingBuilder = new ScanSettings.Builder();

            scanSettingBuilder.SetScanMode(ScanMode.Balanced);

            var scanSettings = scanSettingBuilder.Build();

            this._adapter.BluetoothLeScanner.StartScan(filterList, scanSettings, _scanCallback);

            //this._adapter.StartLeScan (this);

            // in 10 seconds, stop the scan
            await Task.Delay(TimeSpan.FromSeconds(timeOutSeconds));

            // if we're still scanning
            if (this._isScanning)
            {
                Console.WriteLine("BluetoothLEManager: Scan timeout has elapsed.");
                // Use the method, because it also updates the _isScanning portion.
                StopScanningForDevices();
                this.ScanTimeoutElapsed(this, new EventArgs());
            }
        }
예제 #3
0
        public bool StartScan(int timeoutMs, bool filtered)
        {
            try
            {
                if (!BleEnabled)
                {
                    BLE_ERR("can't start scan, ble not enabled");
                    return(false);
                }

                if (!Init())
                {
                    return(false);
                }

                _Timeout = new Timer((obj) =>
                {
                    StopScan();
                }, null, timeoutMs, Timeout.Infinite);

                BLE("start scan");

                _Devices.Clear();
                if (filtered)
                {
                    var filter   = new ScanFilter.Builder().SetServiceUuid(ParcelUuid.FromString(BleConstants.BLE_SERVER_SERVICE_UUID)).Build();
                    var settings = new ScanSettings.Builder().SetScanMode(Android.Bluetooth.LE.ScanMode.LowLatency).Build();
                    _CentralManager.Adapter.BluetoothLeScanner.StartScan(new List <ScanFilter> {
                        filter
                    }, settings, this);
                }
                else
                {
                    _CentralManager.Adapter.BluetoothLeScanner.StartScan(this);
                }

                return(true);
            }
            catch (Exception ex)
            {
                BLE_ERR("start scan error", ex);
                return(false);
            }
        }
예제 #4
0
        public async Task  BeginScanningForDevices()
        {
            this._discoveredDevices = new List <BluetoothDevice>();

            this._isScanning = true;
            ScanSettings settings = new ScanSettings.Builder().SetScanMode(Android.Bluetooth.LE.ScanMode.LowPower).SetCallbackType(ScanCallbackType.AllMatches).Build();
            ScanFilter   filter   = new ScanFilter.Builder().SetDeviceAddress("63:8A:87:FE:F3:76").Build();
            //ScanFilter filter2 = new ScanFilter.Builder().SetServiceUuid(ParcelUuid.fromString(serviceUUIDs[i].toStri‌​ng())).build();
            List <ScanFilter> filters = new List <ScanFilter>();

            filters.Add(filter);
            this._scanner.StartScan(filters, settings, new BluetoothScanCallback());

            await Task.Delay(10000);

            if (this._isScanning)
            {
                //this._scanner.StopScan(new PendingIntent());
            }
        }
예제 #5
0
        protected virtual void StartNewScanner(ScanConfig config)
        {
            this.newCallback = new LollipopScanCallback(args => this.Scanned?.Invoke(this, args));
            var scanMode      = this.ToNative(config.ScanType);
            var filterBuilder = new ScanFilter.Builder();

            if (config.ServiceUuid != null)
            {
                filterBuilder.SetServiceUuid(config.ServiceUuid.Value.ToParcelUuid());
            }

            //new ScanFilter.Builder().SetDeviceAddress().Set
            this.manager.Adapter.BluetoothLeScanner.StartScan(
                new [] { filterBuilder.Build() },
                new ScanSettings
                .Builder()
                .SetScanMode(scanMode)
                .Build(),
                this.newCallback
                );
        }
예제 #6
0
        void UpdateScanFilters()
        {
            if (_scanObservers.Any(obs => obs.Services == null))
            {
                _scanFilters = null;
            }
            else
            {
                var builder = new ScanFilter.Builder();
                _scanFilters = _scanObservers
                               .Aggregate(new HashSet <ServiceUuid>(), (acc, elem) => { acc.UnionWith(elem.Services); return(acc); })
                               .Select(svc =>
                {
                    builder.SetServiceUuid(svc.Uuid.ToParcelUuid());
                    return(builder.Build());
                })
                               .ToArray();
            }

            Reschedule();
        }
        void IAdvertiseAndDiscoverBluetoothDevice.Discover()
        {
            try
            {
                Analytics.TrackEvent(Build.Model + " Discover method called.");

                List <ScanFilter> filters = new List <ScanFilter>();

                ScanFilter filter = new ScanFilter.Builder()
                                    .SetServiceUuid(new ParcelUuid(MY_UUID))
                                    .Build();
                filters.Add(filter);

                //ScanSettings settings = new ScanSettings.Builder()
                //        .SetScanMode(Android.Bluetooth.LE.ScanMode.LowLatency)
                //        .Build();

                ScanSettings.Builder builder = new ScanSettings.Builder();
                builder.SetScanMode(Android.Bluetooth.LE.ScanMode.LowLatency);

                if (Build.VERSION.SdkInt >= BuildVersionCodes.M /* Marshmallow */)
                {
                    builder.SetMatchMode(BluetoothScanMatchMode.Aggressive);
                    builder.SetNumOfMatches((int)BluetoothScanMatchNumber.MaxAdvertisement);
                    builder.SetCallbackType(ScanCallbackType.AllMatches);
                }

                var settings = builder.Build();

                myScanCallback     = new MyScanCallback();
                bluetoothLeScanner = BluetoothAdapter.DefaultAdapter.BluetoothLeScanner;


                bluetoothLeScanner.StartScan(filters, settings, myScanCallback);
            }
            catch (System.Exception ex)
            {
                Analytics.TrackEvent(Build.Model + " Something went wrong in Discover method.");
            }
        }
예제 #8
0
 //TODO: scan for specific service type eg. HeartRateMonitor
 public async void StartScanningForDevices(List <Guid> serviceUuid)
 {
     if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
     {
         if (serviceUuid != null && serviceUuid.Count > 0)
         {
             List <ScanFilter> filterList = new List <ScanFilter>();
             foreach (Guid guid in serviceUuid)
             {
                 UUID       uuid   = UUID.FromString(guid.ToString());
                 ScanFilter filter = new ScanFilter.Builder().SetServiceUuid(new ParcelUuid(uuid)).Build();
                 filterList.Add(filter);
             }
             this.StartScanningForDevices(filterList);
         }
     }
     else
     {
         Console.WriteLine("Adapter: Starting scan for API 20 and below.");
         StartScanningForDevices();
     }
 }
예제 #9
0
        private ScanFilter CreateScanFilter()
        {
            ScanFilter.Builder mBuilder = new ScanFilter.Builder();

            byte[] mManufacturerData = new byte[23];
            byte[] mManufacturerDataMask = new byte[24];
            byte[] uuid = Constants.BeaconGuid.ToByteArray();
            mManufacturerData[0] = 0xBE;
            mManufacturerData[1] = 0xAC;
            for (int i = 2; i <= 17; i++)
            {
                mManufacturerData[i] = uuid[i - 2];
            }
            mManufacturerDataMask[0] = 0x00;
            mManufacturerDataMask[1] = 0x00;
            for (int i = 2; i <= 17; i++)
            {
                mManufacturerDataMask[i] = 0x01;
            }
            mBuilder.SetManufacturerData(76, mManufacturerData, mManufacturerDataMask);
            return mBuilder.Build();
        }
예제 #10
0
        public async void StartScanning()
        {
            if (IsScanning)
            {
                return;
            }

            IsScanning = true;

            // TODO: Handle power on state.

            if (_sdkInt >= Android.OS.BuildVersionCodes.Lollipop) // 21
            {
                _bleScanner   = _adapter.BluetoothLeScanner;
                _scanCallback = new OWBLE_ScanCallback(this);
                var scanFilters         = new List <ScanFilter>();
                var scanSettingsBuilder = new ScanSettings.Builder();

                var scanFilterBuilder = new ScanFilter.Builder();
                scanFilterBuilder.SetServiceUuid(OWBoard.ServiceUUID.ToParcelUuid());
                scanFilters.Add(scanFilterBuilder.Build());
                _bleScanner.StartScan(scanFilters, scanSettingsBuilder.Build(), _scanCallback);
            }
            else if (_sdkInt >= Android.OS.BuildVersionCodes.JellyBeanMr2) // 18
            {
                _leScanCallback = new OWBLE_LeScanCallback(this);
#pragma warning disable 0618
                _adapter.StartLeScan(new Java.Util.UUID[] { OWBoard.ServiceUUID.ToUUID() }, _leScanCallback);
#pragma warning restore 0618
            }
            else
            {
                throw new NotImplementedException("Can't run bluetooth scans on device lower than Android 4.3");
            }

            await Task.Delay(15 * 1000);

            StopScanning();
        }
예제 #11
0
        private bool StartScanningNew(Guid[] serviceUuids)
        {
            Boolean           hasFilter   = serviceUuids?.Any() ?? false;
            List <ScanFilter> scanFilters = null;

            if (hasFilter)
            {
                scanFilters = new List <ScanFilter>();
                foreach (Guid serviceUuid in serviceUuids)
                {
                    ScanFilter.Builder sfb = new ScanFilter.Builder();
                    sfb.SetServiceUuid(ParcelUuid.FromString(serviceUuid.ToString()));
                    scanFilters.Add(sfb.Build());
                }
            }

            ScanSettings.Builder ssb = new ScanSettings.Builder();
            ssb.SetScanMode(this.ScanMode.ToNative());
            //ssb.SetCallbackType(ScanCallbackType.AllMatches);

            if (this._bluetoothAdapter.BluetoothLeScanner != null)
            {
                Trace.Message($"Adapter >=21: Starting a scan for devices. ScanMode: {this.ScanMode}");
                if (hasFilter)
                {
                    Trace.Message($"ScanFilters: {String.Join(", ", serviceUuids)}");
                }
                this._bluetoothAdapter.BluetoothLeScanner.StartScan(scanFilters, ssb.Build(), this._api21ScanCallback);

                return(true);
            }
            else
            {
                Trace.Message("Adapter >= 21: Scan failed. Bluetooth is probably off");
                return(false);
            }
        }
예제 #12
0
        public bool StartScanning()
        {
            if (isScanning)
            {
                return(true);
            }

            if (IsEnabled)
            {
                // Stops scanning after a pre-defined scan period.
                //scanHandler.PostDelayed(new Runnable(() =>
                //{
                //    isScanning = false;

                //    scanner.StopScan(scanCallback);
                //}), 10000);

                isScanning = true;
                ScanFilter.Builder builder = new ScanFilter.Builder();
                builder.SetServiceUuid(DottedUUID);
                ScanSettings.Builder sBuilder = new ScanSettings.Builder();
                sBuilder.SetScanMode(Android.Bluetooth.LE.ScanMode.LowPower);
                scanner.StartScan(new List <ScanFilter> {
                    builder.Build()
                },
                                  sBuilder.Build(),
                                  scanCallback);
                return(true);
            }
            else
            {
                isScanning = false;
                scanner.StopScan(scanCallback);
                return(false);
            }
        }
예제 #13
0
        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;
            }
        }
예제 #14
0
		//TODO: scan for specific service type eg. HeartRateMonitor
		public async void StartScanningForDevices (List<Guid> serviceUuid)
		{
			if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
			{

				if (serviceUuid != null && serviceUuid.Count > 0)
				{
					List<ScanFilter> filterList = new List<ScanFilter>();
					foreach (Guid guid in serviceUuid)
					{
						UUID uuid = UUID.FromString(guid.ToString());
						ScanFilter filter = new ScanFilter.Builder().SetServiceUuid(new ParcelUuid(uuid)).Build();
						filterList.Add(filter);
					}
					this.StartScanningForDevices(filterList);
				}
			}
			else {
				Console.WriteLine("Adapter: Starting scan for API 20 and below.");
				StartScanningForDevices();
			}
		}
예제 #15
0
        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;
            }
        }
예제 #16
0
        private void StartScanningNew(ScanFilterOptions scanFilterOptions)
        {
            var hasFilter = scanFilterOptions?.HasFilter == true;
            List <ScanFilter> scanFilters = null;

            if (hasFilter)
            {
                scanFilters = new List <ScanFilter>();
                if (scanFilterOptions.HasServiceIds)
                {
                    foreach (var serviceUuid in scanFilterOptions.ServiceUuids)
                    {
                        var sfb = new ScanFilter.Builder();
                        sfb.SetServiceUuid(ParcelUuid.FromString(serviceUuid.ToString()));
                        scanFilters.Add(sfb.Build());
                    }
                }
                if (scanFilterOptions.HasServiceData)
                {
                    foreach (var serviceDataFilter in scanFilterOptions.ServiceDataFilters)
                    {
                        var sfb = new ScanFilter.Builder();
                        if (serviceDataFilter.ServiceDataMask == null)
                        {
                            sfb.SetServiceData(ParcelUuid.FromString(serviceDataFilter.ServiceDataUuid.ToString()), serviceDataFilter.ServiceData);
                        }
                        else
                        {
                            sfb.SetServiceData(ParcelUuid.FromString(serviceDataFilter.ServiceDataUuid.ToString()), serviceDataFilter.ServiceData, serviceDataFilter.ServiceDataMask);
                        }
                        scanFilters.Add(sfb.Build());
                    }
                }
                if (scanFilterOptions.HasManufacturerIds)
                {
                    foreach (var manufacturerDataFilter in scanFilterOptions.ManufacturerDataFilters)
                    {
                        var sfb = new ScanFilter.Builder();
                        if (manufacturerDataFilter.ManufacturerDataMask != null)
                        {
                            sfb.SetManufacturerData(manufacturerDataFilter.ManufacturerId, manufacturerDataFilter.ManufacturerData);
                        }
                        else
                        {
                            sfb.SetManufacturerData(manufacturerDataFilter.ManufacturerId, manufacturerDataFilter.ManufacturerData, manufacturerDataFilter.ManufacturerDataMask);
                        }
                        scanFilters.Add(sfb.Build());
                    }
                }
                if (scanFilterOptions.HasDeviceAddresses)
                {
                    foreach (var deviceAddress in scanFilterOptions.DeviceAddresses)
                    {
                        if (BluetoothAdapter.CheckBluetoothAddress(deviceAddress))
                        {
                            var sfb = new ScanFilter.Builder();
                            sfb.SetDeviceAddress(deviceAddress);
                            scanFilters.Add(sfb.Build());
                        }
                        else
                        {
                            Trace.Message($"Device address {deviceAddress} is invalid. The correct format is \"01:02:03:AB:CD:EF\"");
                        }
                    }
                }
                if (scanFilterOptions.HasDeviceNames)
                {
                    foreach (var deviceName in scanFilterOptions.DeviceNames)
                    {
                        var sfb = new ScanFilter.Builder();
                        sfb.SetDeviceName(deviceName);
                        scanFilters.Add(sfb.Build());
                    }
                }
            }

            var ssb = new ScanSettings.Builder();

            ssb.SetScanMode(ScanMode.ToNative());
            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                // enable Bluetooth 5 Advertisement Extensions on Android 8.0 and above
                ssb.SetLegacy(false);
            }
            //ssb.SetCallbackType(ScanCallbackType.AllMatches);

            if (_bluetoothAdapter.BluetoothLeScanner != null)
            {
                Trace.Message($"Adapter >=21: Starting a scan for devices. ScanMode: {ScanMode}");
                if (hasFilter)
                {
                    if (scanFilterOptions.HasServiceIds)
                    {
                        Trace.Message($"Service UUID Scan Filters: {string.Join(", ", scanFilterOptions.ServiceUuids)}");
                    }
                    if (scanFilterOptions.HasServiceData)
                    {
                        Trace.Message($"Service Data Scan Filters: {string.Join(", ", scanFilterOptions.ServiceDataFilters.ToString())}");
                    }
                    if (scanFilterOptions.HasManufacturerIds)
                    {
                        Trace.Message($"Manufacturer Id Scan Filters: {string.Join(", ", scanFilterOptions.ManufacturerDataFilters.ToString())}");
                    }
                    if (scanFilterOptions.HasDeviceAddresses)
                    {
                        Trace.Message($"Device Address Scan Filters: {string.Join(", ", scanFilterOptions.DeviceAddresses)}");
                    }
                    if (scanFilterOptions.HasDeviceNames)
                    {
                        Trace.Message($"Device Name Scan Filters: {string.Join(", ", scanFilterOptions.DeviceNames)}");
                    }
                }
                _bluetoothAdapter.BluetoothLeScanner.StartScan(scanFilters, ssb.Build(), _api21ScanCallback);
            }
            else
            {
                Trace.Message("Adapter >= 21: Scan failed. Bluetooth is probably off");
            }
        }
예제 #17
0
        protected override Task StartScanningForDevicesNativeAsync(Guid[] serviceUuids, CancellationToken scanCancellationToken)
        {
            // clear out the list
            DiscoveredDevices.Clear();

            if (serviceUuids == null || !serviceUuids.Any())
            {
                if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop)
                {
                    Trace.Message("Adapter < 21: Starting a scan for devices.");
                    //without filter
#pragma warning disable 618
                    _bluetoothAdapter.StartLeScan(_api18ScanCallback);
#pragma warning restore 618
                }
                else
                {
                    Trace.Message("Adapter >= 21: Starting a scan for devices.");
                    if (_bluetoothAdapter.BluetoothLeScanner != null)
                    {
                        _bluetoothAdapter.BluetoothLeScanner.StartScan(_api21ScanCallback);
                    }
                    else
                    {
                        Trace.Message("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();
                    Trace.Message("Adapter < 21: Starting a scan for devices.");
#pragma warning disable 618
                    _bluetoothAdapter.StartLeScan(uuids, _api18ScanCallback);
#pragma warning restore 618
                }
                else
                {
                    Trace.Message("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 (_bluetoothAdapter.BluetoothLeScanner != null)
                    {
                        _bluetoothAdapter.BluetoothLeScanner.StartScan(scanFilters, ssb.Build(), _api21ScanCallback);
                    }
                    else
                    {
                        Trace.Message("Adapter >= 21: Scan failed. Bluetooth is probably off");
                    }
                }
            }

            return(Task.FromResult(true));
        }
예제 #18
0
        protected override async Task ScanAsync(CancellationToken cancellationToken)
        {
            // start a scan if bluetooth is present and enabled
            if (BluetoothAdapter.DefaultAdapter?.IsEnabled ?? false)
            {
                try
                {
                    if (ScanMode.HasFlag(BluetoothScanModes.LE))
                    {
                        List <ScanFilter> scanFilters = new List <ScanFilter>();

                        if (DiscoverAll == false)
                        {
                            ScanFilter scanFilter = new ScanFilter.Builder()
                                                    .SetServiceUuid(new ParcelUuid(_deviceIdService.Uuid))
                                                    .Build();

                            scanFilters.Add(scanFilter);
                        }

                        ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder()
                                                                   .SetScanMode(global::Android.Bluetooth.LE.ScanMode.Balanced);

                        // return batched scan results periodically if supported on the BLE chip
                        if (BluetoothAdapter.DefaultAdapter.IsOffloadedScanBatchingSupported)
                        {
                            scanSettingsBuilder.SetReportDelay((long)(ScanDurationMS / 2.0));
                        }

                        // start a fresh manager delegate to collect/read results
                        _bluetoothScannerCallback = new AndroidBluetoothClientScannerCallback(_deviceIdService, _deviceIdCharacteristic, this);

                        BluetoothAdapter.DefaultAdapter.BluetoothLeScanner.StartScan(scanFilters, scanSettingsBuilder.Build(), _bluetoothScannerCallback);
                    }

                    if (ScanMode.HasFlag(BluetoothScanModes.Classic))
                    {
                        BluetoothAdapter.DefaultAdapter.StartDiscovery();
                    }

                    TaskCompletionSource <bool> scanCompletionSource = new TaskCompletionSource <bool>();

                    cancellationToken.Register(() =>
                    {
                        try
                        {
                            if (ScanMode.HasFlag(BluetoothScanModes.LE))
                            {
                                BluetoothAdapter.DefaultAdapter.BluetoothLeScanner.StopScan(_bluetoothScannerCallback);
                            }
                            else if (ScanMode.HasFlag(BluetoothScanModes.Classic) && BluetoothAdapter.DefaultAdapter.IsDiscovering)
                            {
                                BluetoothAdapter.DefaultAdapter.CancelDiscovery();
                            }
                        }
                        catch (Exception ex)
                        {
                            SensusServiceHelper.Get().Logger.Log("Exception while stopping scan:  " + ex.Message, LoggingLevel.Normal, GetType());
                        }
                        finally
                        {
                            scanCompletionSource.TrySetResult(true);
                        }
                    });

                    await scanCompletionSource.Task;
                }
                catch (Exception ex)
                {
                    SensusServiceHelper.Get().Logger.Log("Exception while scanning:  " + ex.Message, LoggingLevel.Normal, GetType());
                }
            }
        }