Detectar si un usuario se está moviendo en un automobile

AVISO : esta pregunta se publicó originalmente antes de que Apple introdujera el hardware de detección de movimiento y las API asociadas en el SDK de iOS. Las respuestas a esta pregunta, sin embargo, siguen siendo relevantes.


Estoy creando una aplicación iPhone iOS que implica el seguimiento del funcionamiento y / o la marcha de un usuario. Es muy importante que los resultados grabados de los usuarios que se ejecutan y caminen sigan siendo honestos. Necesito una manera de atrapar a un usuario que puede estar engañando (o accidentalmente han dejado el rastreador) al usar un automobile.

Para comprobar si el usuario está conduciendo o viajando en un automobile, primero pensé en estas dos comprobaciones, pero ninguna de las dos puede realmente determinar si el usuario está en un automobile o no (hasta cierto punto).

  1. Verifique la velocidad actual del usuario en el siguiente método. Si el usuario viaja más rápido que 20-ish MPH, entonces podría asumir que el usuario está en un automobile:

    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { CLLocation *recentLocation = [locations lastObject]; recentLocation.speed; //If speed is over 20 MPH, assume the user is not on their feet. 

    Sin embargo, no estoy seguro si esto es realmente un buen cheque porque las personas han sido registradas para ir más rápido que eso antes . ¿Es un buen cheque o debo usar otra cosa?

  2. Determine qué tan rápido el usuario está acelerando usando las API aceleradoras y de movimiento proporcionadas con Core Motion Framework . Si el usuario acelera a una velocidad determinada, podría asumir que el usuario está viajando en un vehículo.

¿Son correctos estos supuestos? Creo que mi verdadera pregunta es esta: ¿hay alguna forma mejor de detectar si el usuario se está moviendo en un vehículo? ¿En qué caso? . Y si no es así, ¿son estas comprobaciones adecuadas para este caso o esto sería molesto para algunos usuarios que en realidad son tan rápidos? ¿CoreMotion es la API adecuada para hacer esto?


EDITAR: El nuevo coprocesador iPhones 5S M7 proporciona una detección de movimiento más precisa. ¿Alguien podría explicar cómo usar las nuevas API M7?

Todos los consejos sobre la sabiduría (o la falta de ella) para adivinar acerca de los estados de movimiento de los datos de location siguen siendo válidos. Pero con respecto a su actualización sobre Core Motion y M7 …

Sí, puede usar Core Motion en dispositivos con un coprocesador de movimiento M7, M8, M9, etc. (*) para get una indicación de si el usuario podría estar manejando.

  1. Cree un object CMMotionActivityManager (después de usar su método de class isActivityAvailable para determinar si tiene características M7 (+)) y inicie las actualizaciones de actividad o pregúntelas por las actividades recientes.
  2. Verifique la propiedad automotive CMMotionActivity objects CMMotionActivity para ver si iOS piensa que el usuario está / estuvo en un automobile.
  3. No hay un paso tres.

Al igual que las inferencias GPS, sin embargo, aún debe tomar esta información con un poco de sal. Las API de CoreMotion le ofrecen las mejores conjeturas de iOS sobre la actividad del usuario, pero no hay ninguna garantía de que sea 100% precisa. (Por ejemplo, no estoy seguro si viajar en un tren puede contar como un automotive . También tenga en count que los diferentes types de actividad no son mutuamente excluyentes). Es mejor que su aplicación verifique los types de actividad que le interesan que intentar para excluir los que no quieres.


(*) Los dispositivos M7 son aquellos con A7 SoC: iPhone 5s, iPad Air, iPad mini 2. M8 es A8, M9 es A9, etc. En resumen, todos los dispositivos iOS que se introdujeron desde el otoño de 2013, excluyendo el iPhone 5c.

Puede usar esta biblioteca simple para detectar si el usuario está caminando, corriendo, en el vehículo o no se está moviendo.

Funciona en todos los dispositivos iOS y no necesita chip M7.

https://github.com/SocialObjects-Software/SOMotionDetector

En repo puedes encontrar un proyecto de demostración

El CLLocation basado en CLLocation es la única información confiable que puede get. Según lo especificado por Ali en Need to find Distance usando Gyro + Accelerometer , es inútil encontrar la velocidad y la position durante un período de time más largo. Los valores de aceleración integrados comienzan a moverse después de 0.5 a 2 segundos y no hay posibilidad de volverlos a calibrar.

Dependiendo de su caso de uso veo más problemas que los 44.72 km / h (27.79 mph) de Usain Bolt:

  1. Regiones sin señal GPS como túneles, estacionamiento subterráneo, …
  2. Errores en el GPS. Recuerdo una gira de seguimiento de 6 horas en los Alpes alemanes y esto es lo que la aplicación pensó 🙂
    Caminando sobre el agua a 920 km / h
  3. Como ya mencionó, nunca se sabe si el usuario está en automobile, tren, metro, autobús … Y nunca se sabe si él está conduciendo a sí mismo o solo al copiloto, si esto es importante.

Xcode 7.3, iOS 9.3

Gracias a todos los queueboradores originales.

Acabo de pasar unas horas tratando de entender por qué esta class bastante simple no estaba funcionando para mí. Utilicé toda la sugerencia anterior y de otras publicaciones para ver qué actividad iOS pensaba que el usuario estaba realizando utilizando el marco Core Motion y utilizando la class CMMotionActivityManager .

Resulta que, por la razón que sea, tuve mi "Seguimiento de condición física" en "Configuración" -> "Privacidad" -> "Motion & Fitness" apagado . Y por cualquier razón después de agregar el marco y llamar a una class CM, la aplicación. No solicitó habilitar esto. Debo haber apagado esto manualmente.

Con el time tropecé con esta publicación …

iOS: está activada la actividad de movimiento en Configuración> Privacidad> Actividad de movimiento

Lo que me lleva a revisar la configuration y resolver el problema. Después de voltear "Fitness Tracking" para activarlo y ejecuté la aplicación. de nuevo, todo funcionó como un encanto.

¡Esperemos que esto salve a alguien un poco de time! Aclamaciones.