2014-01-21 2 views
2

Я хочу создать приложение, которое может получать и обрабатывать обновления движения, чтобы понять, является ли пользователь стационарным, ходящим, запущенным или находящимся на транспорте. Я видел по ссылке, что CMMotionActivityManager может быть полезен для меня.Как использовать CMMotionActivityManager и получать обновления?

Класс CMMotionActivityManager обеспечивает доступ к данным движения, хранящимся на устройстве. Данные о движении отражают, идет ли пользователь пешком, бег, в автомобиле или стационарный в течение периодов времени.

Я новичок в разработке приложений, и я не понимаю, как использовать метод для запуска обновления. Способ для этого - - (void)startActivityUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMMotionActivityHandler)handler. Я не понимаю, что я должен написать на обработчик, поскольку ссылка говорит:

обработчик Блок для выполнения при изменении текущего типа движения обнаружено. Информацию о параметрах этого блока см. В CMMotionActivityHandler. Это свойство не должно быть nil.

Моя реализация:

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

Я уже ввезли рамки CoreMotion Но XCode не признают CMMotionActivityHandler, где я не прав? Как я могу решить эту проблему?

Благодаря

ответ

-2
-(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]; 


} 
+0

Не могли бы вы объяснить, что делает этот код? Я этого не понимаю. Что делает код внутри motionHandler? – emattiazzi

+1

Это CMMotionManager, а не CMMotionActivityManager –

+0

NSLog не нужно выполнять в основной очереди, что является излишним. –

4

Пример кода:

[_motionActivityManager startActivityUpdatesToQueue:[[NSOperationQueue alloc] init] 
              withHandler: 
    ^(CMMotionActivity *activity) { 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      if ([activity walking]) { 
       NSLog(@"walking"); 
      } 
    }); 
}]; 
+0

Должен ли я определить что-то еще в моем коде выше? Я использовал ваш код и добавил некоторые, если для активности, чтобы проверить, является ли он автомобильным, запущенным, неизвестным, но он не работает. – emattiazzi

+1

Может быть, это не работает на симуляторе? – emattiazzi

+0

@mattyahtzee: Конечно, он не будет работать на симуляторе. Вы должны проверить устройство. – Bhavin

0

// проверить, если availasble на устройстве

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); 



}]; 

Пожалуйста, проверьте на устройстве

4

Самая высокая проголосовавшая версия этого ответа немного круглая. Он создает очередь, но затем использует GCD для выполнения в главной очереди. Кроме того, многие примеры помещают блок в параметр withHandler, но я нахожу это неудобным и не выглядит таким же чистым (с точки зрения форматирования кода).

Вот мой пример реализации:

@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 
1

Swift 2,0

_motionActivityManager = CMMotionActivityManager() 
_motionActivityManager.startActivityUpdatesToQueue(NSOperationQueue.mainQueue()) 
{ 
    // CMMotionActivity 
    activity in 

    // do your logic here 

} 
Смежные вопросы