繁体   English   中英

如何解析 xamarin.ios 中的蓝牙信标?

[英]How to Parse Bluetooth Beacons in xamarin.ios?

我试图用 iPhone 和 Xamarin.Forms 识别 Eddystone 信标,所以我选择了这个 NuGet 包来做到这一点: https : //github.com/andijakl/universal-beacon/

在 Android 中,它运行良好,可以识别各种类型的信标,包括 Eddystone 的信标。 使用 iOS,可以识别信标,但我无法获取它们的类型和 ID。 我看到在库中有一个CocoaBluetoothCentralDelegate类,它没有完全解析信息。

我肯定部分,有一些与注释的代码,但我还没有制定出如何提取我从需要的信息advertisementData

感谢所有会回答我的人! 我找到了这个答案,但它不完整并且对我没有帮助:

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
}

正如您链接的另一个答案中所述:

通用信标库没有将 iOS 数据包转换为通用数据包的 iOS 实现。 这是需要实施的。

在你上面的代码中,你展示了一个可能的实现。 显示的实现可能存在许多问题,但我可以立即看到一个大问题:

显示的实现使用 iOS CoreBluetooth 回调来读取信标数据包数据。 一个大问题: iBeacon 检测无法与显示的代码一起使用。 在 iOS 上,操作系统旨在阻止使用 CoreBluetooth API 检测 iBeacon 数据包。 您必须使用 CoreLocation API,显示的实现没有这样做。

理论上可以使用显示的 CoreBluetooth 回调来解析 Eddystone 信标数据包和 AltBeacon 数据包(它们是仅当应用程序处于前台时在 iOS 上提供的制造商广告。)但对我来说这听起来不像这段代码接近任何地方准备出发。

在我看来,您正处于尝试让它在这里工作的最前沿。 您可能需要具有扎实的 iOS 本机编程技能(以及 CoreBluetooth/CoreLocation 开发技能)的人来完成这项工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM