近距离监控可能无法正常工作

时间:2021-11-03 02:17:18

for my iOS app i want to implement a feature where the screen should turns off (like when you answer a phone call) when the device is faced down. so I've started by detecting the device orientation:

对于我的iOS应用程序,我想实现一个功能,即当设备向下时,屏幕应该关闭(比如你接电话时)。我首先检测设备的朝向

//in my ViewDidLoad
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.rotated(_:)), name: UIDeviceOrientationDidChangeNotification, object: nil)

//called when the device changes orientation
    func rotated(notification: NSNotification){
        if UIDevice.currentDevice().orientation == UIDeviceOrientation.FaceDown{
            print("device = faced down")
        }else{
            print("device != faced down")
        }
    }

when device is down i've called

设备坏了,我打过电话

UIDevice.currentDevice().proximityMonitoringEnabled = true

else

其他的

UIDevice.currentDevice().proximityMonitoringEnabled = false

the problem is UIDeviceOrientationDidChangeNotification seems to act a little bit late so when the rotated() function is called, the device is already faced down and it turns out that in order for proximityMonitoringEnabled = true to turn off the screen the proximity sensor should not be already covered ! I'm pretty sure that this is an Apple limitation but maybe someone out there did found a solution or came across a workaround! thanks in advance.

问题是UIDeviceOrientationDidChangeNotification似乎工作有点晚,所以当调用旋转()函数时,设备已经是朝下的,结果是,为了接近监控功能=关闭屏幕,接近传感器不应该被覆盖!我很确定这是苹果的限制,但也许有人找到了解决方案或者找到了解决方案!提前谢谢。

1 个解决方案

#1


1  

Approach:

方法:

Since iOS doesn't provide before changing Orientation we couldn't rely on 'UIDeviceOrientationDidChangeNotification'. Instead we can use CoreMotion Framework and access hardware's gyroscope for detecting possible FaceDown orientations and set proximityMonitoringEnabled appropriately.

因为iOS在改变方向之前没有提供,所以我们不能依赖于“UIDeviceOrientationDidChangeNotification”。相反,我们可以使用CoreMotion框架并访问硬件的陀螺仪来检测可能的面朝下方向,并适当地设置proximityMonitoringEnabled。

Gyroscope Data:

陀螺仪数据:

Using Gyroscope observations below values can possibly detect FaceDown Orientation.

使用下面的陀螺仪观测值,可以检测到向下的方向。

let gyroData = (minX:-3.78, minY:-3.38, minZ:-5.33, maxX:3.29, maxY:4.94, maxZ:3.36)

Solution in Swift:

迅速的解决方案:

class ProximityViewController: UIViewController {

    let cmManager = CMMotionManager(), gyroData = (minX:-3.78, minY:-3.38, minZ:-5.33, maxX:3.29, maxY:4.94, maxZ:3.36)

    override func viewDidLoad() {
        super.viewDidLoad()

        //Using GyroMotion
        experimentCoreMotion()
    }

    //MARK: - Using Core Motion
    func experimentCoreMotion() {

        if cmManager.gyroAvailable {

            //Enable device orientation notification
            UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()

            cmManager.gyroUpdateInterval = 0.1

            handleFaceDownOrientation()

        }

    }

    func handleFaceDownOrientation() {

        cmManager.startGyroUpdatesToQueue(NSOperationQueue.currentQueue()!, withHandler: { (data:CMGyroData?, error: NSError?) in

            if self.isGyroDataInRange(data!) {

                UIDevice.currentDevice().proximityMonitoringEnabled = (UIDevice.currentDevice().orientation == .FaceDown)

                if UIDevice.currentDevice().orientation == .FaceDown {  print("FaceDown detected") }
                else { print("Orientation is not facedown") }
            }
        })
    }

    func isGyroDataInRange(val: CMGyroData) -> Bool {
        return ((val.rotationRate.x > gyroData.minX && val.rotationRate.x < gyroData.maxX) &&
            (val.rotationRate.y > gyroData.minY && val.rotationRate.y < gyroData.maxY) &&
            (val.rotationRate.z > gyroData.minZ && val.rotationRate.z < gyroData.maxZ))
    }
}

Hope my solution solves your query. Let me know the solution is working fine for your requirement.

希望我的解决方案能解决你的问题。让我知道解决方案对你的要求是有效的。

Gyroscope & Accelerometer Observations:

陀螺仪和加速度计的观察:

I've experimented the possible values of FaceDown orientation using Gyroscope & Accelerometer. IMO, Gyroscope data seems fine but it's open to explore other hardware's sensors to detect FaceDown Orientation.

我已经用陀螺仪和加速度计试验了脸朝下方向的可能值。IMO,陀螺仪数据看起来很好,但是它可以探索其他硬件的传感器来检测面向下的方向。

#1


1  

Approach:

方法:

Since iOS doesn't provide before changing Orientation we couldn't rely on 'UIDeviceOrientationDidChangeNotification'. Instead we can use CoreMotion Framework and access hardware's gyroscope for detecting possible FaceDown orientations and set proximityMonitoringEnabled appropriately.

因为iOS在改变方向之前没有提供,所以我们不能依赖于“UIDeviceOrientationDidChangeNotification”。相反,我们可以使用CoreMotion框架并访问硬件的陀螺仪来检测可能的面朝下方向,并适当地设置proximityMonitoringEnabled。

Gyroscope Data:

陀螺仪数据:

Using Gyroscope observations below values can possibly detect FaceDown Orientation.

使用下面的陀螺仪观测值,可以检测到向下的方向。

let gyroData = (minX:-3.78, minY:-3.38, minZ:-5.33, maxX:3.29, maxY:4.94, maxZ:3.36)

Solution in Swift:

迅速的解决方案:

class ProximityViewController: UIViewController {

    let cmManager = CMMotionManager(), gyroData = (minX:-3.78, minY:-3.38, minZ:-5.33, maxX:3.29, maxY:4.94, maxZ:3.36)

    override func viewDidLoad() {
        super.viewDidLoad()

        //Using GyroMotion
        experimentCoreMotion()
    }

    //MARK: - Using Core Motion
    func experimentCoreMotion() {

        if cmManager.gyroAvailable {

            //Enable device orientation notification
            UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()

            cmManager.gyroUpdateInterval = 0.1

            handleFaceDownOrientation()

        }

    }

    func handleFaceDownOrientation() {

        cmManager.startGyroUpdatesToQueue(NSOperationQueue.currentQueue()!, withHandler: { (data:CMGyroData?, error: NSError?) in

            if self.isGyroDataInRange(data!) {

                UIDevice.currentDevice().proximityMonitoringEnabled = (UIDevice.currentDevice().orientation == .FaceDown)

                if UIDevice.currentDevice().orientation == .FaceDown {  print("FaceDown detected") }
                else { print("Orientation is not facedown") }
            }
        })
    }

    func isGyroDataInRange(val: CMGyroData) -> Bool {
        return ((val.rotationRate.x > gyroData.minX && val.rotationRate.x < gyroData.maxX) &&
            (val.rotationRate.y > gyroData.minY && val.rotationRate.y < gyroData.maxY) &&
            (val.rotationRate.z > gyroData.minZ && val.rotationRate.z < gyroData.maxZ))
    }
}

Hope my solution solves your query. Let me know the solution is working fine for your requirement.

希望我的解决方案能解决你的问题。让我知道解决方案对你的要求是有效的。

Gyroscope & Accelerometer Observations:

陀螺仪和加速度计的观察:

I've experimented the possible values of FaceDown orientation using Gyroscope & Accelerometer. IMO, Gyroscope data seems fine but it's open to explore other hardware's sensors to detect FaceDown Orientation.

我已经用陀螺仪和加速度计试验了脸朝下方向的可能值。IMO,陀螺仪数据看起来很好,但是它可以探索其他硬件的传感器来检测面向下的方向。