在藍牙開發(fā)中,經(jīng)常會遇到藍牙Mac地址(物理地址-->唯一標記)鏈接的問題:
對于安卓來說,可以通過Mac地址來鏈接,因為他們可以獲取到外設的Mac地址。
對于蘋果而言,是不可以通過Mac地址鏈接的,因為我們無法獲取外設的Mac地址。
雖然蘋果給我們提供了一個外設的UUID,但是這個UUID是通過外設的Mac地址和手機的Mac地址進行加密計算得來的。
換言之,不同手機鏈接同一外設這個值是不同的,所以這個值并不能取代Mac地址作為唯一標記,況且安卓是沒有這個UUID的。
peripheral.identifier.UUIDString;
*!
* @property identifier
*
* @discussion The unique, persistent identifier associated with the peer.
*/
@property(readonly, nonatomic) NSUUID *identifier NS_AVAILABLE(10_13, 7_0);
/* Return a string description of the UUID, such as "E621E1F8-C36C-495A-93FC-0C247A3E6E5F" */
@property (readonly, copy) NSString *UUIDString;
那iOS如何獲取Mac地址呢?
方案A:硬件工程師將Mac地址寫到廠商數(shù)據(jù)中,然后我們獲?。⊕呙桦A段就可以獲取到)
方案B:(本質就是讀取固定指令獲取)讀取外設的180A服務里的2A23特征值,再去進行剪切和拼接來獲?。ū仨毾孺溄由贤庠O)
詳情參考:http://www.itdecent.cn/p/1d6a8fc8134f
但這個方案有大弊端:
1、就是我必須先鏈接上然后再去獲取這個Mac地址,太消耗成本,且效率不高。
假如有很多設備的話,我必須一一驗證,不是再斷開,遠沒有在掃描階段(掃描的過程是很快的,可以在短短幾秒鐘內(nèi)就可以找到周圍的上百臺設備),確認是再鏈接高效。
2、這樣會有莫名其妙的問題。
3、從鏈接的角度來講有點本末倒置,本來我是用Mac地址來鏈接的,但現(xiàn)在變成了,先鏈接再獲取Mac地址,驗證是否正確。
4、僅限某些設備,如果你的藍牙設備不支持這樣獲取,你需要跟硬件工程師溝通,說白了并不通用
那iOS如何鏈接呢?
一般我們可以通過名稱、廠商數(shù)據(jù)來鏈接。
當手機藍牙(此地將手機藍牙作為中心設備)掃描到外設(譬如手環(huán)之類的)后,會進入這個方法
/*!
* @method centralManager:didDiscoverPeripheral:advertisementData:RSSI:
*
* @param central The central manager providing this update.
* @param peripheral A <code>CBPeripheral</code> object.
* @param advertisementData A dictionary containing any advertisement and scan response data.
* @param RSSI The current RSSI of <i>peripheral</i>, in dBm. A value of <code>127</code> is reserved and indicates the RSSI
* was not available.
*
* @discussion This method is invoked while scanning, upon the discovery of <i>peripheral</i> by <i>central</i>. A discovered peripheral must
* be retained in order to use it; otherwise, it is assumed to not be of interest and will be cleaned up by the central manager. For
* a list of <i>advertisementData</i> keys, see {@link CBAdvertisementDataLocalNameKey} and other similar constants.
*
* @seealso CBAdvertisementData.h
*
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI;
名稱、廠商數(shù)據(jù)可以從advertisementData(廣告數(shù)據(jù))中讀取
/*!
* @constant CBAdvertisementDataLocalNameKey
*
* @discussion A <code>NSString</code> containing the local name of a peripheral.
*
*/
CB_EXTERN NSString * const CBAdvertisementDataLocalNameKey;
/*!
* @constant CBAdvertisementDataManufacturerDataKey
*
* @discussion A <code>NSData</code> object containing the manufacturer data of a peripheral.
*
*/
CB_EXTERN NSString * const CBAdvertisementDataManufacturerDataKey;
//advertisementData中可以發(fā)送的數(shù)據(jù)有約定 如下
17 /*
18 對應設置NSString類型的廣播名
19 NSString *const CBAdvertisementDataLocalNameKey;
20 外設制造商的NSData數(shù)據(jù)
21 NSString *const CBAdvertisementDataManufacturerDataKey;
22 外設制造商的CBUUID數(shù)據(jù)
23 NSString *const CBAdvertisementDataServiceDataKey;
24 服務的UUID與其對應的服務數(shù)據(jù)字典數(shù)組
25 NSString *const CBAdvertisementDataServiceUUIDsKey;
26 附加服務的UUID數(shù)組
27 NSString *const CBAdvertisementDataOverflowServiceUUIDsKey;
28 外設的發(fā)送功率 NSNumber類型
29 NSString *const CBAdvertisementDataTxPowerLevelKey;
30 外設是否可以連接
31 NSString *const CBAdvertisementDataIsConnectable;
32 服務的UUID數(shù)組
33 NSString *const CBAdvertisementDataSolicitedServiceUUIDsKey;
34 */
具體如何保證唯一性,這個就需要和藍牙硬件工程師約定了。
1、如果名稱是唯一的,我們就可以用名稱來約定唯一性。
2、如果名稱相同,又要確定唯一性,那我們就需要通過廠商數(shù)據(jù)來約定了。
具體這個規(guī)則要怎么來約定唯一性,就靠彼此約定了,這個規(guī)則隨意,只要彼此雙方約定好就可以。
綜上:
比較好的鏈接方案就是,蘋果、安卓、硬件大家約定好一個規(guī)則,不論是通過名稱或者廠商數(shù)據(jù)都可以確定唯一性通用性。