#import "ViewController.h"
#import <CoreBluetooth/CoreBluetooth.h> @interface ViewController ()<CBCentralManagerDelegate,CBPeripheralDelegate>
/// 中央管理者 -->管理设备的扫描 --连接
@property (nonatomic, strong) CBCentralManager *centralManager;
// 存储的设备
@property (nonatomic, strong) NSMutableArray *peripherals;
// 扫描到的设备
@property (nonatomic, strong) CBPeripheral *cbPeripheral;
// 文本
@property (weak, nonatomic) IBOutlet UITextView *peripheralText;
// 蓝牙状态
@property (nonatomic, assign) CBManagerState peripheralState; @end // 蓝牙4.0设备名
static NSString * const kBlePeripheralName = @"apple";
// 通知服务
static NSString * const kNotifyServerUUID = @"FFE0";
// 写服务
static NSString * const kWriteServerUUID = @"FFE1";
// 通知特征值
static NSString * const kNotifyCharacteristicUUID = @"FFE2";
// 写特征值
static NSString * const kWriteCharacteristicUUID = @"FFE1"; @implementation ViewController
- (NSMutableArray *)peripherals
{
if (!_peripherals) {
_peripherals = [NSMutableArray array];
}
return _peripherals;
} - (CBCentralManager *)centralManager
{
if (!_centralManager)
{
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
return _centralManager;
} // 222 扫描设备
- (IBAction)scanForPeripherals
{
[self.centralManager stopScan];
NSLog(@"扫描设备");
[self showMessage:@"扫描设备"];
if (self.peripheralState == CBManagerStatePoweredOn)
{
[self.centralManager scanForPeripheralsWithServices:nil options:nil];
}
} // 连接设备
- (IBAction)connectToPeripheral
{
if (self.cbPeripheral != nil)
{
NSLog(@"连接设备");
[self showMessage:@"连接设备"];
[self.centralManager connectPeripheral:self.cbPeripheral options:nil];
}
else
{
[self showMessage:@"无设备可连接"];
}
} // 清空设备
- (IBAction)clearPeripherals
{
NSLog(@"清空设备");
[self.peripherals removeAllObjects];
self.peripheralText.text = @"";
[self showMessage:@"清空设备"]; if (self.cbPeripheral != nil)
{
// 取消连接
NSLog(@"取消连接");
[self showMessage:@"取消连接"];
[self.centralManager cancelPeripheralConnection:self.cbPeripheral];
}
}
//
- (void)viewDidLoad {
[super viewDidLoad];
[self centralManager];
}
///
//只要中心管理者初始化 就会触发此代理方法 判断手机蓝牙状态 状态更新时调用
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
switch (central.state) {
case CBManagerStateUnknown:{
NSLog(@"为知状态");
self.peripheralState = central.state;
}
break;
case CBManagerStateResetting:
{
NSLog(@"重置状态");
self.peripheralState = central.state;
}
break;
case CBManagerStateUnsupported:
{
NSLog(@"不支持的状态");
self.peripheralState = central.state;
}
break;
case CBManagerStateUnauthorized:
{
NSLog(@"未授权的状态");
self.peripheralState = central.state;
}
break;
case CBManagerStatePoweredOff:
{
NSLog(@"关闭状态");
self.peripheralState = central.state;
}
break;
case CBManagerStatePoweredOn:
{
NSLog(@"开启状态-可用状态");
self.peripheralState = central.state;
// 链接成功开始扫描设备
[self scanForPeripherals];
NSLog(@"%ld",(long)self.peripheralState);
}
break;
default:
break;
}
}
/**
333扫描到设备 发现设备是开启状态后调用方法 @param central 中心管理者
@param peripheral 扫描到的设备
@param advertisementData 广告信息
@param RSSI 信号强度
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
{
[self showMessage:[NSString stringWithFormat:@"发现设备,设备名:%@",peripheral.name]];
// 设备数组中是否存在 该设备
if (![self.peripherals containsObject:peripheral])
{
[self.peripherals addObject:peripheral];
NSLog(@"%@",peripheral); [self showMessage:[NSString stringWithFormat:@"设备名:%@",peripheral.name]]; //最常用的场景是查找某一个前缀开头的设备
// if ([peripheral.name hasPrefix:@"JDY"] ) {
[self showMessage:@"开始连接"];
[self.centralManager connectPeripheral:peripheral options:nil];
// }
}
} /**
连接失败 @param central 中心管理者
@param peripheral 连接失败的设备
@param error 错误信息
*/ - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
[self showMessage:@"连接失败"];
if ([peripheral.name isEqualToString:kBlePeripheralName])
{
[self.centralManager connectPeripheral:peripheral options:nil];
}
} /**
连接断开 @param central 中心管理者
@param peripheral 连接断开的设备
@param error 错误信息
*/ - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
[self showMessage:@"断开连接"];
if ([peripheral.name isEqualToString:kBlePeripheralName])
{
[self.centralManager connectPeripheral:peripheral options:nil];
}
} /**
444连接成功 @param central 中心管理者
@param peripheral 连接成功的设备
*/
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@"连接设备:%@成功",peripheral.name);
// self.peripheralText.text = [NSString stringWithFormat:@"连接设备:%@成功",peripheral.name];
[self showMessage:[NSString stringWithFormat:@"连接设备:%@成功",peripheral.name]];
// 设备
self.cbPeripheral = peripheral;
// 设置设备的代理
peripheral.delegate = self;
// services:传入nil 代表扫描所有服务
[peripheral discoverServices:nil];
} /**
555扫描到服务 @param peripheral 服务对应的设备
@param error 扫描错误信息
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
// 遍历所有的服务
for (CBService *service in peripheral.services)
{
NSLog(@"服务:%@",service.UUID.UUIDString);
// 获取对应的服务
if ([service.UUID.UUIDString isEqualToString:kWriteServerUUID] || [service.UUID.UUIDString isEqualToString:kNotifyServerUUID])
{
// 根据服务去扫描特征
[peripheral discoverCharacteristics:nil forService:service];
}
}
} /**
666扫描到对应的特征 @param peripheral 设备
@param service 特征对应的服务
@param error 错误信息
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
// 遍历所有的特征
for (CBCharacteristic *characteristic in service.characteristics)
{ NSLog(@"特征值:%@",characteristic.UUID.UUIDString);
if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID])
{
// 写入数据 M_1_1000_\r
NSString *testString = [NSString stringWithFormat:@"%@",@"M_1_1000_\r"];
NSData *data = [testString dataUsingEncoding: NSUTF8StringEncoding]; // NSData *data = [self hexToBytes:testString];
// Byte byte[] = {0xf0, 0x3d, 0x3d, 0x5d,0x02,0xf7};
// NSData *data = [NSData dataWithBytes:byte length:6];
[self.cbPeripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
[self showMessage:@"写入特征值"]; // for (Byte i = 0x0; i < 0x73; i++)
// {
// Byte byte[] = {0xf0, 0x3d, 0x3d, i,
// 0x02,0xf7};
// NSData *data = [NSData dataWithBytes:byte length:6];
// [peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
// }
}
if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID])
{
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
}
} - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error;
{
//这个方法比较好,这个是你发数据到外设的某一个特征值上面,并且响应的类型是 CBCharacteristicWriteWithResponse ,上面的官方文档也有,如果确定发送到外设了,就会给你一个回应,当然,这个也是要看外设那边的特征值UUID的属性是怎么设置的,看官方文档,人家已经说了,条件是,特征值UUID的属性:CBCharacteristicWriteWithResponse
if (!error) {
NSLog(@"说明发送成功,characteristic.uuid为:%@ 发送为%@",[characteristic.UUID UUIDString],characteristic.value);
Byte byte2[] = {0xf0, 0x3d, 0x3d, 0x5d,0x02,0xf7};
NSData* data2 = [[NSData alloc] initWithBytes:byte2 length:];
if ([characteristic.value isEqualToData:data2]) {
NSLog(@"说明发送成功,characteristic.uuid为:%@ 发送为%@",[characteristic.UUID UUIDString],characteristic.value);
}
}else{
NSLog(@"发送失败了啊!characteristic.uuid为:%@ 原因:%@",[characteristic.UUID UUIDString],error); }
//调用下面的方法后 会调用到代理的- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
[peripheral readValueForCharacteristic:characteristic];
} /**
根据特征读到数据 @param peripheral 读取到数据对应的设备
@param characteristic 特征
@param error 错误信息
*/
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error
{
if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID])
{
NSData *data = characteristic.value;
NSLog(@"%@",data);
// 2017-04-25 12:34:41.876974+0800 蓝牙4.0Demo[1745:346611] <9f5436>
// 2017-04-25 12:34:41.983016+0800 蓝牙4.0Demo[1745:346611] <8f5440>
// 2017-04-25 12:34:42.154821+0800 蓝牙4.0Demo[1745:346611] <9f5649>
// 2017-04-25 12:34:42.239481+0800 蓝牙4.0Demo[1745:346611] <8f5640>
}
} - (void)showMessage:(NSString *)message
{
self.peripheralText.text = [self.peripheralText.text stringByAppendingFormat:@"%@\n",message];
[self.peripheralText scrollRectToVisible:CGRectMake(, self.peripheralText.contentSize.height -, self.peripheralText.contentSize.width, ) animated:YES];
} // 把string类型转成byte 之后转成data
-(NSData*)hexToBytes:(NSString *)string{
NSMutableData* data = [[NSMutableData alloc]init];
int idx;
for (idx = ; idx+ <= string.length; idx +=) {
NSRange range = NSMakeRange(idx, );
NSString* hexStr = [string substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
[data appendBytes:&intValue length:];
}
return data;
} //data转string
- (NSString *)hexStringFromData:(NSData*)data{
return [[[[NSString stringWithFormat:@"%@",data]
stringByReplacingOccurrencesOfString: @"<" withString: @""]
stringByReplacingOccurrencesOfString: @">" withString: @""]
stringByReplacingOccurrencesOfString: @" " withString: @""];
} @end

蓝牙硬件交互数据传输Demo的更多相关文章

  1. Android系统编程入门系列之硬件交互——通信硬件USB

    在硬件交互的首篇对设备硬件的分类中,互联通信系列硬件主要用来与其他设备进行数据交互.从本文开始,将重点介绍该系列相关硬件. 互联通信系列硬件 根据硬件的可通信距离,由近及远分为USB.NFC.蓝牙.W ...

  2. Android系统编程入门系列之硬件交互——通信硬件Bluetooth

    通信硬件NFC的文章,虽然可以在Android系统中通过非直接接触的形式与支持NFC硬件的设备通信,但是也只能交互一些简短的标签内容,对大量的持续性数据,却并不能很好的支持.因此针对这个弊端,可以考虑 ...

  3. 如何使用AEditor制作一个简单的H5交互页demo

    转载自:http://www.alloyteam.com/2015/06/h5-jiao-hu-ye-bian-ji-qi-aeditor-jie-shao/ 本教程演示如何使用AEditor制作一个 ...

  4. Android5.0(Lollipop) BLE蓝牙4.0+浅析demo连接(三)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23363591来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...

  5. Android系统编程入门系列之硬件交互——多媒体摄像头

    多媒体系列硬件 多媒体包括图片.动画.音频.视频,这些多媒体素材的采集(输入)主要依靠摄像头和麦克风等硬件设备转化为基础数据,而他们的播放渲染(输出),则需要依靠具有相关功能的编解码软件.当然随着硬件 ...

  6. Android通过JNI实现与C语言的串口通讯操作蓝牙硬件模块

    一直想写一份技术文档,但因为自感能力有限而无从下笔,近期做了个关于Android平台下实现与C语言的通讯来操作蓝牙模块的项目,中间碰到了很多问题,也在网上查了很多资料,在完毕主要功能后.也有一些人在网 ...

  7. Android系统编程入门系列之硬件交互——传感器

    到目前为止,关于应用程序与用户之间的相关内容便比较肤浅的大致介绍完毕.而在整个系统架构中,应用程序与用户之间的交互,犹如参天大树上的枝干和树叶,交互起来五彩缤纷,但使整个生态系统保持生命力的核心,在于 ...

  8. 使用Vue和thrift建立前后端交互的demo

    初识thrift thrift 是 facebook 于2007年开发的一款跨平台 RPC(Remote Procedure Call) 软件框架, 它可以在多种平台上进行无缝交互,数据传输使用二进制 ...

  9. 10分钟完成一个最最简单的BLE蓝牙接收数据的DEMO

    这两天在研究蓝牙,网上有关蓝牙的内容非常有限,Github上的蓝牙框架也很少很复杂,为此我特地写了一个最最简单的DEMO,实现BLE蓝牙接收数据的问题, 不需要什么特定的UUID, 不需要什么断开重连 ...

随机推荐

  1. Exam 70-762 Developing SQL Databases

    这个考试还是很有用的,教了很多有用的东西,不错,虽然考试需要很多钱,不过值的尝试.虽然用了sql server 这么多年但是对于事务.多并发的优化还是处于小学生的水平,通过这次考试争取让自己提一个档次 ...

  2. ubuntu:undefined reference to `snd_pcm_open'

    这几天在做一个局域网的对讲机和广播系统. 需要用到alsa的库来进行音频采集和播放. 但是在编译程序的时候有个比较奇怪的问题. undefined reference to `snd_pcm_open ...

  3. 写给精明Java开发者的测试技巧

    我们都会为我们的代码编写测试,不是吗?毫无疑问,我知道这个问题的答案可能会从 “当然,但你知道怎样才能避免写测试吗?” 到 “必须的!我爱测试”都有.接下来我会给你几个小建议,它们可以让你编写测试变得 ...

  4. (转)Java经典设计模式(3):十一种行为型模式(附实例和详解)

    原文出处: 小宝鸽 Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:J ...

  5. WebRTC学习

    1.     WebRTC学习 1.1   WebRTC现状 本人最早接触WebRTC是在2011年底,那时Google已经在Android源码中加入了webrtc源码,放在/external/web ...

  6. 跨域传输信息postMessage

    widnow.postMessage()方法允许安全的跨域传输. Syntax otherWindow.postMessage(message, targetOrigin, [transfer]); ...

  7. 火狐浏览器安装VULTR笔记

    1.购买一台vultr服务器, 支持支付宝扫码支付,直接美刀转人民币实时结算:优先选日本的,然后美国的; 购买服务器步骤: Server Location: Tokyo Japan Server Ty ...

  8. C++之const类成员变量,const成员函数

    const修饰类的成员函数 const修饰变量一般有两种方式:const T *a,或者 T const *a,这两者都是一样的,主要看const位于*的左边还是右边,这里不再赘述,主要来看一下当co ...

  9. bzoj 2962 序列操作——线段树(卷积?)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2962 如果 _,_,_,…… 变成了 (_+k),(_+k),(_+k),…… ,计算就是在 ...

  10. Day03:集合、文件处理和函数基础

    上节课复习:    1.总结        可变/不可变:            可变类型:list,dict            不可变类型:int,float,str,tuple         ...