一:IOS Ble蓝牙设备自动链接蓝牙的功能需求
二: 主要分为以下几个逻辑点:
1.把主蓝牙列表MAC地址存储到详情界面
2.把链接成功的服务(peripheral)列表调用如:self.deviceModel.peripheral = peripheral;
3.当设备关闭断开的时候,进行时间的运算,判断处理是否进行自动链接
1.设备的蓝牙列表总界面
DeviceViewController.h
#import
#import "BaseTableViewController.h"
#import "DeviceCell.h"
#import "DeviceView.h"
#import "DeviceModel.h"
#import "BlueUtil.h"
#import "CommonDefaults.h"
#import "BTAlertController.h"
#import "BlueTempViewController.h"
#import "OtaViewController.h"
//#import "WJProgress.h"
@interface DeviceViewController : BaseTableViewController
//空白布局文件
@property(strong,nonatomic) DeviceView *deviceView;
//蓝牙列表
@property (nonatomic,strong) NSMutableArray *deviceList;
@property(strong,nonatomic) DeviceModel *deviceModel;
// 扫描到的外围设备
//@property (nonatomic,strong ) NSMutableArray *peripheralList;
@property (nonatomic,strong ) NSMutableArray *peripheralList;
//获取设备定时器
@property(strong,nonatomic) NSTimer *deviceTimer;
@property(strong,nonatomic) BlueUtil *bleUtil;
@property(strong,nonatomic) CommonDefaults *cmDefaults;
@end
二:蓝牙列表总界面
DeviceViewController.m
//
// DeviceViewController.m
// BWProject
//
// Created by rnd on 2018/6/28.
// Copyright © 2018年 Radiance Instruments Ltd. All rights reserved.
//
#import "DeviceViewController.h"
//蓝牙的的两个代理
@interface DeviceViewController ()
@end
@implementation DeviceViewController
- (void)viewDidLoad {
[super viewDidLoad];
//定义函数initData
[self initData];
}
//导航栏中间对齐
- (void)customContentView{
UIColor *commonBlue = [self.commonUtil stringToColor:@"#333333"];
[self.navigationController.navigationBar setBarTintColor:commonBlue];
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
self.navigationItem.title = @"BLE";
//创建下啦刷新
NSString *dropscan = NSLocalizedString(@"dropscan", nil);
UIRefreshControl *rc = [[UIRefreshControl alloc] init];
rc.attributedTitle = [[NSAttributedString alloc] initWithString:dropscan];
[rc addTarget:self action:@selector(redreshTableView) forControlEvents:UIControlEventValueChanged];
self.refreshControl = rc;
}
-(void)initData{
//蓝牙设备类
self.bleUtil = [BlueUtil sharedManager];
[self getDeviceModel];
[self getDeviceList];
[self getPeripheralList];
self.tableView.delegate = self;
self.tableView.dataSource = self;
//小技巧,用了之后不会出现多余的Cell
UIView *view = [[UIView alloc] init];
self.tableView.tableFooterView = view;
//设备定时器时间,如果等于null就每隔2秒钟扫描一次
if(_deviceTimer==nil){
_deviceTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(deviceTime) userInfo:nil repeats:YES];
}
}
/*
程序加载的时候调用
*/
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
if(_deviceList.count>0&&_peripheralList.count>0){
//可变数组对象
[_deviceList removeAllObjects];
[_peripheralList removeAllObjects];
//重新加载数据
[self.tableView reloadData];
}
if (self.refreshControl.refreshing) {
//TODO: 已经在刷新数据了
//NSLog(@"12233");
} else {
NSLog(@"y is %f",self.tableView.contentOffset.y);
if (self.tableView.contentOffset.y == -64.0) {
[UIView animateWithDuration:0.25
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^(void){
self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
} completion:^(BOOL finished){
[self.refreshControl beginRefreshing];
[self.refreshControl sendActionsForControlEvents:UIControlEventValueChanged];
}];
}
}
}
//设备布局文件
-(DeviceView *)getDeviceView{
if(self.deviceView==nil){
self.deviceView = [[DeviceView alloc] init];
}
return self.deviceView;
}
//设备蓝牙列表初始化
-(NSMutableArray*)getDeviceList{
if(self.deviceList==nil){
self.deviceList=[NSMutableArray array];
}
return self.deviceList;
}
//外围蓝牙设备初始化
-(NSMutableArray*)getPeripheralList{
if(self.peripheralList==nil){
self.peripheralList = [NSMutableArray array];
}
return self.peripheralList;
}
-(DeviceModel*)getDeviceModel{
if(self.deviceModel==nil){
self.deviceModel = [[DeviceModel alloc] init];
}
return self.deviceModel;
}
//获取设备连接的数据
-(void)deviceTime{
self.deviceList = [self.bleUtil getDeviceLists];
self.peripheralList = [self.bleUtil getPeriperalLists];
if(self.deviceList.count>0){
[self.tableView reloadData];
}
}
//tableview的行数
#pragma mark tableView
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.deviceList.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifiter = @"DeviceCellIdentifiter";
DeviceCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifiter];
if (cell == nil) {
cell = [[DeviceCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifiter];
}
//蓝牙列表行数是否大于0
if([self.deviceList count]>0){
NSUInteger row = [indexPath row];
if(row0){
NSString *contentTips = @"Connect Tips";
NSString *multiple = @"Cancel";
NSString *single = @"Connect";
//该方法响应列表中行的点击事件
NSString *bleSelected=@"";
//indexPath.row得到选中的行号,提取出在数组中的内容。
BTAlertController *alertController = [BTAlertController alertControllerWithTitle:contentTips message:bleSelected preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *noAction = [UIAlertAction actionWithTitle:multiple style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
}];
UIAlertAction *yesAction = [UIAlertAction actionWithTitle:single style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
//连接第一个扫描到的外设
NSUInteger row = [indexPath row];
int rows =(int)row;
self.deviceModel = [self.deviceList objectAtIndex:indexPath.row];
//[self.cmDefaults saveMacAdder:self.deviceModel.deviceAddre];
//存储地址
[[CommonDefaults shared] saveMacAdder:self.deviceModel.deviceAddre];
//如果是为OTA的话
if([self.deviceModel.deviceName containsString:@"update"]){
[[BlueUtil sharedManager] contentBlue:rows];
OtaViewController *otaView = [[OtaViewController alloc] init];
otaView.title = @"OTA UpGrade";
[self.navigationController pushViewController:otaView animated:YES];
}else{
//连接蓝牙
[[BlueUtil sharedManager] contentBlue:rows];
BlueTempViewController *bluetempView = [[BlueTempViewController alloc] init];
bluetempView.title = @"Temperature";
[self.navigationController pushViewController:bluetempView animated:YES];
}
}];
[alertController addAction:noAction];
[alertController addAction:yesAction];
[self presentViewController:alertController animated:true completion:nil];
}
}
//定义列的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 90;
}
//读取刷新TableView
-(void)redreshTableView{
if(self.refreshControl.refreshing){
self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refresh"];
if(_deviceList!=nil&&_deviceList.count>0){
[_deviceList removeAllObjects];
}
if(_peripheralList.count>0&&_peripheralList!=nil){
[_peripheralList removeAllObjects];
}
//扫描蓝牙
[self.bleUtil startScan];
[self.refreshControl endRefreshing];
self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Down Refresh"];
//扫描
[self.tableView reloadData];
}
}
//用完之后需要关闭掉
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
[[BlueUtil sharedManager] stopScan];
}
@end
三:蓝牙服务界面:
#import
#import
#import "DeviceModel.h"
#import "Constants.h"
#import "BlueTempModel.h"
#import "BWTmpDB.h"
#import "TmpModel.h"
#import "MBProgressHUD.h"
#import "CommonUtil.h"
@interface BlueUtil : NSObject
+ (id)sharedManager;
//颜色转换
@property(nonatomic,strong) CommonUtil *comUtil;
//蓝牙的设备搜索显示在列表中
@property (nonatomic, strong) NSMutableArray *periperals;// 扫描到的外围设备
//连接peripheral
@property(nonatomic,strong) CBPeripheral *peripheral;
//中心管理者
@property (nonatomic, strong) CBCentralManager *centerManager;
//设备列表
@property(nonatomic,strong) NSMutableArray *deviceList;
@property(nonatomic,strong) BlueTempModel *blueTempModel;
@property(strong,nonatomic) NSMutableArray *tempList;
//所有的charater
@property(nonatomic,strong)CBCharacteristic *readtempcharaterone;
//读取高低温报警值
@property(nonatomic,strong)CBCharacteristic *readalarmcharaterone;
@property(nonatomic,strong)CBCharacteristic *readalarmcharatertwo;
@property(nonatomic,strong)CBCharacteristic *readalarmcharaterthree;
@property(nonatomic,strong)CBCharacteristic *readalarmcharaterfour;
//OTA
@property(nonatomic,strong)CBCharacteristic *sendotacharateristic;
//发送数据进行OTA升级
@property(nonatomic,strong) CBCharacteristic *sendupcharateristic;
//读取单位
@property(nonatomic,strong)CBCharacteristic *readtempunit;
//报警静音
@property(nonatomic,strong) CBCharacteristic *sendmuteswitch;
//自动链接
@property(nonatomic,strong) CBCharacteristic *sendzidswitch;
//设备信息
@property(nonatomic,strong)CBCharacteristic *readdeviceinfo;
//设置路由器账号密码
@property(nonatomic,strong)CBCharacteristic *sendsetarouter;
//传输时间间隔
@property(nonatomic,strong) CBCharacteristic *sendupdatetime;
//设备名字
@property(nonatomic,strong) CBCharacteristic *senddevicename;
//设置服务器地址端口
@property(nonatomic,strong) CBCharacteristic *sendsevername;
//设备
@property (nonatomic,strong) DeviceModel *deviceModel;
//dalao
@property(strong,nonatomic) MBProgressHUD *hud;
-(NSMutableArray *)getDeviceLists;
-(NSMutableArray *)getPeriperalLists;
-(void)contentBlue:(int) row;
-(void)startScan;
-(void)stopScan;
//断开蓝牙
-(void)disContentBle;
-(void)writeUpdateOTA:(NSString*)value;
-(void)writeBlueOTA:(NSString *)value;
-(void)wirteBlueOTAData:(NSData *)value;
//写入温度单位数据
-(void)writeUnitData:(NSString *)value;
//写入静音开关数据
-(void)writeMuteData:(NSString*)value;
//写入自动链接列表
-(void)contentAutoBlue:(CBPeripheral*)peripheral;
-(void)writeAlarmData:(NSString *)value codes:(NSString *)code;
//写入arouter值
-(void)sendARouterData:(NSString*)value;
//写入更新时间值
-(void)sendUpdateData:(NSString*)value;
//写入设备名字
-(void)sendNameData:(NSString*)value;
//写入服务器地址端口值
-(void)sendIPPortData:(NSString*)value;
@end
BlueUtil.m
#import "BlueUtil.h"
@interface BlueUtil()
@end
@implementation BlueUtil
+ (id)sharedManager {
static BlueUtil *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
-(id)init{
self = [super init];
if(self){
[self getCBCentralManager];//中心管理者
self.centerManager.delegate = self;
[self getPeriperals];//链接
[self getDeviceList];
[self getDeviceModel];
//[self getBlueTempModel];
[self gettempList];
[self getComUtil];
}
return self;
}
-(CommonUtil *)getComUtil{
if(self.comUtil==nil){
self.comUtil = [[CommonUtil alloc] init];
}
return self.comUtil;
}
//管理中心者
-(CBCentralManager*)getCBCentralManager{
if(self.centerManager==nil){
self.centerManager = [[CBCentralManager alloc] init];
}
return self.centerManager;
}
//链接的蓝牙
-(NSMutableArray *)getPeriperals{
if(self.periperals==nil){
self.periperals = [NSMutableArray array];
}
return self.periperals;
}
//获取设备列表
-(NSMutableArray *)getDeviceList{
if(self.deviceList==nil){
self.deviceList = [NSMutableArray array];
}
return self.deviceList;
}
//获取设备名称,地址样式
-(DeviceModel*)getDeviceModel{
if(self.deviceModel==nil){
self.deviceModel = [[DeviceModel alloc] init];
}
return self.deviceModel;
}
//获取最大,最小温度状态,报警状态
-(BlueTempModel *)getBlueTempModel{
if(self.blueTempModel==nil){
self.blueTempModel = [[BlueTempModel alloc] init];
}
return self.blueTempModel;
}
//获取实时温度的列表数据
-(NSMutableArray *)gettempList{
if(self.tempList==nil){
self.tempList = [NSMutableArray array];
}
return self.tempList;
}
/*
* 获取设备的list
*/
-(NSMutableArray *)getDeviceLists{
return self.deviceList;
}
/*
* 获取设备的periperals
*/
-(NSMutableArray *)getPeriperalLists{
return self.periperals;
}
#pragma 蓝牙代理 ---
//程序运行后,会自动调用的检查蓝牙的方法 并扫描蓝牙的方法
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
if (@available(iOS 10.0, *)) {
if ([central state] == CBManagerStatePoweredOff) {
NSLog(@"CoreBluetooth BLE hardware is powered off");
}
else if ([central state] == CBManagerStatePoweredOn) {
NSLog(@"CoreBluetooth BLE hardware is powered on and ready");
[self startScan];
}
else if ([central state] == CBManagerStateUnauthorized) {
NSLog(@"CoreBluetooth BLE state is unauthorized");
}
else if ([central state] == CBManagerStateUnknown) {
NSLog(@"CoreBluetooth BLE state is unknown");
}
else if ([central state] == CBManagerStateUnsupported) {
NSLog(@"CoreBluetooth BLE hardware is unsupported on this platform");
}
} else {
// Fallback on earlier versions
}
}
/*
* 程序运行的时候开始扫描
*/
-(void)startScan{
if(self.periperals.count>0){
[self.periperals removeAllObjects];
}
if(self.deviceList.count>0){
[self.deviceList removeAllObjects];
}
//利用中心设备扫描外部设备
[self.centerManager scanForPeripheralsWithServices:nil options:nil];
}
/*
* 停止扫描
*/
-(void)stopScan{
[self.centerManager stopScan];
}
/*
* 连接蓝牙设备给外部调用的方法
* 传入的是相对应的行数
*/
-(void)contentBlue:(int) row{
[self.centerManager connectPeripheral:self.periperals[row] options:nil];
}
//断开蓝牙
-(void)disContentBle{
//关键的断开蓝牙 通知也要停止掉
if(self.peripheral!=nil){
if(self.readtempcharaterone!=nil){
[self.peripheral setNotifyValue:NO forCharacteristic:self.readtempcharaterone];
}
[self disconnectPeripheral:self.peripheral];
}
}
//链接外设的列表
- (void) disconnectPeripheral:(CBPeripheral*)peripheral
{
[self.centerManager cancelPeripheralConnection:peripheral];
}
//中心设备获取外围设备的列表
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSS{
//NSString *deviceName;
if (![self.periperals containsObject:peripheral]){
NSArray *keys = [advertisementData allKeys];
for(int i=0;i<[keys count];i++){
id key = [keys objectAtIndex:i];
NSString *keyName = (NSString *) key;
NSData *value = [advertisementData objectForKey: key];
if([keyName isEqualToString:@"kCBAdvDataLocalName"]){
NSString *aStr= (NSString*)value;
NSLog(@"astr is %@",aStr);
self.deviceModel = [[DeviceModel alloc] init];
self.deviceModel.deviceName = aStr;
self.deviceModel.peripheral = peripheral;
[self.periperals addObject:peripheral];
[self.deviceList addObject:self.deviceModel];
}
if([keyName isEqualToString:@"kCBAdvDataManufacturerData"]){
NSLog(@"value is %@",value);
NSString *result = [self convertDataToHexStr:value];
NSLog(@"reslut is %@",result);
if(result!=nil&&result.length>4){
NSString *d = [result substringFromIndex:4];
NSLog(@"D IS %@",d);
NSString *upper = [result uppercaseString];
self.deviceModel.deviceAddre = [NSString stringWithFormat:@"S/N:%@",upper];
}
}
}
}
}
//连接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
if(peripheral!=nil){
//停止扫描 这个用于自动连接的时候
[self.centerManager stopScan];
peripheral.delegate = self;
//再去扫描服务
[peripheral discoverServices:nil];
}
}
//连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
NSLog(@"连接失败,失败原因:%@",error);
NSString *disContentBlue = @"discontentblue";
NSDictionary *blueDiscontent = [NSDictionary dictionaryWithObject:disContentBlue forKey:@"disconnect"];
//发送广播 连接失败
[[NSNotificationCenter defaultCenter] postNotificationName:@"disNofiction" object:nil userInfo:blueDiscontent];
}
//断开连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
NSLog(@"断开连接22");
NSString *disContentBlue = @"discontentblue";
NSDictionary *blueDiscontent = [NSDictionary dictionaryWithObject:disContentBlue forKey:@"disconnect"];
//发送广播 连接失败
[self.hud hideAnimated:YES];
[[NSNotificationCenter defaultCenter] postNotificationName:@"disNofiction" object:nil userInfo:blueDiscontent];
}
#pragma mark - CBPeripheralDelegate
//只要扫描到服务就会调用,其中的外设就是服务所在的外设
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
if (error){
NSLog(@"扫描服务出现错误,错误原因:%@",error);
}else{
//获取外设中所扫描到的服务
for (CBService *service in peripheral.services){
//把所有的service打印出来
//从需要的服务中查找需要的特征
//从peripheral的services中扫描特征
[peripheral discoverCharacteristics:nil forService:service];
}
}
}
//只要扫描到特征就会调用,其中的外设和服务就是特征所在的外设和服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(nonnull CBService *)service error:(nullable NSError *)error{
if (error){
NSLog(@"扫描特征出现错误,错误原因:%@",error);
}else{
for (CBCharacteristic *characteristic in service.characteristics){
NSLog(@"characteristic is %@",characteristic.UUID);
//发送数据到OTA
if([characteristic.UUID isEqual:BW_PROJECT_UPDATE_OTA]){
self.peripheral = peripheral;
self.sendupcharateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//OTA升级
else if([characteristic.UUID isEqual:BW_PROJECT_OTA_DATA]){
self.peripheral = peripheral;
self.sendotacharateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//所有探头的温度数据
else if([characteristic.UUID isEqual:BW_PROJECT_TEMP_ONE]){
self.readtempcharaterone = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//第一个报警值
else if([characteristic.UUID isEqual:BW_PROJECT_ALARM_ONE]){
self.readalarmcharaterone = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//第二个报警值
else if([characteristic.UUID isEqual:BW_PROJECT_ALARM_TWO]){
self.readalarmcharatertwo = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//第三个报警值
else if([characteristic.UUID isEqual:BW_PROJECT_ALARM_THREE]){
self.readalarmcharaterthree = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//第四个报警值
else if([characteristic.UUID isEqual:BW_PROJECT_ALARM_FOUR]){
self.readalarmcharaterfour = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//温度单位
else if([characteristic.UUID isEqual:BW_PROJECT_TEMP_UNIT]){
self.readtempunit = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//报警静音 此过程只能发送数据 并无读取数据的功能
else if([characteristic.UUID isEqual:BW_PROJECT_MUTE_SWITCH]){
self.sendmuteswitch = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//设备信息
else if([characteristic.UUID isEqual:BW_PROJECT_DEVICE_INFO])
{
self.readdeviceinfo = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//设置路由器
else if([characteristic.UUID isEqual:BW_PROJECT_AROUTER_DATA]){
self.sendsetarouter = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//发送时间间隔
else if([characteristic.UUID isEqual:BW_PROJECT_UPDATE_TIME]){
self.sendupdatetime = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//修改设备名字
else if([characteristic.UUID isEqual:BW_PROJECT_DEVICE_NAME]){
self.senddevicename = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//修改设备IP和端口号
else if([characteristic.UUID isEqual:BW_PROJECT_ADDERPORT_DATA]){
self.sendsevername = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
}
}
}
//设置通知
-(void)notifyCharacteristic:(CBPeripheral *)peripheral
characteristic:(CBCharacteristic *)characteristic{
//设置通知,数据通知会进入:didUpdateValueForCharacteristic方法
NSLog(@"发现通知!");
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
[self.centerManager stopScan];
}
//取消通知
-(void)cancelNotifyCharacteristic:(CBPeripheral *)peripheral
characteristic:(CBCharacteristic *)characteristic{
[peripheral setNotifyValue:NO forCharacteristic:characteristic];
}
//接受解析数据
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{ //第一个探头
if(characteristic==self.readtempcharaterone){
NSString *tempdata = [self getTempTMWData:characteristic];
NSArray *data = [tempdata componentsSeparatedByString:@","];
NSDictionary *tempDict = [NSDictionary dictionaryWithObject:data forKey:@"tempData"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"tempNofiction" object:nil userInfo:tempDict];
}
else if(characteristic==self.readalarmcharaterone){
NSString *alarmdata = [self getTempTMWData:characteristic];
if(alarmdata!=nil){
NSArray *data = [alarmdata componentsSeparatedByString:@","];
NSDictionary *alarmDict = [NSDictionary dictionaryWithObject:data forKey:@"alarmDataOne"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"alarmNofictionOne" object:nil userInfo:alarmDict];
}
}
else if(characteristic==self.readalarmcharatertwo){
NSString *alarmdata = [self getTempTMWData:characteristic];
if(alarmdata!=nil){
NSArray *data = [alarmdata componentsSeparatedByString:@","];
NSDictionary *alarmDict = [NSDictionary dictionaryWithObject:data forKey:@"alarmDataTwo"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"alarmNofictionTwo" object:nil userInfo:alarmDict];
}
}
else if(characteristic==self.readalarmcharaterthree){
NSString *alarmdata = [self getTempTMWData:characteristic];
if(alarmdata!=nil){
NSArray *data = [alarmdata componentsSeparatedByString:@","];
NSDictionary *alarmDict = [NSDictionary dictionaryWithObject:data forKey:@"alarmDataThree"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"alarmNofictionThree" object:nil userInfo:alarmDict];
}
}
else if(characteristic==self.readalarmcharaterfour){
NSString *alarmdata = [self getTempTMWData:characteristic];
if(alarmdata!=nil){
NSArray *data = [alarmdata componentsSeparatedByString:@","];
NSDictionary *alarmDict = [NSDictionary dictionaryWithObject:data forKey:@"alarmDataFour"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"alarmNofictionFour" object:nil userInfo:alarmDict];
}
}
//如果读取到温度的单位
else if(characteristic==self.readtempunit){
NSString *tempunit = [self getTempTMWData:characteristic];//1
NSDictionary *tempDict = [NSDictionary dictionaryWithObject:tempunit forKey:@"tempUnit"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"tempUnitNofiction" object:nil userInfo:tempDict];
}
//读取设备信息
else if(characteristic==self.readdeviceinfo){
NSString *deviceinfo = [self getTempTMWData:characteristic];
if(deviceinfo!=nil){
NSArray *data = [deviceinfo componentsSeparatedByString:@","];
if([data count]>0){
if([data count]>4){
NSLog(@"astr is %@",data[4]);
}
}
NSDictionary *deviceinfoDict = [NSDictionary dictionaryWithObject:data forKey:@"deviceInfo"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"deviceInfoNofiction" object:nil userInfo:deviceinfoDict];
}
}
//OTA升级的时候
else if(characteristic==self.sendotacharateristic){
//接受数据处理
NSString *data = [self getOTAData:characteristic];
if(data!=nil){
//发送所有数据 要在清单中注册该广播
NSDictionary *otaDict = [NSDictionary dictionaryWithObject:data forKey:@"otaData"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"otaNofiction" object:nil userInfo:otaDict];
}
}
}
-(NSString *)getOTAData:(CBCharacteristic *)characteristic{
NSData *data = characteristic.value;
return [self convertDataToHexStr:data];
}
-(NSString *)convertDataToHexStr:(NSData *)data
{
if (!data || [data length] == 0) {
return @"";
}
NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
[data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
unsigned char *dataBytes = (unsigned char*)bytes;
for (NSInteger i = 0; i < byteRange.length; i++) {
NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
if ([hexStr length] == 2) {
[string appendString:hexStr];
} else {
[string appendFormat:@"0%@", hexStr];
}
}
}];
return string;
}
//解析温度数据
-(NSString *)getTempTMWData:(CBCharacteristic *)characteristic{
NSData *data = characteristic.value;
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
/*
写入数据区块
*/
-(void)writeUpdateOTA:(NSString*)value{
if(self.sendupcharateristic!=nil){
NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"data is:%@",data);
[self writeOTA:data forCharacteristic:self.sendupcharateristic];
}
}
-(void)writeBlueOTA:(NSString *)value{
NSMutableData *data = [self.comUtil dataFromHexString:[value stringByReplacingOccurrencesOfString:@"0x" withString:@""]];
NSLog(@"data is:%@",data);
[self writeOTA:data forCharacteristic:self.sendotacharateristic];
}
-(void)wirteBlueOTAData:(NSData *)value{
[self writeOTA:value forCharacteristic:self.sendotacharateristic];
}
//写入报警值
-(void)writeAlarmData:(NSString *)value codes:(NSString *)code{
if([code isEqual:@"one"]){
if(self.readalarmcharaterone!=nil){
[self writeTempData:value forCharacteristic:self.readalarmcharaterone];
}
}else if([code isEqual:@"two"]){
if(self.readalarmcharatertwo!=nil){
[self writeTempData:value forCharacteristic:self.readalarmcharatertwo];
}
}else if([code isEqual:@"three"]){
if(self.readalarmcharaterthree!=nil){
[self writeTempData:value forCharacteristic:self.readalarmcharaterthree];
}
}else if([code isEqual:@"four"]){
if(self.readalarmcharaterfour!=nil){
[self writeTempData:value forCharacteristic:self.readalarmcharaterfour];
}
}
}
//写入温度单位数据
-(void)writeUnitData:(NSString *)value{
if(self.readtempunit!=nil){
[self writeTempData:value forCharacteristic:self.readtempunit];
}
}
//写入静音开关数据
-(void)writeMuteData:(NSString*)value{
if(self.sendmuteswitch!=nil){
[self writeTempData:value forCharacteristic:self.sendmuteswitch];
}
}
//写入Arouter值
-(void)sendARouterData:(NSString*)value{
if(self.sendsetarouter!=nil){
[self writeTempData:value forCharacteristic:self.sendsetarouter];
}
}
//写入更新时间值
-(void)sendUpdateData:(NSString*)value{
if(self.sendupdatetime!=nil){
[self writeTempData:value forCharacteristic:self.sendupdatetime];
}
}
//写入DeviceName值
-(void)sendNameData:(NSString*)value{
if(self.senddevicename!=nil){
[self writeTempData:value forCharacteristic:self.senddevicename];
}
}
//
//写入IP/PORT值
-(void)sendIPPortData:(NSString*)value{
if(self.sendsevername!=nil){
[self writeTempData:value forCharacteristic:self.sendsevername];
}
}
//写入自动链接列表数据
-(void)contentAutoBlue:(CBPeripheral*)peripheral{
[self.centerManager connectPeripheral:peripheral options:nil];
}
//写入数据
-(void)writeTempData:(NSString *)value forCharacteristic:(CBCharacteristic *)characteristic
{
NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
if(characteristic.properties & CBCharacteristicPropertyWriteWithoutResponse)
{
[self.peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
}else
{
[self.peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
//写入OTA的区块
-(void)writeOTA:(NSData *)value forCharacteristic:(CBCharacteristic *)characteristic
{
//is no write bluetooth data
if(self.sendotacharateristic.properties & CBCharacteristicPropertyWriteWithoutResponse)
{
//send phone on bluetooth data
[self.peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
}else
{
[self.peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
NSLog(@"已经向外设%@的特征值%@写入数据",_peripheral.name,characteristic.description);
}
@end
四:蓝牙详情界面:
BlueTempViewController.h
#import
#import "BaseViewController.h"
#import "DeviceViewController.h"
#import
#import "BlueTempCell.h"
#import "BlueTempView.h"
#import "BlueTempModel.h"
#import "BlueUtil.h"
#import "BleChartController.h"
#import "MBProgressHUD.h"
#import "SettingController.h"
#import "CommonDefaults.h"
#import "AFNetReqest.h"
#import "Download.h"
#import
@protocol DownloadModelDelegate
@end
@interface BlueTempViewController : BaseViewController
//@property (nonatomic, strong) NSMutableArray *periperals;// 扫描到的外围设备
@property(strong,nonatomic) CommonDefaults *cmDefaults;
@property(strong,nonatomic) BlueTempView *btView;
@property(strong,nonatomic) BlueTempModel *blueTempModel;
@property(strong,nonatomic) NSMutableArray *tempList;
@property(nonatomic,strong) NSMutableArray *deviceList;//定义列表
@property(nonatomic,strong) NSMutableArray *peripheralList;//链接的列表
//-(NSMutableArray *)getDeviceLists;
//
//-(NSMutableArray *)getPeriperalLists;
//连接peripheral
@property(nonatomic,strong) CBPeripheral *peripheral;
@property(nonatomic,assign) int cdata;
@property(nonatomic,strong) NSString *oneHigh;
@property(nonatomic,strong) NSString *oneLow;
@property(nonatomic,strong) NSString *twoHigh;
@property(nonatomic,strong) NSString *twoLow;
@property(nonatomic,strong) NSString *threeHigh;
@property(nonatomic,strong) NSString *threeLow;
@property(nonatomic,strong) NSString *fourHigh;
@property(nonatomic,strong) NSString *fourLow;
@property (nonatomic,assign) BOOL isAutoCon;
@property(assign,nonatomic) BOOL isSaveOnce;
@property (nonatomic,strong) NSTimer * deviceTimer;
@property (nonatomic,assign) int times;
//温度单位
@property(nonatomic,strong) NSString *tmpUnit;
//报警状态1
@property(nonatomic,strong) NSString *alamOneText;
//报警状态2
@property(nonatomic,strong) NSString *alamTwoText;
//报警状态3
@property(nonatomic,strong) NSString *alamThreeText;
//报警状态4
@property(nonatomic,strong) NSString *alamFourText;
//温度状态1
@property(nonatomic,strong) NSString *tempOne;
//温度状态2
@property(nonatomic,strong) NSString *tempTwo;
//温度状态3
@property(nonatomic,strong) NSString *tempThree;
//温度状态4
@property(nonatomic,strong) NSString *tempFour;
//设备探头名称1
@property(nonatomic,strong) NSString *probeOneName;
//设备探头名称2
@property(nonatomic,strong) NSString *probeTwoName;
//设备探头名称3
@property(nonatomic,strong) NSString *probeThreeName;
//设备探头名称4
@property(nonatomic,strong) NSString *probeFourName;
//最大温度1
@property(nonatomic,strong) NSString *maxOne;
//最小温度1
@property(nonatomic,strong) NSString *minOne;
//最大温度2
@property(nonatomic,strong) NSString *maxTwo;
//最小温度2
@property(nonatomic,strong) NSString *minTwo;
//最大温度3
@property(nonatomic,strong) NSString *maxThree;
//最小温度3
@property(nonatomic,strong) NSString *minThree;
//最大温度4
@property(nonatomic,strong) NSString *maxFour;
//最小温度4
@property(nonatomic,strong) NSString *minFour;
//设备序列号
@property(nonatomic,strong) NSString *deviceNo;
//固件升级判断逻辑
@property(nonatomic,strong) NSString *deviceInfo;
@property(strong,nonatomic) NSTimer *highTimer;
@property(strong,nonatomic) NSString *highTimerdata;
//获取当前的时间
@property (strong,nonatomic) NSDate *currentDate;
//时间格式化
@property(strong,nonatomic) NSDateFormatter *dateformatter;
@property(nonatomic) long ctime;
@property(strong,nonatomic) MBProgressHUD *hud;
@property(strong,nonatomic) NSString *salNumber;
@property(strong,nonatomic) NSString *arr;
@property(nonatomic,assign) id delegate;
@property(nonatomic,strong) Download *download;
//新增Model
@property(strong,nonatomic) BlueTempModel *bleModel;
@property(strong,nonatomic) NSString *stringdate;
//中心管理者
@property (nonatomic, strong) CBCentralManager *centerManager;
@end
BlueTempViewController.m
//重写返回
- (void)onBackClick{
self.isAutoCon = FALSE;
NSString *tips = @"DisConnect Tips";
NSString *cancel = @"Cancel";
NSString *ok = @"OK";
BTAlertController *alertController = [BTAlertController alertControllerWithTitle:tips message:@"Do you want to give up Bluetooth connected" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *noAction = [UIAlertAction actionWithTitle:cancel style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
}];
UIAlertAction *yesAction = [UIAlertAction actionWithTitle:ok style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
//断开蓝牙 结束升级
[[BlueUtil sharedManager] disContentBle];
[self.navigationController popViewControllerAnimated:YES];
}];
[alertController addAction:noAction];
[alertController addAction:yesAction];
[self presentViewController:alertController animated:true completion:nil];
}
/*
断开蓝牙的时候发送广播
*/
-(void)disContentBle:(NSNotification*)notification{
self.isAutoCon = TRUE;
//当接受到蓝牙退出的指令之后 不断开界面 需要重新去连接界面
if(self.deviceTimer==nil){
self.deviceTimer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(deviceTime) userInfo:nil repeats:YES];
}
}
//自动连接蓝牙代码
-(void)deviceTime{
//自定加1
self.times++;
NSString *mac = [[CommonDefaults shared] getMacAdder];
self.deviceList = [[BlueUtil sharedManager] getDeviceLists];
self.peripheralList = [[BlueUtil sharedManager] getPeriperalLists];
//如果不为空的时候
if(mac!=nil&&self.isAutoCon){
for(int i=0;i=5){
NSLog(@"大于了20。。%@",self.deviceTimer);
NSLog(@"大于了20.。%d",self.times);
if(self.deviceTimer!=nil){
[self.deviceTimer invalidate];
self.deviceTimer = nil;
}
self.isAutoCon = FALSE;
UIViewController *target = nil;
for (UIViewController * controller in self.navigationController.viewControllers) {
//遍历
if ([controller isKindOfClass:[DeviceViewController class]]) {
//这里判断是否为你想要跳转的页面
target = controller;
}
}
if (target) {
[self.navigationController popToViewController:target animated:YES]; //跳转
}
}else{
NSLog(@"DDD-HHH-LLL%@",self.deviceTimer);
NSLog(@"DDD-HHH-LLL%d",self.times);
}
}
五:相关蓝牙列表的服务调用
-(BlueTempModel*)getBleTempModel{
if(self.bleModel==nil){
self.bleModel = [[BlueTempModel alloc] init];
}
return self.bleModel;
}
-(CommonDefaults*)getCmDefaults{
if(self.cmDefaults==nil){
self.cmDefaults = [[CommonDefaults alloc] init];
}
return self.cmDefaults;
}
-(BlueTempView *)getBlueTempView{
if(self.btView==nil){
self.btView = [[BlueTempView alloc] init];
}
return self.btView;
}
-(BlueTempModel *)getBlueTempModel{
if(self.blueTempModel==nil){
self.blueTempModel = [[BlueTempModel alloc] init];
}
return self.blueTempModel;
}
-(NSMutableArray *)gettempList{
if(self.tempList==nil){
self.tempList = [NSMutableArray array];
}
return self.tempList;
}
-(NSMutableArray*)getDeviceList{
if(self.deviceList==nil){
self.deviceList=[NSMutableArray array];
}
return self.deviceList;
}
-(NSMutableArray*)getPeripheralList{
if(self.peripheralList==nil){
self.peripheralList = [NSMutableArray array];
}
return self.peripheralList;
}
这篇博文总结了蓝牙自动链接的相关知识,判断到当设备断开之后,一定时间范围内,如果设备再次开启,App移动应用端将依旧链接,继续读取/写入相关数据,如果超出时间范围内,则进行返回退出链接界面,需要用times断开的次数,进行逻辑处理和功能需求的最终目的。
如果对您有所帮助,或者不懂之处可以留言,若有写的不对之处,欢迎志同道合的朋友一起学习,一起进步,谢谢您的阅读,别忘了点赞呀!