如何检测iPhone上的屏幕锁定/解锁事件?

时间:2011-10-25 11:20:55

标签: ios objective-c events unlock

如何检测iPhone上的屏幕锁定/解锁事件?当用户解锁时,我想从我的iPhone应用程序显示通知提醒。 (就像在Android中用于屏幕解锁的广播接收器一样。)

6 个答案:

答案 0 :(得分:24)

检查一下,我想检测锁定/解锁事件,我通过达尔文通知解决了它。 您可以在设备被"com.apple.springboard.lockcomplete"锁定时检测到事件。

//call back
static void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
    // the "com.apple.springboard.lockcomplete" notification will always come after the "com.apple.springboard.lockstate" notification

    NSString *lockState = (NSString*)name;
    NSLog(@"Darwin notification NAME = %@",name);

    if([lockState isEqualToString:@"com.apple.springboard.lockcomplete"])
    {
        NSLog(@"DEVICE LOCKED");
    }
    else
    {
        NSLog(@"LOCK STATUS CHANGED");
    }   
}


-(void)registerforDeviceLockNotif
{
    //Screen lock notifications
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    NULL, // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.springboard.lockcomplete"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);

    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    NULL, // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.springboard.lockstate"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);  
}   

答案 1 :(得分:3)

  

其实我想要退出应用程序并锁定iPhone,   过了一段时间我解锁了iPhone,然后退出应用程序   显示通知或警告启动应用程序。

你不能在iPhone上这样做。

答案 2 :(得分:1)

您可能需要在AppDelegate中实施以下方法:

  

告诉代表该应用程序现在在后台。

- (void)applicationDidEnterBackground:(UIApplication *)application
  

告诉代理该应用程序已变为活动状态。

- (void)applicationDidBecomeActive:(UIApplication *)application
  

告诉代理该应用程序即将变为非活动状态。

- (void)applicationWillResignActive:(UIApplication *)application

答案 3 :(得分:1)

要在swift 5中检测应用程序内部的锁定/解锁,这仅对我有用:

override func viewDidLoad() {
    super.viewDidLoad()

     NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.willEnterForegroundNotification, object: nil)
     NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
}

@objc func applicationDidBecomeActive(notification: NSNotification) {
    print("ACTIVE")
}
@objc func applicationDidEnterBackground(notification: NSNotification) {
    print("BACKGROUND")
}

答案 4 :(得分:0)

  1. 在将应用提交到App Store时,您不能使用com.apple.springboard.lockcompletecom.apple.springboard.lockstate,因为您的应用是私有API,因此将被拒绝。

  2. com.apple.springboard.lockcomplete通知并非总是在com.apple.springboard.lockstate通知之后出现,它可能会更早或更晚发生。您需要设置一个计时器来等待该事件。

因此,这是在Swift 5中检测屏幕锁定和解锁状态的方法:

struct NotificationName {
    // Listen to CFNotification, and convert to Notification
    public static let lockComplete = Notification.Name("NotificationName.lockComplete")
    public static let lockState = Notification.Name("NotificationName.lockState")

    // Handle lockComplete and lockState Notification to post locked or unlocked notification.
    public static let locked = Notification.Name("NotificationName.locked")
    public static let unlocked = Notification.Name("NotificationName.unlocked")
}

func addNotificationObservers() {
    let lockCompleteString = "com.apple.springboard.lockcomplete"
    let lockString = "com.apple.springboard.lockstate"

    // Listen to CFNotification, post Notification accordingly.
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
                                    nil,
                                    { (_, _, _, _, _) in
                                        NotificationCenter.default.post(name: NotificationName.lockComplete, object: nil)
                                    },
                                    lockCompleteString as CFString,
                                    nil,
                                    CFNotificationSuspensionBehavior.deliverImmediately)

    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
                                    nil,
                                    { (_, _, _, _, _) in
                                        NotificationCenter.default.post(name: NotificationName.lockState, object: nil)
                                    },
                                    lockString as CFString,
                                    nil,
                                    CFNotificationSuspensionBehavior.deliverImmediately)

    // Listen to Notification and handle.
    NotificationCenter.default.addObserver(self,
                                            selector: #selector(onLockComplete),
                                            name: NotificationName.lockComplete,
                                            object: nil)

    NotificationCenter.default.addObserver(self,
                                            selector: #selector(onLockState),
                                            name: NotificationName.lockState,
                                            object: nil)
}

// nil means don't know; ture or false means we did or did not received such notification.
var receiveLockStateNotification: Bool? = nil
// when we received lockState notification, use timer to wait 0.3s for the lockComplete notification.
var waitForLockCompleteNotificationTimer: Timer? = nil
var receiveLockCompleteNotification: Bool? = nil

// When we received lockComplete notification, invalidate timer and refresh lock status.
@objc
func onLockComplete() {
    if let timer = waitForLockCompleteNotificationTimer {
        timer.invalidate()
        waitForLockCompleteNotificationTimer = nil
    }

    receiveLockCompleteNotification = true
    changeIsLockedIfNeeded()
}

// When we received lockState notification, refresh lock status.
@objc
func onLockState() {
    receiveLockStateNotification = true
    changeIsLockedIfNeeded()
}

func changeIsLockedIfNeeded() {
    guard let state = receiveLockStateNotification, state else {
        // If we don't receive lockState notification, return.
        return
    }

    guard let complete = receiveLockCompleteNotification else {
        // If we don't receive lockComplete notification, wait 0.3s.
        // If nothing happens in 0.3s, then make sure we don't receive lockComplete, and refresh lock status.
        waitForLockCompleteNotificationTimer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false, block: { _ in
            self.receiveLockCompleteNotification = false
            self.changeIsLockedIfNeeded()
        })
        return
    }

    // When we determined lockState and lockComplete notification is received or not.
    // We can update the device lock status by 'complete' value.
    NotificationCenter.default.post(
        name: complete ? NotificationName.locked : NotificationName.unlocked,
        object: nil
    )

    // Reset status.
    receiveLockStateNotification = nil
    receiveLockCompleteNotification = nil
}

答案 5 :(得分:-2)

从当前视图控制器中,您应该为UIApplicationDidEnterBackgroundNotification添加一个观察者,并在解除视图控制器时删除观察者 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];