最近在項(xiàng)目里面使用了藍(lán)牙跟設(shè)備進(jìn)行通訊,發(fā)現(xiàn)cancelPeripheralConnection這個方法不起效果,總是延時那么5秒才斷開。APP端作為中心管理者連接外圍設(shè)備。具體業(yè)務(wù)流程大概是這樣的:
1.掃描外圍設(shè)備。
2.連接指定的設(shè)備,如名稱為“aaa”的設(shè)備。
3.查找服務(wù)、查找指定特征后發(fā)送數(shù)據(jù),訂閱一個通知(告訴APP這次的發(fā)送內(nèi)容是否正確)。
4.didUpdateValueForCharacteristic:里面判斷數(shù)據(jù)是否正確,以此顯示給用戶。之后調(diào)用cancelPeripheralConnection斷開連接
多么痛的領(lǐng)悟的事情發(fā)生在調(diào)用cancelPeripheralConnection之后。
cancelPeripheralConnection調(diào)用完之后立刻回調(diào)didDisconnectPeripheral這個方法,表明此次已經(jīng)“斷開”連接。
但,事實(shí)是。。。。只是APP層面斷開了連接,物理層并沒有完全斷開。這樣,出現(xiàn)的現(xiàn)象是狀態(tài)欄的藍(lán)牙小圖標(biāo)不會立刻暗下來,而是過5秒后才會暗下來。(暗下來才是物理層的真正斷開)
如果用戶操作完第一次(以上四步驟),接著很快進(jìn)行第二次(也需要進(jìn)行以上四步驟),這樣就會導(dǎo)致用戶在掃描的時候浪費(fèi)數(shù)秒(小于5秒)的時間,導(dǎo)致第二次以后的操作體驗(yàn)非常不好。因?yàn)榈谝淮蔚倪B接在APP層是斷開了,但是在物理層不沒有斷開的,此時第二次掃描、連接的時候必須等待第一次的物理層斷開才可以正常進(jìn)行。(安卓的立馬就斷開了,。。。??影。?/p>
解決辦法:設(shè)備端回碼之后立刻斷開連接!這樣才能保證物理層的斷開了。也就是說,想要藍(lán)牙圖標(biāo)立刻變暗,需要設(shè)備端做斷開。如果不需要這么高要求,那就等待5秒吧。
我是怎么發(fā)現(xiàn)的?
首先,cancelPeripheralConnection 為什么不是disConnectXXX呢?這個引起我的懷疑。
接著,我查了這個方法的官方注釋:
/*!
*@method cancelPeripheralConnection:
*
*@param peripheralA CBPeripheral.
*
*@discussion Cancels an active or pending connection to peripheral. Note that this is non-blocking, and any CBPeripheral
*commands that are still pending to peripheral may or may not complete.
*
*@seecentralManager:didDisconnectPeripheral:error:
*
*/
- (void)cancelPeripheralConnection:(CBPeripheral*)peripheral;
說明此方法只是切斷APP層的連接,may or may not complete :不一定能切斷物理層的連接。
思考:蘋果為什么這樣做?
這是藍(lán)牙設(shè)備的調(diào)度管理鎖導(dǎo)致的,因?yàn)橐粋€藍(lán)牙外設(shè)連接到APP,其實(shí)是連接到系統(tǒng)的藍(lán)牙管理模塊。但iphone上有很多APP都可能用到藍(lán)牙的連接,怎么辦?那就交給系統(tǒng)去分配吧!因?yàn)橛锌赡苡羞@種情況:APP1、APP2需要連接到同一個設(shè)備,但是他們用的是同一個設(shè)備的不同服務(wù)而已,假設(shè)現(xiàn)在兩個APP都在后臺連接這個設(shè)備(看起來有兩個外設(shè),其實(shí)對于系統(tǒng)來說只有一個在連接著),恰巧APP1需要跟設(shè)備(periphral)斷開,而APP2一定不能斷開,那怎么辦?系統(tǒng)是要斷開還是不斷開呢。。。所以這種情況就需要對藍(lán)牙設(shè)備進(jìn)行管理了:APP1要斷開,可以,你不用就可以了,對于系統(tǒng)來說你是斷開的,這是虛擬的斷開,你要連接就重新申請吧。
但是對于那個固定的5秒延時斷開,我是沒找到確切的證據(jù)了。。。
不知道說得對不對,求深入理解。。。。