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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7888490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:02:41  来源:igfitidea点击:

How can I detect screen lock/unlock events on the iPhone?

iosobjective-ceventsunlock

提问by Vikas S Singh

How can I detect screen lock/unlock events on the iPhone? When the user unlocks it, I want to show a notification alert from my iPhone app. (For Just like Broadcast Receiver for screen unlock in Android.)

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

回答by Rohit Kashyap

Check this out, I wanted to detect the lock/unlock events, I solved it by Darwin notifications. You can detect the event when the device is locked by "com.apple.springboard.lockcomplete".

看看这个,我想检测锁定/解锁事件,我通过达尔文通知解决了它。当设备被 锁定时,您可以检测到该事件"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);  
}   

回答by Vadim

To detect lock/unlock inside app in swift 5 only this worked for me:

要在 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")
}

回答by Oliver

Actually I want the if I exit the application and lock the iPhone , and after some time I have unlock the iPhone , then exit Applications show the notifications or Alert the Start-up the Applications.

实际上我想要如果我退出应用程序并锁定 iPhone ,一段时间后我解锁了 iPhone ,然后退出应用程序显示通知或提醒启动应用程序。

You can't do that on the iPhone.

你不能在 iPhone 上这样做。

回答by Alen Liang

  1. You can't use com.apple.springboard.lockcompleteor com.apple.springboard.lockstatewhen submitting your app to App Store, your app will be rejected because it's private API.

  2. The com.apple.springboard.lockcompletenotification NOT always comes after the com.apple.springboard.lockstatenotification, it may happen early or later. You need to set a timer to wait for that event.

  1. 您无法使用com.apple.springboard.lockcompletecom.apple.springboard.lockstate将您的应用程序提交到 App Store 时,您的应用程序将被拒绝,因为它是私有 API。

  2. com.apple.springboard.lockcomplete通知并非总是来了之后com.apple.springboard.lockstate通知,可能提前或之后发生。您需要设置一个计时器来等待该事件。

So here is how you can detect screen lock and unlock status, in Swift 5:

下面是在 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
}

回答by Nekto

May be you need to implement following methods in AppDelegate:

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

Tells the delegate that the application is now in the background.

告诉委托应用程序现在在后台。

- (void)applicationDidEnterBackground:(UIApplication *)application

Tells the delegate that the application has become active.

告诉委托应用程序已变为活动状态。

- (void)applicationDidBecomeActive:(UIApplication *)application

Tells the delegate that the application is about to become inactive.

告诉委托应用程序即将变为非活动状态。

- (void)applicationWillResignActive:(UIApplication *)application

回答by Mostafizur Rahman

From the current view controller your should add an observer for UIApplicationDidEnterBackgroundNotification and remove the observer during dismissing the view controller [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];

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