昨天在藍(lán)牙技術(shù)交流群中有人提出了這樣一個(gè)需求:
需要實(shí)時(shí)更新曾經(jīng)搜索過并緩存下來的設(shè)備的RSSI, 不論連接與否
我當(dāng)時(shí)隨便想了下給出的建議是:
場景一: 沒有連接過設(shè)備
1. 通過首次搜索, 能夠獲取到臨近手機(jī)的外設(shè), 拿到并更新一次RSSI
2. 定時(shí)調(diào)用`readRSSI`方法, 通過`peripheral: didReadRSSI:(NSNumber *)RSSI error:`回調(diào)來獲取RSSI, 如果在身邊的應(yīng)當(dāng)可以獲取到RSSI并更新, 不在附近的會(huì)返回error, 將其置為離線狀態(tài)(如果基于GAP協(xié)議的設(shè)備, 被其他設(shè)備連接后, 也將不再進(jìn)行廣播)
3. 至于時(shí)效性, 看定時(shí)器的間隔時(shí)間
場景二: 綁定過設(shè)備
這種情況可能不存在手動(dòng)搜索這個(gè)環(huán)節(jié), 直接按照場景一步驟2來
今天有空試了一下, 其實(shí)是滿足不了這個(gè)需求的, 而我也想到了另外的實(shí)現(xiàn)方式, 先來分析下這種思路的問題在哪里
關(guān)鍵點(diǎn)就在與需要通過外設(shè)調(diào)用readRSSI
, 然后 通過peripheral: didReadRSSI:(NSNumber *)RSSI error:
回調(diào)來獲取RSSI, 而我正是忽略了這兩個(gè)API
按照這種思路直接遍歷數(shù)組, 通過外設(shè)調(diào)用readRSSI
, 那么控制臺(tái)下你將看到如下報(bào)錯(cuò):
[CoreBluetooth] API MISUSE: Reading RSSI for peripheral <CBPeripheral: 0x1015b7c40, identifier = 3B8FA357-8E62-45CE-A8DB-ACE3962B5599, name = 河蟹-和諧, state = disconnected> while delegate is either nil or does not implement peripheral:didReadRSSI:error:
如果你以為設(shè)置了delegate就可以了, 那么你將遇到下面的報(bào)錯(cuò):
[CoreBluetooth] API MISUSE: <CBPeripheral: 0x1016862d0, identifier = 80D55926-D1B7-0875-F70B-50ACD7BF5889, name = 河蟹-和諧, state = disconnected> can only accept commands while in the connected state
我猜想將所有在周邊的設(shè)備都連接上然后去更新RSSi的方式, 不是每個(gè)項(xiàng)目都滿足的, 所以這個(gè)方法不太實(shí)際 , 僅適用于連接中的設(shè)備.
我想到的另外一種方式是:
通過設(shè)置搜索選項(xiàng), 調(diào)用搜索外設(shè)API來拿到RSSI值信息
設(shè)置KEY: CBCentralManagerScanOptionAllowDuplicatesKey
這個(gè)KEY的官方介紹:
A Boolean value that specifies whether the scan should run without duplicate filtering.
The value for this key is an NSNumber object.
If `YES`, filtering is disabled and a discovery event is generated each time the central receives an advertising packet from the peripheral.
Disabling this filtering can have an adverse effect on battery life and should be used only if necessary.
If `NO`, multiple discoveries of the same peripheral are coalesced into a single discovery event.
If the key is not specified, the default value is `NO`.
過濾默認(rèn)是開啟的, 如果搜索選項(xiàng)設(shè)置為YES
, 那么將會(huì)收到每次設(shè)備廣播的信息, 外設(shè)廣播一次會(huì)在37,38,39三個(gè)信號(hào)分別發(fā)送一次廣播, 算是一次廣播事件, 而廣播事件間隔時(shí)間完全取決于嵌入式設(shè)置 (Link Layer允許Host在這三個(gè)物理信道中斩披,任意選取一個(gè)或者多個(gè)屉符,用于廣播)