有没有办法检查iOS设备是否被锁定/解锁?

Roh*_*yap 13 gps sleep core-location ios

我在我的应用程序中使用了GPS位置更新.我想检测iOS设备是否处于睡眠模式,这样我就可以关闭GPS位置更新并优化电池使用.我已经在iOS 6中尝试了pausesLocationupdates,但它无法正常工作.我想在设备进入睡眠模式后立即关闭GPS位置更新.我想检测设备中的锁定/解锁事件.

有没有办法实现这个功能?

到目前为止,我收到了下面给出的达尔文通知

-(void)registerForall
{
    //Screen lock notifications
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    NULL, // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.iokit.hid.displayStatus"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);


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

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

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

}
//call back
static void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
    NSLog(@"IN Display status changed");
    NSLog(@"Darwin notification NAME = %@",name);


}
Run Code Online (Sandbox Code Playgroud)

当设备被锁定/解锁时,我能够获得达尔文通知,但真正的问题是如何识别通知是来自锁定还是解锁设备.控制台日志是:

 LockDetectDemo[2086] <Warning>: IN Display status changed
 LockDetectDemo[2086] <Warning>: Darwin notification NAME = com.apple.springboard.lockcomplete
 LockDetectDemo[2086] <Warning>: IN Display status changed
 LockDetectDemo[2086] <Warning>: Darwin notification NAME = com.apple.springboard.lockstate
 LockDetectDemo[2086] <Warning>: IN Display status changed
 LockDetectDemo[2086] <Warning>: Darwin notification NAME = com.apple.springboard.hasBlankedScreen
 LockDetectDemo[2086] <Warning>: IN Display status changed
 LockDetectDemo[2086] <Warning>: Darwin notification NAME = com.apple.iokit.hid.displayStatus
Run Code Online (Sandbox Code Playgroud)

任何私有API也足够了.提前致谢.

Roh*_*yap 17

我这样解决了:

//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
    CFStringRef nameCFString = (CFStringRef)name;
    NSString *lockState = (NSString*)nameCFString;
    NSLog(@"Darwin notification NAME = %@",name);

    if([lockState isEqualToString:@"com.apple.springboard.lockcomplete"])
    {
        NSLog(@"DEVICE LOCKED");
        //Logic to disable the GPS
    }
    else
    {
        NSLog(@"LOCK STATUS CHANGED");
        //Logic to enable the GPS
    }
}

-(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);
}
Run Code Online (Sandbox Code Playgroud)

注意:" com.apple.springboard.lockstmplete "通知将始终位于"com.apple.springboard.lockstate"通知之后

更新

从最新版本的iOS开始,无法再依赖这两个通知的顺序

  • 来自Eskimo @ apple:https://devforums.apple.com/message/912689#912689:这些通知密钥未记录,因此被视为私有API.而且,从兼容性的观点来看,依赖于它们并不是对先前描述的技术的显着改进.btw被认为是公共API的通知密钥列在<notify_keys.h>中,但需要注意的是,并非所有这些都在iOS上有意义. (8认同)
  • 它现在不必要的讨论,更新分别是用例,我的应用甚至在后台使用位置更新,我有一个处理程序,当用户锁定设备(应用程序在后台),我想暂停位置更新. (2认同)
  • 在按下电源按钮和设备收到通知时,是否可以区分显示状态变化? (2认同)

Jul*_*les 11

现在不允许应用程序收听设备锁定通知!

我收到了这个:

亲爱的开发者,

我们发现您最近提交的"xxxx"存在一个或多个问题.要处理您的提交,必须纠正以下问题:

不支持的操作 - 不允许应用程序监听设备锁定通知.

一旦纠正了这些问题,请使用Xcode或Application Loader将新二进制文件上传到iTunes Connect.在iTunes Connect上的我的应用程序的应用程序详细信息页面上选择新的二进制文件,然后单击提交以进行查看.

问候,

App Store团队
2017年4月26日10:56

  • 这似乎不是一个答案,而是对该问题的额外限制。 (2认同)

Nit*_*7ak 7

/*注册用于检测锁定状态的应用程序*/

 -(void)registerAppforDetectLockState {

     int notify_token;
     notify_register_dispatch("com.apple.springboard.lockstate",     &notify_token,dispatch_get_main_queue(), ^(int token) {
     uint64_t state = UINT64_MAX;
     notify_get_state(token, &state);
     if(state == 0) {
        NSLog(@"unlock device");
     } else {
        NSLog(@"lock device");
     }

     NSLog(@"com.apple.springboard.lockstate = %llu", state);
     UILocalNotification *notification = [[UILocalNotification alloc]init];
     notification.repeatInterval = NSDayCalendarUnit;
     [notification setAlertBody:@"Hello world!! I come becoz you lock/unlock your device :)"];
     notification.alertAction = @"View";
     notification.alertAction = @"Yes";
     [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:1]];
     notification.soundName = UILocalNotificationDefaultSoundName;
     [notification setTimeZone:[NSTimeZone  defaultTimeZone]];

     [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

  });

 }
Run Code Online (Sandbox Code Playgroud)