Search code examples
iosgpssleepcore-location

Is there a way to check if the iOS device is locked/unlocked?


I have used GPS location updates in my application. I want to detect if the iOS device is in sleep mode so that I can turn off the GPS location updates and optimize the battery use. I have already tried pausesLocationupdates in iOS 6, but it does not work as desired. I want to turn off the GPS location updates as soon as the device goes to sleep mode. I want to detect the lock/unlock event in the device.

Is there any way to achieve this functionality ?

so far I got the darwin notifications as given below

-(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);


}

I am able to get the darwin notifications when device is locked/unlocked, but the real problem is how identify between if the notification has come from locking or the unlocking of the device. Console logs are:

 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

Any private API would also suffice. Thanks in advance.


Solution

  • I solved it like this:

    //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);
    }
    

    Note: the "com.apple.springboard.lockcomplete" notification will always come after the "com.apple.springboard.lockstate" notification

    Update

    The order of the two notifications can no longer be relied upon, as of recent versions of iOS