Как использовать CMMotionActivityManager и получать обновления?
Я хочу создать приложение, которое может получать и обрабатывать обновления движения, чтобы понять, находится ли пользователь в неподвижном состоянии, гуляет, работает или находится в транспорте. Я видел по ссылке, что CMMotionActivityManager может быть полезен для меня.
Класс CMMotionActivityManager обеспечивает доступ к данным движения, хранящимся на устройстве. Данные о движении отражают, идет ли пользователь в течение определенного периода времени на ходьбе, беге, в транспортном средстве или в неподвижном состоянии.
Я новичок в разработке приложений и не понимаю, как использовать метод для запуска обновления. Метод для этого - (void)startActivityUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMMotionActivityHandler)handler
, Я не понимаю, что я должен написать на обработчик, потому что ссылка говорит:
handler Блок для выполнения при обнаружении изменения в текущем типе движения. Для получения информации о параметрах этого блока, см. CMMotionActivityHandler. Это свойство не должно быть нулевым.
Моя реализация:
- (IBAction)startButtonPressed:(id)sender {
_motionActivityManager = [[CMMotionActivityManager alloc] init];
[_motionActivityManager startActivityUpdatesToQueue:NSOperationQueueDefaultMaxConcurrentOperationCount withHandler:CMMotionActivityHandler];
}
Я уже импортировал инфраструктуру CoreMotion, но XCode не распознает CMMotionActivityHandler
где я не прав? Как я могу решить эту проблему?
Спасибо
5 ответов
Получившая наибольшее количество голосов версия этого ответа является немного окольными. Он создает очередь, но затем использует 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
Образец кода:
[_motionActivityManager startActivityUpdatesToQueue:[[NSOperationQueue alloc] init]
withHandler:
^(CMMotionActivity *activity) {
dispatch_async(dispatch_get_main_queue(), ^{
if ([activity walking]) {
NSLog(@"walking");
}
});
}];
Swift 2.0
_motionActivityManager = CMMotionActivityManager()
_motionActivityManager.startActivityUpdatesToQueue(NSOperationQueue.mainQueue())
{
// CMMotionActivity
activity in
// do your logic here
}
// проверить, доступно ли на устройстве
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);
}];
Пожалуйста, проверьте на устройстве
-(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];
}