您好,登錄后才能下訂單哦!
目前APP同硬件模塊通信的方式主要有幾種模式: 藍(lán)牙連接模式、WiFi 連接模式(Socket 或 HTTP server)、DLNA 音視頻共享 (iOS端還可使用AirPlay)。最近 常州開發(fā)APP公司點個贊科技項目中測試了 A PP與外設(shè) 通 過 藍(lán)牙方式 實現(xiàn) 硬件 連 接 的功能,對相關(guān)的開發(fā)實現(xiàn)和測試方法進(jìn)行一些整理, 在此分享給大家。
1. 藍(lán)牙基礎(chǔ)知識
1. iOS平臺下藍(lán)牙開發(fā)可以使用 MFI(ExternalAccessory 框架) 或 BLE (CoreBluetooth 框架) 進(jìn)行,但實際開發(fā)中基本都使用 CoreBluetooth 框架,因為它功能更強大,支持藍(lán)牙4.0標(biāo)準(zhǔn)。
2. 藍(lán)牙4.0 BLE (Bluetooth low energy) : 它的優(yōu)點在于傳輸快,耗電低,但傳輸數(shù)據(jù)有限,雖然這個傳輸字節(jié)大小硬件工程師可調(diào),但也不會太大。
3. CoreBluetooth框架的核心是peripheral和 central, 可以理解成外設(shè)和中心, 發(fā)起連接的是central,被連接的設(shè)備為 peripheral,它們是一組相對概念。 比如,當(dāng)手機去連接控制藍(lán)牙耳機時,你的手機就是central,當(dāng)手機藍(lán)牙被另一個手機連接并為其提供服務(wù)時就是peripheral。
4. Service和Characteristic:藍(lán)牙 設(shè)備 通過GATT協(xié) 議 定 義的數(shù)據(jù)通訊方式。一個 peripheral可以提供多種 服務(wù)Service,一種Service 又可以包含多個不同的 特征Characteristic。特征就是具體鍵值對,提供數(shù)據(jù)的地方。每個特征屬性分為讀、寫、通知等幾種方式。
5. central通過peripheral 的 Characteristic 來讀寫外設(shè)的數(shù)據(jù),和獲取通知。 Peripheral廣播自己的Service和characteristic,Central訂閱某一個具體的characteristic,Peripheral就和Central之間通過characteristic建立了一個雙向的數(shù)據(jù)通道
6. 外設(shè)peripheral、服務(wù)Service、特征characteristic之間的關(guān)系:
7. UUID: 藍(lán)牙上的唯一標(biāo)示符,為了區(qū)分不同服務(wù)和特征,就用UUID來表示。
2. 藍(lán)牙的兩種工作模式
1. 中心模式
1. 建立中心
2. 掃描外設(shè)( discover )
3. 連接外設(shè) (connect) 連接失敗、連接斷開、連接成功
4. 掃描外設(shè)中的服務(wù)和特征 (discover)
- 4.1 獲取外設(shè)的 services
- 4.2 獲取外設(shè)的 Characteristics, 獲取 Characteristics 的值,獲 Characteristics 的 Descriptor 和 Descriptor 的值
5. 與外設(shè)做數(shù)據(jù)交互 (explore and interact)
6. 訂閱 Characteristic 的通知
7. 斷開連接 (disconnect)
2. 外設(shè)模式
1. 啟動一個 Peripheral 管理對象
2. 本地 Peripheral 設(shè)置服務(wù),特性,描述,權(quán)限等等
3. Peripheral 發(fā)送廣播
4. 設(shè)置處理訂閱、取消訂閱、讀 characteristic、寫 characteristic 的委托方法
3. 藍(lán)牙設(shè)備的工作狀態(tài)
1. 準(zhǔn)備(standby)
2. 廣播(advertising)
3. 監(jiān)聽掃描(Scanning
4. 發(fā)起連接(Initiating)
5. 已連接(Connected)
3. 藍(lán)牙連接的開發(fā)實現(xiàn)
這里以手機端作為central,以藍(lán)牙設(shè)備作為peripheral,藍(lán)牙設(shè)備連接的開發(fā)實現(xiàn)主要包括以下步驟:
1. 導(dǎo)入蘋果系統(tǒng)藍(lán)牙框架
#import
2. 遵循兩個藍(lán)牙框架相關(guān)的協(xié)議
<cbcentralmanagerdelegate,cbperipheraldelegate></cbcentralmanagerdelegate,cbperipheraldelegate>
3. 新建兩個實例屬性,一個特征屬性
@property (nonatomic, strong) CBCentralManager*centralManager; //中心管理者
@property (nonatomic, strong) CBPeripheral *peripheral; //連接到的外設(shè)
@property (nonatomic, strong) CBCharacteristic*characteristic; //特征
4. 初始化CBCentralManager,進(jìn)行藍(lán)牙管理
- (void)viewDidLoad {
[superviewDidLoad];
self.centralManager= [[CBCentralManager alloc] initWithDelegate:selfqueue:dispatch_get_main_queue()]; //創(chuàng)建實例進(jìn)行藍(lán)牙管理
}
//若中心管理者初始化之后就會觸發(fā)下面這個代理方法。該代理方法是用來判斷手機藍(lán)牙的狀態(tài)的
-(void)centralManagerDidUpdateState:(CBCentralManager *)central {
//藍(lán)牙可用,開始掃描外設(shè)
if(central.state == CBManagerStatePoweredOn) {
NSLog(@"藍(lán)牙可用");
//在中心管理者成功開啟之后再進(jìn)行一些操作
//搜索掃描外設(shè)
//根據(jù)SERVICE_UUID來掃描外設(shè),如果不設(shè)置SERVICE_UUID,則掃描所有藍(lán)牙設(shè)備
//[self.centralManagerstartAdvertising:@{CBAdvertisementDataServiceUUIDsKey:@[[CBUUIDUUIDWithString:SERVICE_UUID]]}];
[centralscanForPeripheralsWithServices:nil options:nil];
}
if(central.state== CBManagerStateUnsupported) {
NSLog(@"該設(shè)備不支持藍(lán)牙");
}
if(central.state == CBManagerStatePoweredOff) {
NSLog(@"藍(lán)牙已關(guān)閉");
}
if(central.state == CBManagerStateUnknown) {
NSLog(@"藍(lán)牙當(dāng)前狀態(tài)不明確");
}
if(central.state == CBManagerStateUnauthorized) {
NSLog(@"藍(lán)牙未被授權(quán)");
}
}
5. 搜索外圍設(shè)備
//執(zhí)行掃描動作之后,如果掃描到外設(shè)了,就會自動回調(diào)下面的協(xié)議方法
/** 發(fā)現(xiàn)符合要求的外設(shè),回調(diào) */
- (void)centralManager:(CBCentralManager*)central didDiscoverPeripheral:(CBPeripheral *)peripheraladvertisementData:(NSDictionary*)advertisementDataRSSI:(NSNumber *)RSSI {
NSLog(@"%@====",peripheral.name);
//根據(jù)外設(shè)名字有選擇性的篩選連接藍(lán)牙設(shè)備
if([peripheral.name hasPrefix:@"TEAMOSA"]) {
//在這里對外設(shè)攜帶的廣播數(shù)據(jù)進(jìn)行進(jìn)一步的處理
if([self.peripheraNames containsObject:peripheral.name]) {
//如果數(shù)組中包含了就不再添加
return;
}
//添加到外設(shè)名字?jǐn)?shù)組中
[self.peripheraNamesaddObject:peripheral.name];
//標(biāo)記外設(shè),讓它的生命周期與控制器的一致
self.peripheral= peripheral;
//可以根據(jù)外設(shè)名字來過濾外設(shè)
//[central connectPeripheral:peripheral options:nil];
}
//連接外設(shè)
//[central connectPeripheral:peripheral options:nil];
}
6. 連接外圍設(shè)備
//連接外圍設(shè)備,中心管理者連接外設(shè)成功,如果連接成功就會回調(diào)這個協(xié)議方法
/** 連接成功 */---
- (void)centralManager:(CBCentralManager*)central didConnectPeripheral:(CBPeripheral *)peripheral{
//連接成功之后,可以進(jìn)行服務(wù)和特性的發(fā)現(xiàn)。停止中心管理設(shè)備的掃描動作,要不然在你和已經(jīng)連接好的外設(shè)進(jìn)行數(shù)據(jù)溝通時,如果又有一個外設(shè)進(jìn)行廣播且符合你的連接條件,那么你的iOS設(shè)備也會去連接這個設(shè)備(因為iOS BLE4.0是支持一對多連接的),導(dǎo)致數(shù)據(jù)的混亂。
//停止掃描動作
[self.centralManagerstopScan];
//設(shè)置外設(shè)的代理
peripheral.delegate= self;
//根據(jù)UUID來尋找對象服務(wù)
//[peripheral discoverServices:@[[CBUUID UUIDWithString:SERVICE_UUID]]];
//外設(shè)發(fā)現(xiàn)服務(wù),傳nil代表不過濾,一次性讀出外設(shè)的所有服務(wù)
[peripheraldiscoverServices:nil];
NSLog(@"%s,line = %d, %@=連接成功", __FUNCTION__, __LINE__,peripheral.name);
}
//外設(shè)連接失敗
/** 連接失敗的回調(diào) */
- (void)centralManager:(CBCentralManager*)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError*)error {
NSLog(@"%s,line = %d, %@=連接失敗", __FUNCTION__, __LINE__,peripheral.name);
}
//丟失連接 掉線
/** 斷開連接 */
- (void)centralManager:(CBCentralManager*)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullableNSError *)error {
NSLog(@"%s,line = %d, %@=斷開連接", __FUNCTION__, __LINE__,peripheral.name);
//斷開連接可以設(shè)置重新連接
[centralconnectPeripheral:peripheral options:nil];
}
以上,已經(jīng)實現(xiàn)了APP端連接藍(lán)牙設(shè)備的功能,藍(lán)牙設(shè)備連接完成后,還可以對設(shè)備進(jìn)行數(shù)據(jù)讀寫,包括:獲取外圍設(shè)備服務(wù)和特征;從外圍設(shè)備讀取數(shù)據(jù);向外圍設(shè)備發(fā)送(寫入)數(shù)據(jù)等操作。這里暫不具體展開。
4. APP連接藍(lán)牙設(shè)備的測試關(guān)注點
介紹了藍(lán)牙的基礎(chǔ)知識、APP連接藍(lán)牙設(shè)備的開發(fā)實現(xiàn),接下來將介紹APP連接藍(lán)牙設(shè)備這一過程測試中需要關(guān)注的測試點(由于每種藍(lán)牙設(shè)備連接需求不同,開發(fā)實現(xiàn)上也會有細(xì)小差別,實際測試中可視具體開發(fā)邏輯進(jìn)行調(diào)整):
1. APP掃描設(shè)備
1)手機端藍(lán)牙不同設(shè)置下是否能正常掃描:藍(lán)牙打開、藍(lán)牙關(guān)閉;
2)藍(lán)牙設(shè)備被掃描到并出現(xiàn)在可連接設(shè)備列表的條件:藍(lán)牙設(shè)備名稱與可連接的設(shè)備列表中的名稱匹配、設(shè)備處于廣播狀態(tài);
藍(lán)牙設(shè)備與可連接的設(shè)備列表中名稱是否匹配:匹配、不匹配;
藍(lán)牙設(shè)備狀態(tài)(視具體硬件而定):待機狀態(tài)、廣播狀態(tài)、已連接狀態(tài)、藍(lán)牙設(shè)備操作中、數(shù)據(jù)傳輸中、關(guān)機狀態(tài);
測試以上各種組合場景下,藍(lán)牙設(shè)備是否能正常掃描且出現(xiàn)在可連接設(shè)備列表;
3)不同場景下,是否正常掃描:
一個手機同時掃描多個設(shè)備;
多個手機同時掃描同一個設(shè)備;
多個手機同時掃描多個設(shè)備;
4)掃描過程中取消;
5)掃描結(jié)果:掃描超時;未掃描到可連接設(shè)備,是否支持重試;掃描失?。粧呙璩晒?;
2. 連接設(shè)備(APP端點擊可連接設(shè)備列表,連接藍(lán)牙設(shè)備)
1)測試藍(lán)牙設(shè)備狀態(tài)變化后,不同狀態(tài)下是否可正常連接:待機狀態(tài)、廣播狀態(tài)、已連接狀態(tài)、藍(lán)牙設(shè)備操作中、數(shù)據(jù)傳輸中、關(guān)機狀態(tài);
2)連接結(jié)果的處理:連接成功、連接失敗、連接超時等;
3)連接成功后的操作:APP其他操作、連接中斷、退到后臺、殺掉APP等;
4)其他場景:掃描到多個設(shè)備;
3. 斷開連接
1)設(shè)備端斷開:設(shè)備關(guān)機、設(shè)備電量耗盡;
2)APP端斷開:手動斷開、其他操作斷開連接;
4. 其他交互操作
1)切換其他藍(lán)牙設(shè)備,是否正常連接;
2)藍(lán)牙斷開后重新打開,支持自動連接;
3)距離超出藍(lán)牙可檢測范圍,是否會斷開連接,再恢復(fù)到可檢測范圍,能否自動連接;
4)手機端連接多個不同藍(lán)牙設(shè)備,各個設(shè)備功能是否都正常使用;
5. 連接成功后的數(shù)據(jù)傳輸
1)功能上,APP端和藍(lán)牙設(shè)備端是否符合正常使用需求;
2)性能上,APP與藍(lán)牙設(shè)備的交互是否滿足需求;
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。