iOS传感器与CMMotionManager

iOS 中常见传感器如下所示

类型 作用
环境光传感器 感应光照强度
距离传感器 感应靠近设备屏幕的物体
磁力计传感器 感应周边磁场
内部温度传感器 感应设备内部温度(非公开)
湿度传感器 感应设备是否进水(非微电子传感器)
陀螺仪 感应持握方式
加速计 感应设备运动

其中陀螺仪、加速计和磁力计的数据获取均依赖于 CMMotionManager。

CMMotionManager

CMMotionManager 是 Core Motion 库的核心类,负责获取和处理手机的运动信息,它可以获取的数据有

  • 加速度,标识设备在三维空间中的瞬时加速度
  • 陀螺仪,标识设备在三个主轴上的瞬时旋转
  • 磁场信息,标识设备相对于地球磁场的方位
  • 设备运动数据,标识关键的运动相关属性,包括设备用户引起的加速度、姿态、旋转速率、相对于校准磁场的方位以及相对于重力的方位等,这些数据均来自于 Core Motion 的传感器融合算法,从这一个数据接口即可获取以上三种数据,因此使用较为广泛

CMMotionManager 有 “push” 和 “pull” 两种方式获取数据,push 方式实时获取数据,采样频率高,pull 方式仅在需要数据时采集数据,Apple 更加推荐这种方式获取数据。

push 方式

将 CMMotionManager 采集频率 interval 设置好以后,CMMotionManager 会在一个操作队列里从特定的 block 返回实时数据更新,这里以设备运动数据 DeviceMotion 为例,代码如下

    CMMotionManager *motionManager = [[CMMotionManager alloc] init];
    motionManager.deviceMotionUpdateInterval = 1/15.0;
    if (motionManager.deviceMotionAvailable) {
        [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
                                           withHandler: ^(CMDeviceMotion *motion, NSError *error){
                                               double x = motion.gravity.x;
                                               double y = motion.gravity.y;
                                               double z = motion.gravity.z;
                                               //NSLog(@"roll:%f, pitch:%f, yew:%f", motion.attitude.roll, motion.attitude.pitch, motion.attitude.yaw);
                                               NSLog(@"x:%f, y:%f, z:%f", x, y, z);
                                           }];
    }

首先要注意尽可能在 app 中只创建一个 CMMotionManager 对象,多个 CMMotionManager 对象会影响从加速计和陀螺仪接受数据的速率。其次,在启动接收设备传感器信息前要检查传感器是否硬件可达,可以用
deviceMotionAvailable 检测硬件是否正常,用 deviceMotionActive 检测当前 CMMotionManager 是否正在提供数据更新。

暂停更新也很容易,直接调用 stopXXXUpdates 即可。

pull 方式

仍以 DevideMotion 为例,pull 方式代码如下

    CMMotionManager *motionManager = [[CMMotionManager alloc] init];
    motionManager.deviceMotionUpdateInterval = 1/15.0;
    if (motionManager.deviceMotionAvailable) {
        [motionManager startDeviceMotionUpdates];
        double x = motionManager.deviceMotion.gravity.x;
        double y = motionManager.deviceMotion.gravity.y;
        double z = motionManager.deviceMotion.gravity.z;
        NSLog(@"x:%f, y:%f, z:%f", x, y, z);
    }

但是这样的方式获取的数据实时性不高,第一次获取可能没有数据,同时要注意不能过于频繁的获取,否则可能引起崩溃。

下面是 CMMotionManager 监听的各类运动信息的简单描述。首先需要明确,iOS 设备的运动传感器使用了如下的坐标系

image

而 DeviceMotion 信息具体对应 iOS 中的 CMDeviceMotion 类,它包含的数据有

1. attitude

attitude 用于标识空间位置的欧拉角(roll、yaw、pitch)和四元数(quaternion)

image

其中绕 x 轴运动称作 pitch(俯仰),绕 y 轴运动称作 roll(滚转),绕 z 轴运动称作 yaw(偏航)。

当设备正面向上、顶部指向正北、水平放置时,pitch、yaw 和 roll 值均为 0,其他变化如下

  • 设备顶部上扬,pitch 由 0 递增 pi/2,顶部下沉,由 0 递减 pi/2
  • 设备顶部左偏 180 度范围内,yaw 由 0 递增 pi,右偏递减
  • 设备左部上旋,roll 由 0 递增 pi,左部下旋,roll 由 0 递减

2. rotationRate

rotationRate 标识设备旋转速率,具体变化如下

  • pitch 增加,x > 0,pictch 减少,x < 0
  • roll 增加,y > 0,row 减少,y < 0
  • yaw 增加,z > 0,yaw 减少,z < 0

3. gravity

gravity 用于标识重力在设备各个方向的分量,具体值的变化遵循如下规律:重力方向始终指向地球,而在设备的三个方向上有不同分量,最大可达 1.0,最小是 0.0。

4. userAcceleration

userAcceleration 用于标识设备各个方向上的加速度,注意是加速度值,可以标识当前设备正在当前方向上减速 or 加速。

5. magneticField & heading

magneticField 用于标识设备周围的磁场范围和精度,heading 用于标识北极方向。但是要注意,这两个值的检测需要指定 ReferenceFrame,它是一个 CMAttitudeReferenceFrame 的枚举,有四个值

  • CMAttitudeReferenceFrameXArbitraryZVertical
  • CMAttitudeReferenceFrameXArbitraryCorrectedZVertical
  • CMAttitudeReferenceFrameXMagneticNorthZVertical
  • CMAttitudeReferenceFrameXTrueNorthZVertical

其中前两个 frame 下磁性返回非法负值,只有选择了 CMAttitudeReferenceFrameXMagneticNorthZVertical 或 CMAttitudeReferenceFrameXTrueNorthZVertical 才有有效值,这两个枚举分别指代磁性北极和地理北极。

距离传感器

距离传感器可以检测有物理在靠近或者远离屏幕,使用如下

    [UIDevice currentDevice].proximityMonitoringEnabled = YES;
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(proximityStateDidChange:) name:UIDeviceProximityStateDidChangeNotification object:nil];
    
- (void)proximityStateDidChange:(NSNotification *)note
{
    if ([UIDevice currentDevice].proximityState) {
        NSLog(@"Coming");
    } else {
        NSLog(@"Leaving");
    }
}

环境光传感器

目前没有找到相应的 API,可以采取的思路是通过摄像头获取每一帧,进行光线强度检测

            NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
            CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL, imageDataSampleBuffer, kCMAttachmentMode_ShouldPropagate);
            NSDictionary *metadata = [[NSDictionary alloc] initWithDictionary:(__bridge NSDictionary*)metadataDict];
            CFRelease(metadataDict);
            NSDictionary *exifMetadata = [[metadata objectForKey:(NSString *) kCGImagePropertyExifDictionary] mutableCopy];
            float brightnessValue = [[exifMetadata  objectForKey:(NSString *) kCGImagePropertyExifBrightnessValue] floatValue];
            NSLog(@"%f",brightnessValue);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355