¿Hay alguna forma de monitorear el movimiento de los usuarios de iPhone como la function "raise to speak"?

Quiero recibir una notificación cuando el usuario levanta el iPhone a la cara. Al igual que siri. ¿Es posible?

Agregue un requisito más específico: Quiero oscurecer la pantalla cuando el usuario coloca el teléfono cerca de su oreja. Sé que el sensor de proximidad puede habilitarse para implementar esto. Pero es molesto que la pantalla se oscurezca de vez en cuando cuando el usuario mueve el dedo sobre el sensor. Entonces me pregunto cómo evitar este caso y solo oscurecer la pantalla cuando el usuario levanta el iPhone para hablar.

Consulte Uso del sensor de proximidad en la reference de la class UIDevice. Vos tambien:

  • Permitirle:

    UIDevice *device = [UIDevice currentDevice]; device.proximityMonitoringEnabled = YES; 
  • Compruebe si se habilitó correctamente; observe la notificación UIDeviceProximityStateDidChangeNotification si tiene éxito; de lo contrario, es posible que su dispositivo no sea capaz:

     if (device.proximityMonitoringEnabled) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleProximityChange:) name:UIDeviceProximityStateDidChangeNotification object:nil]; } else { // device not capable } 
  • Y escribe tu selector:

     - (void)handleProximityChange:(NSNotification *)notification { NSLog(@"%s proximityState=%d", __FUNCTION__, [[UIDevice currentDevice] proximityState]); } 

Para detectar si el usuario lo mantiene en alto, podría casarme con el sensor de proximidad con el CMMotionManager y mirar la propiedad de gravity para ver si sostienen el teléfono casi verticalmente. Por lo tanto, defina algunas properties de class:

 @property (nonatomic, strong) CMMotionManager *motionManager; @property (nonatomic, strong) NSOperationQueue *deviceQueue; 

Y luego puede iniciar CMMotionManager , buscando si el dispositivo se mantiene en position vertical:

 self.deviceQueue = [[NSOperationQueue alloc] init]; self.motionManager = [[CMMotionManager alloc] init]; self.motionManager.deviceMotionUpdateInterval = 5.0 / 60.0; UIDevice *device = [UIDevice currentDevice]; [self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical toQueue:self.deviceQueue withHandler:^(CMDeviceMotion *motion, NSError *error) { BOOL vertical = (motion.gravity.z > -0.4 && motion.gravity.z < 0.4 & motion.gravity.y < -0.7); if ((vertical && !device.proximityMonitoringEnabled) || (!vertical && device.proximityMonitoringEnabled)) { device.proximityMonitoringEnabled = vertical; } }]; 

Si estos umbrales de gravity tienen sentido es un poco subjetivo. También podría, en lugar de simplemente mirar para ver si el teléfono se mantiene aproximadamente verticalmente, mire otros datos del acelerómetro (por ejemplo, si levantaron el object o no). Parece que hay muchas maneras de pelar el gato.

Sé que esto es antiguo, pero simplifiqué un poco la lógica y hice una class de envoltorio en Swift.

Lo puedes encontrar aquí

 class DeviceRaisedToEarListener: NSObject { private let deviceQueue = NSOperationQueue() private let motionManager = CMMotionManager() private var vertical: Bool = false private(set) var isRaisedToEar: Bool = false { didSet { if oldValue != self.isRaisedToEar { self.stateChanged?(isRaisedToEar: self.isRaisedToEar) } } } var stateChanged:((isRaisedToEar: Bool)->())? = nil override init() { super.init() self.setupMotionManager() } private func setupMotionManager() { self.motionManager.deviceMotionUpdateInterval = 5.0 / 60.0 let device = UIDevice.currentDevice() // Only listen for proximity changes if the device is held vertically self.motionManager.startDeviceMotionUpdatesUsingReferenceFrame(CMAttitudeReferenceFrame.XArbitraryZVertical, toQueue: self.deviceQueue) { (motion, error) in self.vertical = (motion.gravity.z > -0.4 && motion.gravity.z < 0.4 && motion.gravity.y < -0.7) } } func startListening() { UIDevice.currentDevice().proximityMonitoringEnabled = true NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleProximityChange:", name: UIDeviceProximityStateDidChangeNotification, object: nil) } func stopListening() { UIDevice.currentDevice().proximityMonitoringEnabled = false NSNotificationCenter.defaultCenter().removeObserver(self) } func handleProximityChange(notification: NSNotification) { self.isRaisedToEar = UIDevice.currentDevice().proximityState && self.vertical } deinit { self.stopListening() } } // How to use: private func setupRaiseListener() { self.deviceListener.stateChanged = { [weak self] isRaisedToEar in println("is raised? \(isRaisedToEar)") } self.deviceListener.startListening() }