Как разобрать Bluetooth-маяки в xamarin.ios? - PullRequest
0 голосов
/ 03 апреля 2019

Я пытаюсь распознать вихри Eddystone с помощью форм iphone и xamarin, поэтому я выбираю этот пакет nuget, чтобы добиться цели: https://github.com/andijakl/universal-beacon/

В Android он прекрасно работает и распознает все типы маяков, включая вихревые. С ios маяки распознаются, но я не могу получить их тип и идентификатор. Итак, я увидел, что в библиотеке есть класс CocoaBluetoothCentralDelegate, который не анализирует информацию полностью. Я частично уверен, что есть что-то с этим закомментированным кодом, но я не понимаю, как извлечь информацию, которая мне нужна, из AdvertisingData. Спасибо всем, что ответит мне! Я тоже нашел этот ответ, но он не полный и он мне не помогает: https://stackoverflow.com/a/54293722/7089089

internal class CocoaBluetoothCentralDelegate : CBCentralManagerDelegate
{
    public event EventHandler<BLEAdvertisementPacketArgs> OnAdvertisementPacketReceived;

    #region CBCentralManagerDelegate

    public override void ConnectedPeripheral(CBCentralManager central, CBPeripheral peripheral)
    {
        Debug.WriteLine($"ConnectedPeripheral(CBCentralManager central, CBPeripheral {peripheral})");
    }

    public override void DisconnectedPeripheral(CBCentralManager central, CBPeripheral peripheral, NSError error)
    {
        Debug.WriteLine($"DisconnectedPeripheral(CBCentralManager central, CBPeripheral {peripheral}, NSError {error})");
    }

    public override void DiscoveredPeripheral(CBCentralManager central, CBPeripheral peripheral, NSDictionary advertisementData, NSNumber RSSI)
    {
        Debug.WriteLine($"Cocoa peripheral {peripheral}");
        Debug.WriteLine($"Cocoa advertisementData {advertisementData}");
        Debug.WriteLine($"Cocoa RSSI {RSSI}");

        var bLEAdvertisementPacket = new BLEAdvertisementPacket()
        {
            Advertisement = new BLEAdvertisement()
            {
                LocalName = peripheral.Name,
                ServiceUuids = new List<Guid>(),
                DataSections = new List<BLEAdvertisementDataSection>(),
                ManufacturerData = new List<BLEManufacturerData>()
            },
            AdvertisementType = BLEAdvertisementType.ScanResponse,
            BluetoothAddress = (ulong)peripheral.Identifier.GetHashCode(),
            RawSignalStrengthInDBm = RSSI.Int16Value,
            Timestamp = DateTimeOffset.Now
        };

        //https://developer.apple.com/documentation/corebluetooth/cbadvertisementdataserviceuuidskey
        //if (advertisementData.ContainsKey(CBAdvertisement.DataServiceUUIDsKey))
        //{
        //    bLEAdvertisementPacket.Advertisement.ServiceUuids.Add(
        //        item: new BLEManufacturerData(packetType: BLEPacketType.UUID16List,
        //                                      data: (advertisementData[CBAdvertisement.DataServiceUUIDsKey])));
        //}

        //https://developer.apple.com/documentation/corebluetooth/cbadvertisementdataservicedatakey
        //if (advertisementData.ContainsKey(CBAdvertisement.DataServiceDataKey))
        //{
        //    bLEAdvertisementPacket.Advertisement.DataSections.Add(
        //        item: new BLEManufacturerData(packetType: BLEPacketType.ServiceData,
        //                                      data: advertisementData[CBAdvertisement.DataServiceDataKey]));
        //}

        //https://developer.apple.com/documentation/corebluetooth/cbadvertisementdatamanufacturerdatakey
        if (advertisementData.ContainsKey(CBAdvertisement.DataManufacturerDataKey))
        {
            bLEAdvertisementPacket.Advertisement.ManufacturerData.Add(
                item: new BLEManufacturerData(packetType: BLEPacketType.ManufacturerData,
                                              data: (advertisementData[CBAdvertisement.DataManufacturerDataKey]
                                                     as NSData).ToArray()));
        }

        // Missing CBAdvertisement.DataTxPowerLevelKey

        var bLEAdvertisementPacketArgs = new BLEAdvertisementPacketArgs(data: bLEAdvertisementPacket);
        OnAdvertisementPacketReceived?.Invoke(this, bLEAdvertisementPacketArgs);
    }

    public override void FailedToConnectPeripheral(CBCentralManager central, CBPeripheral peripheral, NSError error)
    {
        Debug.WriteLine($"FailedToConnectPeripheral(CBCentralManager central, CBPeripheral {peripheral}, NSError {error})");
    }

    public override void UpdatedState(CBCentralManager central)
    {
        switch (central.State)
        {
            case CBCentralManagerState.Unknown:
                Debug.WriteLine("CBCentralManagerState.Unknown");
                break;
            case CBCentralManagerState.Resetting:
                Debug.WriteLine("CBCentralManagerState.Resetting");
                break;
            case CBCentralManagerState.Unsupported:
                Debug.WriteLine("CBCentralManagerState.Unsupported");
                break;
            case CBCentralManagerState.Unauthorized:
                Debug.WriteLine("CBCentralManagerState.Unauthorized");
                break;
            case CBCentralManagerState.PoweredOff:
                Debug.WriteLine("CBCentralManagerState.PoweredOff");
                break;
            case CBCentralManagerState.PoweredOn:
                Debug.WriteLine("CBCentralManagerState.PoweredOn");
                central.ScanForPeripherals(peripheralUuids: new CBUUID[] { },
                                                           options: new PeripheralScanningOptions { AllowDuplicatesKey = true });
                break;
            default:
                throw new NotImplementedException();
        }
    }

    public override void WillRestoreState(CBCentralManager central, NSDictionary dict)
    {
        Debug.WriteLine($"WillRestoreState(CBCentralManager central, NSDictionary {dict})");
    }

    #endregion CBCentralManagerDelegate
}

1 Ответ

0 голосов
/ 03 апреля 2019

Как отмечено в другом ответе, который вы связали:

Универсальная библиотека маяков не имеет реализации iOS, которая преобразует пакеты iOS в универсальные пакеты. Это должно быть реализовано.

В приведенном выше коде вы показываете возможную реализацию этого. Реализация может показывать ряд проблем, но я сразу вижу большую:

Показанная реализация использует обратный вызов iOS CoreBluetooth для чтения данных пакета маяка. Одна большая проблема с этим: Обнаружения iBeacon не могут работать с показанным кодом. На iOS операционная система предназначена для блокировки обнаружений пакетов iBeacon с помощью API-интерфейсов CoreBluetooth. Вы должны использовать API-интерфейсы CoreLocation, которые не показаны в указанной реализации.

Теоретически возможно использовать обратный вызов CoreBluetooth, показанный для анализа пакетов маяка Eddystone и пакетов AltBeacon (которые являются рекламой производителя, предоставляемой на iOS, когда приложение находится только на переднем плане). Но для меня это не похоже на этот код где-то близко к тому, чтобы быть готовым к работе.

Для меня это звучит так, будто вы на грани истощения, пытаясь заставить это работать здесь. Вам, вероятно, нужен кто-то с хорошими навыками программирования на iOS (и навыками разработки CoreBluetooth / CoreLocation), чтобы это работало.

...