简体   繁体   English

如何检测外围设备何时停止广告日期,以便我可以删除该外围设备表单已发现设备列表?

[英]How to detect when a peripheral stops advertisement Date so that i can remove that peripheral form discovered device list?

When you connect to the Bluetooth Central Manager (CM) and start scanning for a device that has particular services, the CM will let you know when it finds a device.当您连接到蓝牙中央管理器 (CM) 并开始扫描具有特定服务的设备时,CM 会在找到设备时通知您。

func centralManager(
    central: CBCentralManager, 
    didDiscoverPeripheral peripheral: CBPeripheral, 
    advertisementData: [String : AnyObject], 
    RSSI: NSNumber)

However, there's no corresponding “didUndiscoverPeripheral” type of function.但是,没有相应的“didUndiscoverPeripheral”类型的函数。 In the case of my app, I needed to show an instruction screen, detect when the device was turned on (discovered), show a list of discovered devices and let the user select it.就我的应用程序而言,我需要显示一个指令屏幕,检测设备何时开启(发现),显示发现的设备列表并让用户选择它。 If the device timed out or was turned off(stops broadcasting advertisement Date), I needed to remove the device from the discovered device list.如果设备超时或关闭(停止广播广告日期),我需要从发现的设备列表中删除该设备。

It will be better if you can explain it with a working example.如果你能用一个有效的例子来解释它会更好。

Set the CBCentralManagerScanOptionAllowDuplicatesKey to true before the scan starts so that the didDiscover peripheral callBack method will execute every time when an advertisement packet is received.在扫描开始前将 CBCentralManagerScanOptionAllowDuplicatesKey 设置为 true,这样 didDiscover 外设回调方法将在每次收到广告数据包时执行。

create a dictionary and a timer to keep track of the discovered device list.创建一个字典和一个计时器来跟踪发现的设备列表。 The key of the dictionary is peripheral identifier and value is counter initially set to 5 when the peripheral is discovered first time after that when an advertisement packet from the peripheral is received we keep on updating the counter value to 5 in didDiscover peripheral callback method.字典的键是外设标识符,当第一次发现外设时,计数器的初始值设置为 5,之后当收到来自外设的广告包时,我们会在 didDiscover 外设回调方法中不断更新计数器值到 5。

    var discoveredPeripherals : [String: Int] = [String: Int]()
    var discoveryTimer : Timer =  Timer()

ScheduledTimer when scan is starts :扫描开始时的 ScheduledTimer :

    discoveryTimer =  Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateDiscoveredDevices), userInfo: nil, repeats: true)

stop the timer when scan stops.扫描停止时停止计时器。

    discoveryTimer.invalidate()

if the device stops advertisement and it is not connected then remove the device after 5 sec from the discovered device list.如果设备停止广播并且未连接,则在 5 秒后从发现的设备列表中删除该设备。

@objc func updateDiscoveredDevices() {
        peripherals.forEach{
            if discoveredPeripherals.index(forKey: $0.identifier.uuidString) != nil
            {
                if discoveredPeripherals[$0.identifier.uuidString]! != 0
                {
                    discoveredPeripherals[$0.bleDeviceGetId()]! -= 1
                }
                else{
                    if $0.state != CBPeripheralState.connected
                    {
                        removeDevice($0)
                    }
                }
            }
        }
    }

Thanks to @Paulw11 for suggesting this approach.感谢@Paulw11 提出这种方法。

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

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