iOS藍芽開發:藍芽連線和資料讀寫
當下藍芽開發可謂是越來越火,不論是智慧穿戴的興起還是藍芽傢俱,車聯網藍芽等等,很多同學也會接觸到藍芽的專案,我從事藍芽開發也有一段時間了,經手了兩個專案。廢話不多說了,先向大家簡單的介紹有關藍芽開發的知識。藍芽低能耗(BLE),以下介紹的都是圍繞iOS的框架展開的。
藍芽開發分為中心者模式和管理者模式:1.常用的(其實99.99%)就是使用中心者模式作為開發,就是我們手機作為主機,連線藍芽外設;2.管理者模式,這個基本用到的比較少,我們手機自己作為外設,自己建立服務和特徵,然後有其他的裝置連線我們的手機。
在做藍芽開發之前,最好先了解一些概念:
服務(services):藍芽外設對外廣播的必定會有一個服務,可能也有多個,服務下面包含著一些特徵,服務可以理解成一個模組的視窗;
特徵(characteristic):存在於服務下面的,一個服務下面也可以存在多個特徵,特徵可以理解成具體實現功能的視窗,一般特徵都會有value,也就是特徵值,特徵是與外界互動的最小單位;
UUID:可以理解成藍芽上的唯一識別符號(硬體上肯定不是這個意思,但是這樣理解便於我們開發),為了區分不同的服務和特徵,或者給服務和特徵取名字,我們就用UUID來代表服務和特徵。
藍芽連線可以大致分為以下幾個步驟
1.建立一個Central Manager例項進行藍芽管理
2.搜尋外圍裝置
3.連線外圍裝置
4.獲得外圍裝置的服務
5.獲得服務的特徵
6.從外圍裝置讀資料
7.給外圍裝置傳送資料
其他:提醒
首先我們先匯入系統的BLE的框架
import
必須遵守2個協議
/* 中心管理者 /
@property (nonatomic, strong) CBCentralManager *cMgr;
/* 連線到的外設 /
@property (nonatomic, strong) CBPeripheral *peripheral;
1.建立一個Central Manager例項進行藍芽管理
-(CBCentralManager *)cmgr
{
if (!_cmgr) {
_cMgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
return _cMgr;
}
//只要中心管理者初始化 就會觸發此代理方法 判斷手機藍芽狀態
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
switch (central.state) {
case 0:
NSLog(@”CBCentralManagerStateUnknown”);
break;
case 1:
NSLog(@”CBCentralManagerStateResetting”);
break;
case 2:
NSLog(@”CBCentralManagerStateUnsupported”);//不支援藍芽
break;
case 3:
NSLog(@”CBCentralManagerStateUnauthorized”);
break;
case 4:
{
NSLog(@”CBCentralManagerStatePoweredOff”);//藍芽未開啟
}
break;
case 5:
{
NSLog(@”CBCentralManagerStatePoweredOn”);//藍芽已開啟
// 在中心管理者成功開啟後再進行一些操作
// 搜尋外設
[self.cMgr scanForPeripheralsWithServices:nil // 通過某些服務篩選外設
options:nil]; // dict,條件
// 搜尋成功之後,會呼叫我們找到外設的代理方法
// - (void)centralManager:(CBCentralManager )central didDiscoverPeripheral:(CBPeripheral
}
break;
default:
break;
}
}
2.搜尋外圍裝置 (我這裡為了舉例,採用了自己身邊的一個手環)
// 發現外設後呼叫的方法
- (void)centralManager:(CBCentralManager *)central // 中心管理者
didDiscoverPeripheral:(CBPeripheral *)peripheral // 外設
advertisementData:(NSDictionary *)advertisementData // 外設攜帶的資料
RSSI:(NSNumber *)RSSI // 外設發出的藍芽訊號強度
{
//NSLog(@”%s, line = %d, cetral = %@,peripheral = %@, advertisementData = %@, RSSI = %@”, FUNCTION, LINE, central, peripheral, advertisementData, RSSI);
/*
peripheral = , advertisementData = {
kCBAdvDataChannel = 38;
kCBAdvDataIsConnectable = 1;
kCBAdvDataLocalName = OBand;
kCBAdvDataManufacturerData = <4c69616e 0e060678 a5043853 75>;
kCBAdvDataServiceUUIDs = (
FEE7
);
kCBAdvDataTxPowerLevel = 0;
}, RSSI = -55
根據列印結果,我們可以得到運動手環它的名字叫 OBand-75
*/
// 需要對連線到的外設進行過濾
// 1.訊號強度(40以上才連線, 80以上連線)
// 2.通過裝置名(裝置字串字首是 OBand)
// 在此時我們的過濾規則是:有OBand字首並且訊號強度大於35
// 通過列印,我們知道RSSI一般是帶-的
if ([peripheral.name hasPrefix:@"OBand"]) {
// 在此處對我們的 advertisementData(外設攜帶的廣播資料) 進行一些處理
// 通常通過過濾,我們會得到一些外設,然後將外設儲存到我們的可變陣列中,
// 這裡由於附近只有1個運動手環, 所以我們先按1個外設進行處理
// 標記我們的外設,讓他的生命週期 = vc
self.peripheral = peripheral;
// 發現完之後就是進行連線
[self.cMgr connectPeripheral:self.peripheral options:nil];
NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);
}
}
3.連線外圍裝置
// 中心管理者連線外設成功
- (void)centralManager:(CBCentralManager *)central // 中心管理者
didConnectPeripheral:(CBPeripheral *)peripheral // 外設
{
NSLog(@”%s, line = %d, %@=連線成功”, FUNCTION, LINE, peripheral.name);
// 連線成功之後,可以進行服務和特徵的發現
// 設定外設的代理
self.peripheral.delegate = self;
// 外設發現服務,傳nil代表不過濾
// 這裡會觸發外設的代理方法 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
[self.peripheral discoverServices:nil];
}
// 外設連線失敗
- (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:(NSError *)error
{
NSLog(@”%s, line = %d, %@=斷開連線”, FUNCTION, LINE, peripheral.name);
}
4.獲得外圍裝置的服務 & 5.獲得服務的特徵
// 發現外設服務裡的特徵的時候呼叫的代理方法(這個是比較重要的方法,你在這裡可以通過事先知道UUID找到你需要的特徵,訂閱特徵,或者這裡寫入資料給特徵也可以)
- (void)peripheral:(CBPeripheral )peripheral didDiscoverCharacteristicsForService:(CBService )service error:(NSError *)error
{
NSLog(@”%s, line = %d”, FUNCTION, LINE);
for (CBCharacteristic *cha in service.characteristics) {
//NSLog(@"%s, line = %d, char = %@", __FUNCTION__, __LINE__, cha);
}
}
6.從外圍裝置讀資料
// 更新特徵的value的時候會呼叫 (凡是從藍芽傳過來的資料都要經過這個回撥,簡單的說這個方法就是你拿資料的唯一方法) 你可以判斷是否
- (void)peripheral:(CBPeripheral )peripheral didUpdateValueForCharacteristic:(CBCharacteristic )characteristic error:(NSError *)error
{
NSLog(@”%s, line = %d”, FUNCTION, LINE);
if (characteristic == @”你要的特徵的UUID或者是你已經找到的特徵”) {
//characteristic.value就是你要的資料
}
}
7.給外圍裝置傳送資料(也就是寫入資料到藍芽)
這個方法你可以放在button的響應裡面,也可以在找到特徵的時候就寫入,具體看你業務需求怎麼用啦
[self.peripherale writeValue:_batteryData forCharacteristic:self.characteristic type:CBCharacteristicWriteWithResponse];//第一個引數是已連線的藍芽裝置 ;第二個引數是要寫入到哪個特徵; 第三個引數是通過此響應記錄是否成功寫入
// 需要注意的是特徵的屬性是否支援寫資料
- (void)yf_peripheral:(CBPeripheral )peripheral didWriteData:(NSData )data forCharacteristic:(nonnull CBCharacteristic *)characteristic
{
/*
typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {
CBCharacteristicPropertyBroadcast = 0x01,
CBCharacteristicPropertyRead = 0x02,
CBCharacteristicPropertyWriteWithoutResponse = 0x04,
CBCharacteristicPropertyWrite = 0x08,
CBCharacteristicPropertyNotify = 0x10,
CBCharacteristicPropertyIndicate = 0x20,
CBCharacteristicPropertyAuthenticatedSignedWrites = 0x40,
CBCharacteristicPropertyExtendedProperties = 0x80,
CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0) = 0x100,
CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0) = 0x200
};
打印出特徵的許可權(characteristic.properties),可以看到有很多種,這是一個NS_OPTIONS的列舉,可以是多個值
常見的又read,write,noitfy,indicate.知道這幾個基本夠用了,前倆是讀寫許可權,後倆都是通知,倆不同的通知方式
*/
// NSLog(@”%s, line = %d, char.pro = %d”, FUNCTION, LINE, characteristic.properties);
// 此時由於列舉屬性是NS_OPTIONS,所以一個列舉可能對應多個型別,所以判斷不能用 = ,而應該用包含&
}
其他:提醒
有那麼多的特徵,我們怎麼知道哪些特徵是用來讀資料的,哪些是用來寫入的,哪些是需要訂閱之後再讀的呢?
如果你們硬體工程師事先告訴你了,或者有完成的開發文件,那麼就可以直接知道了,否則你就需要自己去檢視特徵的屬性,推介可以使用下第三方的app——LightBlue,讓你更能清楚的看到你藍芽裡面的服務,特徵,特徵的屬性。
其他後續有關文章,我會慢慢整理髮出來,有需要的同學可以留下郵箱,我這裡有視訊教程,我也可以回答相關的問題,有錯誤的地方可以幫忙指出來呦!
相關推薦
iOS藍芽開發:藍芽連線和資料讀寫
當下藍芽開發可謂是越來越火,不論是智慧穿戴的興起還是藍芽傢俱,車聯網藍芽等等,很多同學也會接觸到藍芽的專案,我從事藍芽開發也有一段時間了,經手了兩個專案。廢話不多說了,先向大家簡單的介紹有關藍芽開發的知識。藍芽低能耗(BLE),以下介紹的都是圍繞iOS的框架展開
iOS藍芽開發:藍芽的連線和資料的讀寫
藍芽開發說簡單也簡單,說不簡單也有點難,開發人員在首次開發藍芽前首先需要搞清楚藍芽開發的概念,還要了解掌握藍芽開發的一整套流程,這樣才能快速上手開發藍芽。 藍芽開發分為兩種模式:管理者模式和中心者模式。管理者模式基本很少用到,相當於iPhone手機
030:Cetus中間件和MHA讀寫分離
sample ignore 分離 dir sse binary 順序 cpu tar zxvf 030:Cetus中間件和MHA讀寫分離 一、主機環境 虛擬機配置 CPU 內存 硬盤 OS版本 MySQL版本 MHA版本 Cetus版本 2-core 4
1 android藍芽開發---與藍芽模組進行通訊
原文地址 http://www.cnblogs.com/wenjiang/p/3200138.html 近半個月來一直在搞android藍芽這方面,主要是專案需要與藍芽模組進行通訊。開頭的進展很順利,但因為藍芽模組不在我這裡,所以只能用手機測試。一開頭就發現手機的藍芽
android藍芽開發-與藍芽模組通訊
因為我馬上要離職了,在很多官網上看到招聘android基本都要會藍芽開發,wifi的經驗,所以就來學習下藍芽! 於是,我得到了很好的教訓:請確保專案中的最關鍵因素是否在我們的掌握中。像是藍芽模組這種東西,應該今早催促對方拿過來才是,而不是自己一個人在那邊瞎搞。 嘮叨話就先到
Android 藍芽開發,藍芽連印表機。
public synchronized void connect(String macAddress, BluetoothDevice device) { if (mThread != null) { mThread.interrupt(); m
Android藍芽開發與藍芽模組進行通訊(基於eclipse)
public class ComminuteActivity extends Activity { private BluetoothReceiver receiver; private BluetoothAdapter bluetoothAdapter; private Lis
【視頻】零基礎學Android開發:藍牙聊天室APP(一)
android入門 mod http 開發 org 薪資 get target 下載 零基礎學Android開發:藍牙聊天室APP第一講 1. Android介紹與環境搭建:史上最高效Android入門學習 1.1 Google的大小戰略 1.2 物聯網與雲計算 1.3
基於Swift的iOS應用程式開發:通過UITextFieldDelegate快速理解Delegate事件代理
// // 關於文字輸入框的事件代理,摘錄蘋果開發者中心的官方解釋如下: //*******************************************************************************************// //* To understand wh
Java Web開發:Spring MVC連線 MongoDB啟動使用者名稱密碼
預先準備 配置版本 spring MVC 4.1.1 spring-data-mongodb 1.60 mongodb3.2.1 springMVC開發環境已經配好 mongodb新增使用者 注意事項:mongodb3.0版本後密碼加密有兩種方式,MONGODB-CR兩種方
iOS App開發:最好的設計和開發工具
眾所周知,iOS是一個作業系統,由蘋果公司設計與開發而且依靠蘋果硬體執行,如iPhone、iPad和iPod。設計該作業系統最初的想法是開發一個介面,可在小屏手機上較為容易地執行應用程式。因此iPhone派上用場。像其他的任意一款移動作業系統,iPhone提供使
安卓開發:SmartImageView簡單實現和應用
overload override ans geb actor dsta pub pac 獲取 通常從服務器端獲取的圖片是URL地址,如果簡單地通過URL地址獲取圖片? 有一個開源項目:SmartImageView,做到了這個功能,同時還有其他功能,下載不便,過於龐大 這裏
Android OpenSL ES 開發:Android OpenSL 介紹和開發流程說明
ror logic ogr activity engine eid 優化 als 分享 一、Android OpenSL ES 介紹 OpenSL ES (Open Sound Library for Embedded Systems)是無授權費、跨平臺、針對嵌入式系統精心
基礎知識概念(1):Socket 長連線和短連線的概念
1.短連線 連線->傳輸資料->關閉連線 HTTP是無狀態的,瀏覽器和伺服器每進行一次HTTP操作,就建立一次連線,但任務結束後就中斷連線。短連線是指SOCKET建立連線後 ,傳送後或接收完資料後,就馬上斷開連線。 2.長連線
SpringBoot專案開發(二十二):SpringBoot MongoDB實現副本集(讀寫分離)
1.MongoDB可以單庫、主從(官方現已不推薦)、副本集、分片加副本集,通過分片加副本集可以組成龐大的資料儲存叢集,而大部分專案使用副本集就能滿足需求了 2.MongoDB副本集(Replica Set):有自動故障恢復功能的主從叢集,有一個Primary節點和一個或多個Secon
Android開發(2):資料儲存之一:SharedPrefrences和檔案讀寫
一、資料儲存 本文主要講前兩種儲存方式,其中檔案讀寫只記錄Internal Storage方式 1. SharedPrefrences方式 輕量級NVP方式儲存,以XML的檔案方式儲存,適合少量資料的儲存。 NVP:Name/Value pair, 名稱/值 對。 2.
Windows網路程式設計(四):建立UDP連線和收發訊息
UDP訊息的傳送和接收需要UDP連線,所以,上面的TCP連線已經不適用了,具體的區別主要有: 建立Socket時引數不同建立服務端時不需要listen和accept操作建立客戶端時不需要connect操作伺服器需要bind操作,客戶端不需要。 傳送和接收UDP訊息要用到sendt
Windows網路程式設計(三):建立TCP連線和收發訊息
先看服務端: // ConsoleApplication3.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #define _WINSOCK_DEPRECATED_NO_WARNINGS //這個宣告要在stdafx.h的後面,但要
kotlin安卓開發:fragment向activity傳遞資料通過handler,設定回撥方法
從activity向fragment傳遞就比較方便了,直接用: fg.arguments = arguments 現在看看怎麼從fragment向activity傳遞資料。 比如說,我們在一個ViewPage裡面設定了若干個fragment,fragment裡面有一個按鈕,提交相關
Python web開發:Flask的URL和檢視
URL與檢視 URL與函式的對映: 從之前的helloworld.py檔案中,我們已經看到,一個URL要與執行函式進行對映,使用的是@app.route裝飾器。@app.route裝飾器中,可以指定URL的規則來進行更加詳細的對映,比如現在要對映一個文章詳情的URL,文章詳情的URL