如何使用CMMotionActivityManager并接收更新?

我想创build一个应用程序,可以接收和处理动作更新,以了解用户是否静止,走路,跑步或在交通工具上。 我已经看到CMMotionActivityManager对我有用的参考。

CMMotionActivityManager类提供对设备存储的运动数据的访问。 运动数据反映了用户是在步行,在车上跑步,还是在一段时间内静止。

我是新的应用程序开发,我不明白如何使用该方法开始更新。 这样做的方法是- (void)startActivityUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMMotionActivityHandler)handler 。 我不明白我应该写在处理程序上,因为引用说:

处理程序当检测到当前运动types的变化时执行的程序段。 有关此块参数的信息,请参阅CMMotionActivityHandler。 该属性不能为零。

我的实现是:

 - (IBAction)startButtonPressed:(id)sender { _motionActivityManager = [[CMMotionActivityManager alloc] init]; [_motionActivityManager startActivityUpdatesToQueue:NSOperationQueueDefaultMaxConcurrentOperationCount withHandler:CMMotionActivityHandler]; } 

我已经导入了CoreMotion框架但是XCode不能识别CMMotionActivityHandler ,我错在哪里? 我该如何解决这个问题?

谢谢

示例代码:

 [_motionActivityManager startActivityUpdatesToQueue:[[NSOperationQueue alloc] init] withHandler: ^(CMMotionActivity *activity) { dispatch_async(dispatch_get_main_queue(), ^{ if ([activity walking]) { NSLog(@"walking"); } }); }]; 

这个答案的最高投票版本有点迂回。 它创build一个队列,然后使用GCD在主队列上执行。 另外,很多示例在withHandler参数中放置了一个块,但是我发现这个块很笨重,并且从代码格式的angular度看起来不够干净。

这是我的示例实现:

 @implementation MotionHandler { @private // this is a private variable for this class that is not visible outside // (also, iOS handles memory and access management of these faster than properties) CMMotionActivityManager *_motionActivityManager; } // initialization method, you can do other stuff here too - (instancetype)init { self = [super init]; if (self) { // check to see if the device can handle motion activity if ([CMMotionActivityManager isActivityAvailable]) { // if so, initialize the activity manager _motionActivityManager = [[CMMotionActivityManager alloc] init]; } } } - (void)startMotionActivityMonitoring { // create the motion activity handler CMMotionActivityHandler motionActivityHandler = ^(CMMotionActivity *activity) { // TODO motion detected here. Do something. } // check to see if the motion activity manager exists if (_motionActivityManager) { // if so, start monitoring activity // notice that we add updates to the mainQueue. This will call your handler on the main thread [_motionActivityManager startActivityUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:motionActivityHandler]; } } @end 

//检查是否有设备

 BOOL b= [CMMotionActivityManager isActivityAvailable];; motionActivityManager=[[CMMotionActivityManager alloc]init]; //register for coremotion notification [motionActivityManager startActivityUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMMotionActivity *activity) { NSLog(@"Got a core motion update"); NSLog(@"Current activity date is %f",activity.timestamp); NSLog(@"Current activity confidence from a scale of 0 to 2 - 2 being best- is: %ld",activity.confidence); NSLog(@"Current activity type is unknown: %i",activity.unknown); NSLog(@"Current activity type is stationary: %i",activity.stationary); NSLog(@"Current activity type is walking: %i",activity.walking); NSLog(@"Current activity type is running: %i",activity.running); NSLog(@"Current activity type is cycling: %i",activity.cycling); NSLog(@"Current activity type is automotive: %i",activity.automotive); }]; 

请检查设备

Swift 2.0

 _motionActivityManager = CMMotionActivityManager() _motionActivityManager.startActivityUpdatesToQueue(NSOperationQueue.mainQueue()) { // CMMotionActivity activity in // do your logic here } 
 -(void)device_motion{ self.motionManager= [[CMMotionManager alloc] init]; self.motionManager.deviceMotionUpdateInterval = 1.0/60.0; self.opQ = [NSOperationQueue currentQueue]; if(self.motionManager.isDeviceMotionAvailable) { // Listen to events from the motionManager self.motionHandler = ^ (CMDeviceMotion *motion, NSError *error) { if (!prevTime) { prevTime = motion.timestamp; return; } //Calculate delta time between previous motionUpdate call and _now_ double deltaTime = motion.timestamp - prevTime; prevTime = motion.timestamp; //Y axis rotation CMRotationRate rotationRate = motion.rotationRate; double rotation = rotationRate.y; if (fabs(rotation) < 0.05) //igonre bias return; //Calculate the angular distance double anglePathRad = rotation * deltaTime; //calculate total panoram angle currAngle += CC_RADIANS_TO_DEGREES(anglePathRad); NSLog(@"Angle : %f ",currAngle); }; } else { NSLog(@"No Device Motion on device."); } // Start listening to motionManager events [self.motionManager startDeviceMotionUpdatesToQueue:self.opQ withHandler:self.motionHandler]; }