我正在尝试用iphone和xamarin形式识别eddystone信标,所以我选择这个nuget包来做这个诀窍:https://github.com/andijakl/universal-beacon/
在android中,它很有效,可以识别各种类型的信标,包括eddystone信标。随着ios信标被识别,但我无法获得他们的类型和身份。所以我在库中看到这个CocoaBluetoothCentralDelegate类没有完全解析信息。我部分肯定这个注释代码有一些东西,但我不知道如何从advertData中提取我需要的信息。感谢所有能回答我的人!我也找到了这个答案,但它并不完整,它对我没有帮助: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
}
如您在其他答案中所述:
通用信标库没有将iOS数据包转换为通用数据包的iOS实现。这需要实施。
在上面的代码中,您将展示可能的实现。实现显示可能存在许多问题,但我可以立即看到一个大问题:
显示的实现使用iOS CoreBluetooth回调来读取信标包数据。这有一个很大的问题:iBeacon检测不能与显示的代码一起使用。在iOS上,操作系统旨在使用CoreBluetooth API阻止对iBeacon数据包的检测。您必须使用CoreLocation API,而实现的实现不会这样做。
理论上可以使用显示的CoreBluetooth回调来解析Eddystone信标数据包和AltBeacon数据包(当应用程序仅在前台时,这是iOS上提供的制造商广告。)但是这听起来并不像我这个代码在任何地方关闭准备好去。
听起来我觉得你正在努力让这个工作在这里。您可能需要具备可靠iOS本机编程技能(以及CoreBluetooth / CoreLocation开发技能)的人才能使其正常工作。