宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

一、传感器

1、什么是传感器
传感器是一种感应检测周围环境的一种装置, 目前已经广泛应用于智能手机上

传感器的作用
用于感应检测设备周边的信息
不同类型的传感器, 检测的信息也不一样

iPhone中的下面现象都是由传感器完成的
在地图应用中, 能判断出手机头面向的方向
一关灯, iPhone会自动调整屏幕的亮度
打电话时, 人脸贴近iPhone屏幕时, 屏幕会自动锁屏
… …

二、各种传感器

1、传感器的类型
iPhone内置的传感器有
运动传感器加速度传感器加速计(Motion/Accelerometer Sensor)
环境光传感器(Ambient Light Sensor)
距离传感器(Proximity Sensor)
磁力计传感器(Magnetometer Sensor)
内部温度传感器(Internal Temperature Sensor)
湿度传感器(Moisture Sensor)
陀螺仪(Gyroscope)
… …

2、环境光传感器(Ambient Light Sensor)
是iPhone和Mac设备中最为古老的传感器成员

它能够让你在使用 Mac、iPhone、iPad时,眼睛更为舒适 
从一个明亮的室外走入相对黑暗的室内后,iOS设备会自动调低亮度,让屏幕显得不再那么光亮刺眼 
当你使用iPhone拍照时,闪光灯会在一定条件下自动开启
几乎所有的Mac 都带有背光键盘,当周围光线弱到一定条件时,会自动开启键盘背光 

3、距离传感器(Proximity Sensor)
用于检测是否有其他物体靠近设备屏幕
当你打电话或接电话时将电话屏幕贴近耳边,iPhone会自动关闭屏幕 ,好处是
节省电量 
防止耳朵或面部不小心触摸屏幕而引发一些不想要的意外操作 
题外话:利用距离传感器,能找出很多电视剧的穿帮镜头

4、磁力计传感器(Magnetometer Sensor)
可以感应地球磁场, 获得方向信息, 使位置服务数据更精准
可以用于电子罗盘和导航应用
iPad的Smart Cover盒盖睡眠操作就是基于磁力计传感器

5、内部温度传感器(Internal Temperature Sensor)
从 iPad一代开始,iOS设备都加入了一个内部温度传感器,用于检测内部组件温度,当温度超过系统设定的阈值时,会出现以下提示 

6、湿度传感器(Moisture Sensor)
湿度传感器跟其他基于微电子的传感器不同,是一个简单的物理传感器

简单来说,湿度传感器就是一张遇水变红的试纸

Apple的维修人员就是通过检测试纸是否变红,来判断设备是否进水
(设备进水不在保修范围之内)

7、陀螺仪(Gyroscope)
陀螺仪是随着iPhone4的上市首次出现在iOS设备上的传感器
陀螺仪的原理是检测设备在X、Y、Z轴上所旋转的角速度

陀螺仪在赛车类游戏中有重大作用:
模拟汽车驾驶时方向盘旋转的动作 
使得这类游戏的操控体验更为真实

iOS开发 传感器(加速计、摇一摇、计步器)-风君雪科技博客

8、加速计传感器(Motion/Accelerometer Sensor)
最早出现在iOS设备上的传感器之一
加速计用于检测设备在X、Y、Z轴上的加速度 (哪个方向有力的作用)

加速计可以用于检测设备的摇晃,经典应用场景
摇一摇
计步器

iOS开发 传感器(加速计、摇一摇、计步器)-风君雪科技博客

小结:

iOS开发 传感器(加速计、摇一摇、计步器)-风君雪科技博客

三、距离传感器的使用

默认情况下,每一个应用程序距离传感器都是关闭状态

如果需要,需要通过代码将其打开

// 开启距离感应功能
[UIDevice currentDevice].proximityMonitoringEnabled = YES;
// 监听距离感应的通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(proximityChange:)
name:UIDeviceProximityStateDidChangeNotification
object:nil];

- (void)proximityChange:(NSNotification *)notification {
    if ([UIDevice currentDevice].proximityState == YES) {
    NSLog(@"某个物体靠近了设备屏幕"); // 屏幕会自动锁住
    } else {
    NSLog(@"某个物体远离了设备屏幕"); // 屏幕会自动解锁
    }
}

四、加速计

1、加速计原理
检测设备在X、Y、Z轴上的加速度 (哪个方向有力的作用,哪个方向运动了)
根据加速度数值,就可以判断出在各个方向上的作用力度

iOS开发 传感器(加速计、摇一摇、计步器)-风君雪科技博客

2、UIAccelerometer
  1)加速计程序的开发
在iOS4以前:使用UIAccelerometer,用法非常简单(到了iOS5就已经过期)
从iOS4开始:CoreMotion.framework

虽然UIAccelerometer已经过期,但由于其用法极其简单,很多程序里面都还有残留

  2)UIAccelerometer的使用步骤

获得单例对象
UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];

设置代理
accelerometer.delegate = self;

设置采样间隔
accelerometer.updateInterval = 1.0/30.0; // 1秒钟采样30次

实现代理方法
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
// acceleration中的x、y、z三个属性分别代表每个轴上的加速度

3、Core Motion

1)Core Motion

在iOS4之前,加速度计由UIAccelerometer类来负责采集数据

随着iPhone4的推出加速度计全面升级,并引入了陀螺仪与Motion(运动)相关的编程成为重头戏苹果特地在iOS4中增加了专门处理Motion的框架-CoreMotion.framework

Core Motion不仅能够提供实时的加速度值和旋转速度值,更重要的是,苹果在其中集成了很多牛逼的算法

2)Core Motion获取数据的两种方式

iOS开发 传感器(加速计、摇一摇、计步器)-风君雪科技博客

获取加速计信息

push
实时采集所有数据(采集频率高)

创建运动管理者对象
CMMotionManager *mgr = [[CMMotionManager alloc] init];

判断加速计是否可用(最好判断)
if (mgr.isAccelerometerAvailable) {
    // 加速计可用
}

设置采样间隔
mgr.accelerometerUpdateInterval = 1.0/30.0; // 1秒钟采样30次

开始采样(采样到数据就会调用handler,handler会在queue中执行)
- (void)startAccelerometerUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMAccelerometerHandler)handler;

 pull
在有需要的时候,再主动去采集数据

创建运动管理者对象
CMMotionManager *mgr = [[CMMotionManager alloc] init];

判断加速计是否可用(最好判断)
if (mgr.isAccelerometerAvailable) { // 加速计可用 }

开始采样
- (void)startAccelerometerUpdates;

在需要的时候采集加速度数据
CMAcceleration acc = mgr.accelerometerData.acceleration;
NSLog(@"%f, %f, %f", acc.x, acc.y, acc.z);

 获取陀螺仪信息

- (void)pullGyro
{
    // pull方式获取陀螺仪信息
    // 1.判断陀螺仪是否可用
    if (!self.mgr.isGyroAvailable) {
        NSLog(@"设备小于iPhone4,或者陀螺仪损坏");
        return;
    }
    
    // 2.开始采样
    [self.mgr startGyroUpdates];
}

- (void)pushGyro
{
    // push方式获取陀螺仪信息
    // 1.判断陀螺仪是否可用
    if (!self.mgr.isGyroAvailable) {
        NSLog(@"设备小于iPhone4,或者陀螺仪损坏");
        return;
    }
    
    // 2.设置采样
    self.mgr.gyroUpdateInterval = 1.0 / 10;
    
    // 3.开始采样
    [self.mgr startGyroUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMGyroData * _Nullable gyroData, NSError * _Nullable error) {
        if (error) {
            NSLog(@"%@", error);
            return;
        }
        
        // 获取陀螺仪的信息
        CMRotationRate rotationRate = gyroData.rotationRate;
        NSLog(@"x:%f y:%f z:%f", rotationRate.x, rotationRate.y, rotationRate.z);
    }];
}

 4、Core Motion框架结构示意图

iOS开发 传感器(加速计、摇一摇、计步器)-风君雪科技博客

五、摇一摇

监控摇一摇的方法
方法1:通过分析加速计数据来判断是否进行了摇一摇操作(比较复杂)
方法2:iOS自带的Shake监控API(非常简单)

判断摇一摇的步骤:实现3个摇一摇监听方法

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event /** 检测到摇动 */
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event /** 摇动取消(被中断) */
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event /** 摇动结束 */

六、计步器

计步器是从iOS7开始引入(内部原理还是加速计)
iOS7 : CMStepCounter –> iOS8过期

// 1.判断计步器是否可用
    if (![CMStepCounter isStepCountingAvailable]) {
        NSLog(@"计步器不可用");
        return;
    }
    
    // 2.开始计步
    // 2.1.创建计步器
    CMStepCounter *stepCounter = [[CMStepCounter alloc] init];
    
    // 2.2.开始计步
    // updateOn : 用户走了多少步之后,更新block
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [stepCounter startStepCountingUpdatesToQueue:queue updateOn:5 withHandler:^(NSInteger numberOfSteps, NSDate * _Nonnull timestamp, NSError * _Nullable error) {
        if (error) return;
        
        // 1.GCD方式
//        dispatch_sync(dispatch_get_main_queue(), ^{
//            self.stepLabel.text = [NSString stringWithFormat:@"您一共走了%ld步", numberOfSteps];
//        });
        NSString *stepString = [NSString stringWithFormat:@"您一共走了%ld步", numberOfSteps];
        [self.stepLabel performSelectorOnMainThread:@selector(setText:) withObject:stepString waitUntilDone:YES];
    }];

iOS8用法

/** 计步器对象 */
@property (nonatomic, strong) CMPedometer *pedometer;

#pragma mark - 懒加载代码
- (CMPedometer *)pedometer
{
    if (_pedometer == nil) {
        self.pedometer = [[CMPedometer alloc] init];
    }
    return _pedometer;
}


// 1.判断计步器是否可用
    if (![CMPedometer isStepCountingAvailable]) {
        return;
    }
    
    // 2.开始计步
    // 2.1.创建计步对象
    
    // 2.2.开始计步
    // FromDate : 从什么时间开始计步
    NSDate *date = [NSDate date];
    [self.pedometer startPedometerUpdatesFromDate:date withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
        if (error) {
            NSLog(@"%@", error);
            return;
        }
        
        NSLog(@"您一共走了%@步", pedometerData.numberOfSteps);
    }];

计算前7天内的 某段时间一共走了多少步

NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
    fmt.dateFormat = @"yyyy-MM-dd";
    NSDate *fromDate = [fmt dateFromString:@"2015-9-26"];
    NSDate *toDate = [fmt dateFromString:@"2015-9-28"];
    [self.pedometer queryPedometerDataFromDate:fromDate toDate:toDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
        NSLog(@"%@", pedometerData.numberOfSteps);
    }];