Не могу найти рекламу BLE - PullRequest
       20

Не могу найти рекламу BLE

0 голосов
/ 12 января 2019

В моем приложении Xamarin.Forms я пишу собственный код Android, чтобы рекламировать UUID и некоторые тестовые данные для сканирования другим устройством и его поиска. Я запускаю приложение на планшете SM-T580. Вот мой код:

var parameters = (new AdvertiseSettings.Builder())
                         .SetAdvertiseMode(AdvertiseMode.Balanced)
                         .SetConnectable(false)
                         .SetTimeout(0)
                         .SetTxPowerLevel(AdvertiseTx.PowerMedium).Build();

AdvertiseData data = (new AdvertiseData.Builder()).AddServiceData(_applicationParcelUuid,
                                                                          System.Text.Encoding.ASCII.GetBytes("helloTest123"))
                                                  .Build();

if (BluetoothAdapter.DefaultAdapter.BluetoothLeAdvertiser != null)
{
 BluetoothAdapter.DefaultAdapter.BluetoothLeAdvertiser.StartAdvertising(parameters, data, _customAvertiseCallback);
}

В моем _customAvertiseCallback вызывается переопределение OnStartSuccess, поэтому я думаю, что оно должно работать. Я пытаюсь протестировать его с помощью приложения nRF Connect на устройстве Nexus 5, но на нем никогда не появляется реклама моего устройства.

EDIT

Я попытался добавить код, который сканирует рекламу BLE, чтобы посмотреть, смогу ли я забрать его сам. Он находит другую рекламу BLE с других устройств, но не из моего приложения. Вот мой код для сканирования, он работает в том же приложении:

public void StartBluetoothScanning()
{
    if(_bleScanningInitialized)
    {
        return;
    }

    /**
        * Initialize BluetoothAdapter
        * Check the device has the hardware feature BLE
        * Then enable the hardware,
    */
    BluetoothManager bluetoothManager = (BluetoothManager)GetSystemService(Java.Lang.Class.FromType(typeof(BluetoothManager)));
    var bluetoothAdapter = bluetoothManager.Adapter;
    bool isBleSupported = bluetoothAdapter != null && this.BaseContext.PackageManager.HasSystemFeature(PackageManager.FeatureBluetoothLe);

    if(!isBleSupported)
    {
        return;
    }

    /**
        * Register GATT update receiver
    */

    this.RegisterReceiver(_gattUpdateReceiver, new IntentFilter(BluetoothAdapter.ActionStateChanged));

    /**
    * Initialize Bluetooth service.
    */

    Intent gattServiceIntent = new Intent(BaseContext, typeof(BluetoothGattService));
    var componentName = BaseContext.StartService(gattServiceIntent);
    bool isBind = BaseContext.BindService(gattServiceIntent, _serviceConnection, Bind.AutoCreate);

    /**
    * Prepare for scanning
    */

    List<ScanFilter> scanFilters = new List<ScanFilter>();
    ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder();
    //scanFilterBuilder.SetServiceUuid(_applicationParcelUuid);
        scanFilters.Add(scanFilterBuilder.Build());

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

    if (!bluetoothAdapter.IsEnabled)
    {
        bluetoothAdapter.Enable();
    }

    if (BluetoothAdapter.DefaultAdapter.BluetoothLeScanner != null)
    {
        BluetoothAdapter.DefaultAdapter.BluetoothLeScanner.StartScan(scanFilters, scanSettingsBuilder.Build(), _customScanCallback);

        _bleScanningInitialized = true;
    }
    else
    {
        if (ContextCompat.CheckSelfPermission(ApplicationContext,
            Android.Manifest.Permission.AccessFineLocation) != Permission.Granted)
        {

        }
    }
}

public class CustomScanCallback : ScanCallback
{
    public override void OnScanResult([GeneratedEnum] ScanCallbackType callbackType, ScanResult result)
    {
        base.OnScanResult(callbackType, result);

        if (result.ScanRecord.ServiceUuids != null)
        {
            foreach (var x in result.ScanRecord.ServiceUuids)
            {
                var id = x.Uuid.ToString();

                // never true
                if(id == _applicationGuid)
                {
                    // Found my advertisement,
                }
            }
        }
    }

    public override void OnScanFailed([GeneratedEnum] ScanFailure errorCode)
    {
        // never gets called
        base.OnScanFailed(errorCode);
    }
}

1 Ответ

0 голосов
/ 14 января 2019

Наконец-то обнаружена проблема: AddServiceData должно быть AddServiceUuid, поэтому я могу найти его в result.ScanRecord.ServiceUuids обратного вызова сканирования. Кроме того, для тех, кто не знал, Android 8.0 требуется для Bluetooth 5.0, который имеет увеличенный объем данных для рекламы:

https://source.android.com/devices/bluetooth/ble_advertising

Ваше устройство также должно поддерживать Bluetooth 5.0. Мой SM-T580 этого не делает.

В более старых версиях Bluetooth вы не можете рекламировать более 1 UUID или максимальную полезную нагрузку пользователя в 29 байт.

...