传感器技术

传感器技术

加速计传感器(微信摇一摇,计步器)

目标: 演示加速剂的使用,做一个小球滚动的游戏.
关键词:Accelerrmoter
作用:检测设备在x,y,z的加速度(力的作用)

  1. 导入框架CoreMotion.

  2. 核心类:CMMotionmanager.动作管理者,包含加速度数据,加速度数据和磁场数据等.

  3. 逻辑代码部分
    3.0. 判断硬件是否支持
    3.1. 获取加速度数据.
    3.2. 提供了两种获取方式
    1.push(推送)实时向你推送.使用队列,通过block定时执行.
    1. 判断是否是激活加速计状态.??pull需要么??
    2.pull(拉取)在你需要数据的时候,主动获取.开启速度更新
    2. 通过acceleremoterData属性,去获取数据.
    小球是通过push.因为要实时更新.
    ============== 让小球滚起来. ===========
    利用x,y的值,来给小球添加作用力(将0.5的力放大),竖直偏移是它向下移动,水平偏移是它左右移动.

  4. 注意点生命周期问题:图层.改圆角,不能再viewDidload中改,也不能在viewWillAppear(还没布局),在ViewDidAppear也不行,会跳动先方后圆.最后知道了ViewDidLayoutSubviews中写.这个时候自动布局才已经改变了.

// 用于接收和处理`加速事件`和其它的动作事件
#import <CoreMotion/CoreMotion.h>

- (void)viewDidLoad {
    [super viewDidLoad];
  
    // ========== 1. 获取加速度的数据 ==========
    
    // 1. 判断加速计是否可用
    if (self.motionManager.accelerometerAvailable == NO) {
        NSLog(@"不支持该硬件!");
        return;
    }
    
    // ========== 2. 获取数据 (Pull方式) ==========
    
    // 1.0 秒更新一次数据
    self.motionManager.accelerometerUpdateInterval = 1.0;
    
    // 1. 激活加速计 (提供数据)
    // 开始更新新数据 (Pull方式)
    [self.motionManager startAccelerometerUpdates];
    
    // [self.motionManager stopAccelerometerUpdates];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // ========== 在点击时, 获取加速计的数据 ==========
    // 通过一个属性来获取到最新的加速计数据
    CMAccelerometerData *data = self.motionManager.accelerometerData;
    
    // 加速计数据
    CMAcceleration acce = data.acceleration;
    
    NSLog(@"%f, %f, %f", acce.x, acce.y, acce.z);
}

#pragma mark - Getter & Setter

- (CMMotionManager *)motionManager
{
    if (_motionManager == nil) {
        _motionManager = [[CMMotionManager alloc] init];
    }
    return _motionManager;
}

#pragma mark - 小球案例
/*
 在self.view 的 layoutSubviews 执行完成
 当该方法执行时, 子视图已经布局完成
 * 当view的frame值或者它的子视图的frame被修改, 需要重新布局
 */
- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    
    self.imageView.layer.cornerRadius = self.imageView.bounds.size.width * 0.5;
    // IB中也可以设置 clipToBounds
    // self.imageView.clipsToBounds = YES;
    // self.imageView.layer.masksToBounds = YES;
}

  // 开始更新加速计数据 (Push, 定时更新)
        [self.motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {
            if (error) {
                NSLog(@"获取数据失败! %@", error);
                return;
            }
            // CMAccelerometerData : 表示加速计的数据
            // CMAcceleration : 表示加速度的结构体
            CMAcceleration data = accelerometerData.acceleration;
            NSLog(@"%f, %f", data.x, data.y);
            
            // ========== 让小球滚动 ==========
            // 1. 利用x, y的值, 来给小球添加作用力 (将0.5的力放大成10像素)
            CGFloat speedX = data.x * 30;
            CGFloat speedY = data.y * 30;
            // NSLog(@"%f, %f", speedX, speedY);
            
            // 2. 改变frame值, 让小球滚动
            CGRect rect = self.imageView.frame;
            rect.origin.x += speedX;
            // y方向的数据要颠倒
            rect.origin.y += -speedY;
            
            [UIView animateWithDuration:0.25 animations:^{
                self.imageView.frame = rect;
            }];
            
            NSLog(@"%@", NSStringFromCGRect(self.imageView.frame));
            
            // 在非主线程当中更新UI界面, frame值会改变, 但是界面是没有影响(不确定)
        }];

陀螺仪(赛车类游戏)
目标:掌握陀螺仪的使用
* 获取角速度

关键类:CMMotionManager,关键字:Groy

  1. 同加速度前面部分代码.
  2. push获取数据
    2.1. 判断是否激活,激活
    2.2. 开始陀螺仪数据更新
    2.3. 获取旋转速率(角速度),x,y,z这里面代表三个方向旋转的角速度数据.
  3. pull方式(类比上面)
代码部分都类似距离传感器
[self.motionManager startGyroUpdates];

[self.motionManager startGyroUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMGyroData * _Nullable gyroData, NSError * _Nullable error) {
            
            // CMGyroData : 表示陀螺仪的数据
            // CMRotationRate : 表示旋转速率, 角速度的结构体,
            CMRotationRate rate = gyroData.rotationRate;
            
            // 静止状态下, 值是接近于0的
            NSLog(@"%f, %f, %f", rate.x, rate.y, rate.z);
        }];

计步器来统计数据

关键类:
CMStepCounter早期使用的,
CMPedometer取代前面的检测走了多少步.
类似上面,也是通过计步数据对象,的各个属性获取相关值.

#import <CoreMotion/CoreMotion.h>

// 1. 实例化一个计步器
    self.pedometer = [[CMPedometer alloc] init];
    
    // 开始统计相关的行走信息 (开始统计的时间)
    // 会定时的触发Block方法, 没办法设置
    [self.pedometer startPedometerUpdatesFromDate:[NSDate date] withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
        
        // CMPedometerData: 表示计步器所统计的数据
        
        // ========== 检测走了多少步 ==========
        // 1. 判断该检测是否可用 (依赖硬件)
        if ([CMPedometer isStepCountingAvailable] == NO) {
            NSLog(@"不支持步数的计算统计");
            return;
        } else {
            // 走了几步
            NSNumber *number = pedometerData.numberOfSteps;
            NSLog(@"走了%zd步", number.intValue);
        }
        
        // ========== 检测走了多少米 ==========
        if ([CMPedometer isDistanceAvailable] == YES) {
            NSNumber *distance = pedometerData.distance;
            NSLog(@"走了%f米", distance.floatValue);
        }
    }];
距离传感器(靠近手机,打电话)

相关框架:CoreMotion(动作)
观察相关类,没有发现距离传感器的类(特别没有专门的类),是通过UIDevice来获取的.
关键字proximity距离.
UIDevice可以用来判断系统版本.

  1. [UIDevice currentDevice].proximityMonitoring默认关闭的
  2. 不是所有的设备都有距离传感器的.判断方法特别.
    Demo目标:类似微信的语音播放,扬声器和听筒切换
    思路:
  3. 距离传感器判断是否靠近屏幕.
  4. 根据状态,修改声音的输出.

知识点: UIDevice类内,有距离传感器状态改变的通知
代码:

  1. 开启距离传感器
  2. 添加接收系统通知
  3. 播放声音改变,关键类:AVAudioSession(音频会话),是个单例,有个重写输出音频端口的方法.
  4. 猜想根据通知参数的userInfo,获取当前的距离传感器状态,但是打印发现没有数据,只是通知你改变了状态了.
  5. 观看文档发现直接通过获取设备的proximityState属性,来判断是否靠近设备.

前提是需要向系统声明我所需要使用的音频相关功能.只需要走一次

  1. AVAudioSession单例有个setCategory方法进行类别的设置,参数是你需要做的功能.
  2. 修改声音的输出端口,是听筒还是扬声器.
  3. 播放音乐AVAudioPlayer 播放音乐的类,1.实例化,2.调用播放方法.
代码部分
导入
#import <AVFoundation/AVFoundation.h>

  // ========== 1. 开启距离传感器 ==========
    if ([[UIDevice currentDevice] isProximityMonitoringEnabled] == NO) {
        NSLog(@"当前距离传感器没有打开");
        
        // 尝试打开距离传感器, 如果失败了, 意味着不支持该硬件
        [[UIDevice currentDevice] setProximityMonitoringEnabled:YES];
        
        // 打开结果判断 (是否支持硬件)
        if ([[UIDevice currentDevice] isProximityMonitoringEnabled] == NO) {
            NSLog(@"不支持该硬件, 无法使用");
        } else {
            NSLog(@"成功打开距离传感器");
            
            // ========== 2. 监听通知 ==========
            // 监听通知
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(proximityDidChangeAction:) name:UIDeviceProximityStateDidChangeNotification object:nil];
        }
    }
    
    // ========== 2. 向系统声明, 所使用的音频的相关功能 ==========
    // 告诉系统, 本应用会使用哪一些与音频相关的功能
    NSError *error;
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord  error:&error];
    if (error) {
        NSLog(@"音频功能声音出错: %@", error);
    }
    
    // ========== 3. 测试: 播放歌曲 ==========
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"南征北战 - 我的天坑.mp3" withExtension:nil];
    // 实例化音乐播放器
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    if (error) {
        NSLog(@"歌曲播放出错");
    }
    // 开始播放
    [self.player play];

- (void)proximityDidChangeAction:(NSNotification *)notification
{
    // ========== 1. 判断是否靠近屏幕 ==========
    // 并没有通过userInfo来携带数据, 应该直接获取距离传感器的proximityState属性
    NSLog(@"%@", notification.userInfo);
    
    /** 音频会话
     1. 设置应用当前所处的音频环境 (播放声音, 录音, 用什么来播放)
     2. 向系统诠释应用使用音频相关行为的意图
     */
    
    // 设置音频的输出设备 (听筒或扬声器)
    /**
     AVAudioSessionPortOverrideNone    = 0,  (扬声器)
     AVAudioSessionPortOverrideSpeaker  (听筒)
     */
    AVAudioSessionPortOverride port = [UIDevice currentDevice].proximityState == NO ? AVAudioSessionPortOverrideSpeaker : AVAudioSessionPortOverrideNone;

    NSError *error;
    [[AVAudioSession sharedInstance] overrideOutputAudioPort:port error:&error];
    if (error) {
        NSLog(@"改变声音输出失败");
    }
}

- (void)dealloc
{
    // 移除观察者
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
磁力传感器(了解,不常使用)
温度传感器(系统自动做的)
湿度传感器(保修用的)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容