Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differentiate between screen lock and home button press on iOS7

I need to do something in applicationDidEnterBackground. But I need to differentiate which user action causes the "enter background": screen lock or home button press.

I was using this code, which is from this post - How to differentiate between screen lock and home button press on iOS5?:

UIApplicationState state = [application applicationState];
if (state == UIApplicationStateInactive) {
    NSLog(@"Sent to background by locking screen");
} else if (state == UIApplicationStateBackground) {
    NSLog(@"Sent to background by home button/switching to other app");
}

It works fine on iOS6. but on iOS7 (both device and simulator), I always get UIApplicationStateBackground, whether the user clicks the home or the lock button.

Does someone have an idea about what could cause this? iOS 7 updates to multi-task background handling? Or some setting of my app (my app's background mode is off)?

And is there an alternative solution?

like image 509
Perisheroy Avatar asked Oct 25 '13 17:10

Perisheroy


2 Answers

This solution was taken from this answer and worked for me. It is a bit hacky but it makes it easier to be accepted on the appstore because it doesn't use com.apple.springboard.lockcomplete or com.apple.springboard.lockstate.

The following code goes into your AppDelegate:

func applicationDidEnterBackground(_ application: UIApplication) {
    if (DidUserPressLockButton()) {
        print("User pressed lock button")
    } else {
        print("user pressed home button")
    }
}

private func DidUserPressLockButton() -> Bool {
    let oldBrightness = UIScreen.main.brightness
    UIScreen.main.brightness = oldBrightness + (oldBrightness <= 0.01 ? (0.01) : (-0.01))
    return oldBrightness != UIScreen.main.brightness
}

The idea is to try changing the brightness of the screen after the application went to background and to check if this change was successful.

Disclaimer: it doesn't work on the simulator and you will have to test it on a real device.

like image 189
MCSim Avatar answered Nov 15 '22 19:11

MCSim


This can help you both on iOS6 & iOS7 :).

When user press lock button you will get a com.apple.springboard.lockcomplete notification.

//new way
//put this in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
                                    NULL,
                                    displayStatusChanged,
                                    CFSTR("com.apple.springboard.lockcomplete"),
                                    NULL,
                                    CFNotificationSuspensionBehaviorDeliverImmediately);

//put this function in AppDelegate
static void displayStatusChanged(CFNotificationCenterRef center,
                                 void *observer,
                                 CFStringRef name,
                                 const void *object,
                                 CFDictionaryRef userInfo) {
    if (name == CFSTR("com.apple.springboard.lockcomplete")) {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kDisplayStatusLocked"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

//put this in onAppEnterBackground
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
    if (state == UIApplicationStateInactive) {
        NSLog(@"Sent to background by locking screen");
    } else if (state == UIApplicationStateBackground) {
        if (![[NSUserDefaults standardUserDefaults] boolForKey:@"kDisplayStatusLocked"]) {
            NSLog(@"Sent to background by home button/switching to other app");
        } else {
            NSLog(@"Sent to background by locking screen");
        }
    }

//put this in - (void)applicationWillEnterForeground:(UIApplication *)application
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"kDisplayStatusLocked"];
[[NSUserDefaults standardUserDefaults] synchronize];

CGFloat screenBrightness = [[UIScreen mainScreen] brightness];

NSLog(@"Screen brightness: %f", screenBrightness);

UIApplicationState state = [[UIApplication sharedApplication] applicationState];

if (state == UIApplicationStateInactive) {

    NSLog(@"Sent to background by locking screen");

} else if (state == UIApplicationStateBackground) {
    if (screenBrightness > 0.0) {
        NSLog(@"Sent to background by home button/switching to other app");
    } else {
        NSLog(@"Sent to background by locking screen");
    }
}

like image 36
wqq Avatar answered Nov 15 '22 17:11

wqq