- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章iOS蓝牙开发 蓝牙连接和数据读写由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
在做蓝牙开发之前,最好先了解一些概念: 服务(services):蓝牙外设对外广播的必定会有一个服务,可能也有多个,服务下面包含着一些特征,服务可以理解成一个模块的窗口; 特征(characteristic):存在于服务下面的,一个服务下面也可以存在多个特征,特征可以理解成具体实现功能的窗口,一般特征都会有value,也就是特征值,特征是与外界交互的最小单位; UUID:可以理解成蓝牙上的唯一标识符(硬件上肯定不是这个意思,但是这样理解便于我们开发),为了区分不同的服务和特征,或者给服务和特征取名字,我们就用UUID来代表服务和特征.
蓝牙连接可以大致分为以下几个步骤 。
1.建立一个Central Manager实例进行蓝牙管理 2.搜索外围设备 3.连接外围设备 4.获得外围设备的服务 5.获得服务的特征 6.从外围设备读数据 7.给外围设备发送数据 其他:提醒 。
首先我们先导入系统的BLE的框架 #import <CoreBluetooth/CoreBluetooth.h> 。
必须遵守2个协议 <CBCentralManagerDelegate, CBPeripheralDelegate> 。
/** 中心管理者 */ @property (nonatomic, strong) CBCentralManager *cMgr,
/** 连接到的外设 */ @property (nonatomic, strong) CBPeripheral *peripheral,
1.建立一个Central Manager实例进行蓝牙管理 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
-(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 *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI; //找到外设
}
break
;
default
:
break
;
}
}
|
2.搜索外围设备 (我这里为了举例,采用了自己身边的一个手环) 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
// 发现外设后调用的方法
- (
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 = <CBPeripheral: 0x166668f0 identifier = C69010E7-EB75-E078-FFB4-421B4B951341, Name = "OBand-75", state = disconnected>, 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.连接外围设备 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
// 中心管理者连接外设成功
- (
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.获得服务的特征 。
1
2
3
4
5
6
7
8
9
10
|
// 发现外设服务里的特征的时候调用的代理方法(这个是比较重要的方法,你在这里可以通过事先知道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);
}
}
|
5.从外围设备读数据 。
1
2
3
4
5
6
7
8
|
// 更新特征的value的时候会调用 (凡是从蓝牙传过来的数据都要经过这个回调,简单的说这个方法就是你拿数据的唯一方法) 你可以判断是否
- (
void
)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
NSLog(@
"%s, line = %d"
, __FUNCTION__, __LINE__);
if
(characteristic == @
"你要的特征的UUID或者是你已经找到的特征"
) {
//characteristic.value就是你要的数据
}
}
|
6.给外围设备发送数据(也就是写入数据到蓝牙) 。
这个方法你可以放在button的响应里面,也可以在找到特征的时候就写入,具体看你业务需求怎么用啦 。
1
2
|
[self.peripherale writeValue:_batteryData forCharacteristic:self.characteristic type:CBCharacteristicWriteWithResponse];
//第一个参数是已连接的蓝牙设备 ;第二个参数是要写入到哪个特征; 第三个参数是通过此响应记录是否成功写入
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// 需要注意的是特征的属性是否支持写数据
- (
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,所以一个枚举可能对应多个类型,所以判断不能用 = ,而应该用包含&
}
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://blog.csdn.net/Mr_tangIT/article/details/80620969 。
最后此篇关于iOS蓝牙开发 蓝牙连接和数据读写的文章就讲到这里了,如果你想了解更多关于iOS蓝牙开发 蓝牙连接和数据读写的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我知道这个问题可能已经被问过,但我检查了所有这些,我认为我的情况有所不同(请友善)。所以我有两个数据集,第一个是测试数据集,第二个是我保存在数据框中的预测(预测值,这就是没有数据列的原因)。我想合并两
在 .loc 方法的帮助下,我根据同一数据框中另一列中的值来识别 Panda 数据框中某一列中的值。 下面给出了代码片段供您引用: var1 = output_df['Player'].loc[out
当我在 Windows 中使用 WinSCP 通过 Ubuntu 连接到 VMware 时,它提示: The server rejected SFTP connection, but it lis
我正在开发一个使用 xml web 服务的 android 应用程序。在 wi-fi 网络中连接时工作正常,但在 3G 网络中连接时失败(未找到 http 404)。 这不仅仅发生在设备中。为了进行测
我有一个XIB包含我的控件的文件,加载到 Interface Builder(Snow Leopard 上的 Xcode 4.0.2)中。 文件的所有者被设置为 someClassController
我在本地计算机上管理 MySQL 数据库,并通过运行以下程序通过 C 连接到它: #include #include #include int main(int argc, char** arg
我不知道为什么每次有人访问我网站上的页面时,都会打开一个与数据库的新连接。最终我到达了大约 300 并收到错误并且页面不再加载。我认为它应该工作的方式是,我将 maxIdle 设置为 30,这意味着
希望清理 NMEA GPS 中的 .txt 文件。我当前的代码如下。 deletes = ['$GPGGA', '$GPGSA', '$GPGSV', '$PSRF156', ] searchquer
我有一个 URL、一个用户名和一个密码。我想在 C# .Net WinForms 中建立 VPN 连接。 你能告诉我从哪里开始吗?任何第三方 API? 代码示例将受到高度赞赏... 最佳答案 您可以像
有没有更好的方法将字符串 vector 转换为字符 vector ,字符串之间的终止符为零。 因此,如果我有一个包含以下字符串的 vector "test","my","string",那么我想接收一
我正在编写一个库,它不断检查 android 设备的连接,并在设备连接、断开连接或互联网连接变慢时给出回调。 https://github.com/muddassir235/connection_ch
我的操作系统:Centos 7 + CLOUDLINUX 7.7当我尝试从服务器登录Mysql时 [root@server3 ~]# Mysql -u root -h localhost -P 330
我收到错误:Puma 发现此错误:无法打开到本地主机的 TCP 连接:9200(连接被拒绝 - 连接(2)用于“本地主机”端口 9200)(Faraday::ConnectionFailed)在我的
请给我一些解决以下错误的方法。 这是一个聊天应用....代码和错误如下:: conversations_controller.rb def create if Conversation.bet
我想将两个单元格中的数据连接到一个单元格中。我还想只组合那些具有相同 ID 的单元格。 任务 ID 名称 4355.2 参与者 4355.2 领袖 4462.1 在线 4462.1 快速 4597.1
我经常需要连接 TSQL 中的字段... 使用“+”运算符时 TSQL 强制您处理的两个问题是 Data Type Precedence和 NULL 值。 使用数据类型优先级,问题是转换错误。 1)
有没有在 iPad 或 iPhone 应用程序中使用 Facebook 连接。 这个想法是登录这个应用程序,然后能够看到我的哪些 facebook 用户也在使用该应用程序及其功能。 最佳答案 是的。
我在连接或打印字符串时遇到了一个奇怪的问题。我有一个 char * ,可以将其设置为字符串文字的几个值之一。 char *myStrLiteral = NULL; ... if(blah) myS
对于以下数据 - let $x := "Yahooooo !!!! Select one number - " let $y := 1 2 3 4 5 6 7 我想得到
我正在看 UDEMY for perl 的培训视频,但是视频不清晰,看起来有错误。 培训展示了如何使用以下示例连接 2 个字符串: #!usr/bin/perl print $str = "Hi";
我是一名优秀的程序员,十分优秀!