是否有一种方法可以检测iOS设备进入睡眠模式(屏幕变黑时)的事件?



我想检测两个事件:

  1. 设备被锁定/解锁
  2. 设备进入睡眠状态,屏幕变黑。

我在这里能够实现的第一个:是否有办法检查iOS设备是否锁定/解锁?

现在我想检测第二个事件,有什么办法吗?

你基本上已经有了解决方案,我猜你是从我最近的一个答案中找到的:)

使用com.apple.springboard.hasBlankedScreen事件

屏幕空白时有多个事件发生,但这一个应该足够了:

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

,其中回调是:

static void hasBlankedScreen(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
    NSString* notifyName = (__bridge NSString*)name;
    // this check should really only be necessary if you reuse this one callback method
    //  for multiple Darwin notification events
    if ([notifyName isEqualToString:@"com.apple.springboard.hasBlankedScreen"]) {
       NSLog(@"screen has either gone dark, or been turned back on!");
    }
}

更新:正如@VictorRonin在下面的评论中所说,你应该很容易自己跟踪屏幕当前是打开还是关闭。这允许您确定在屏幕打开或关闭时是否发生hasBlankedScreen事件。例如,当你的应用程序启动时,设置一个变量来指示屏幕是打开的。此外,任何时候发生任何UI交互(按下按钮等),你都知道屏幕当前必须处于打开状态。所以,你得到的下一个hasBlankedScreen应该表明屏幕是关闭

另外,我想确保我们清楚术语。当屏幕超时自动变暗或用户手动按下电源键时,设备锁定。无论用户是否配置了密码,都会发生这种情况。此时,您将看到com.apple.springboard.hasBlankedScreencom.apple.springboard.lockcomplete事件。

当屏幕重新打开时,您将再次看到com.apple.springboard.hasBlankedScreen。但是,您将不会看到com.apple.springboard.lockstate,直到用户实际解锁设备与滑动(可能是一个密码)。


更新2:

还有另一种方法。您可以使用另一组api来侦听此通知,并在通知到来时获得一个状态变量:

#import <notify.h>
int status = notify_register_dispatch("com.apple.springboard.hasBlankedScreen",
                                      &notifyToken,
                                      dispatch_get_main_queue(), ^(int t) {
                                          uint64_t state;
                                          int result = notify_get_state(notifyToken, &state);
                                          NSLog(@"lock state change = %llu", state);
                                          if (result != NOTIFY_STATUS_OK) {
                                              NSLog(@"notify_get_state() not returning NOTIFY_STATUS_OK");
                                          }
                                      });
if (status != NOTIFY_STATUS_OK) {
    NSLog(@"notify_register_dispatch() not returning NOTIFY_STATUS_OK");
}

,您将需要保留一个ivar或其他持久变量,以存储通知令牌(不要在注册的方法中将其作为局部变量!)

int notifyToken;

您应该看到通过notify_get_state()获得的state变量在0和1之间切换,这将使您区分屏幕打开和关闭事件。

虽然这个文档很旧,但它确实列出了哪些通知事件具有可以通过notify_get_state()检索的相关状态。

警告:请参阅相关问题,了解最后一种技术的一些复杂性

您也可以订阅通知:"com.apple.springboard. "并使用API SBGetScreenLockStatus来确定设备是否被锁定。

最新更新