Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to distinguish between locking the device and sending an app to background?

I have an app that needs to do something when it’s sent to background using the Home button and something else when the device is locked using the top hardware button. The standard way of solving these requirements are the notifications and delegate methods sent out by UIApplication. On iOS 4 they look like this:

// Pressing the home button Will resign active. Did enter background. // Tapping app icon on Springboard Will enter foreground. Did become active.  // Pressing the lock button Will resign active. // Unlocking the device Did become active. 

In other words, it’s quite easy to tell between locking and backgrounding. On iOS 5 the behaviour changed:

// Pressing the home button Will resign active. Did enter background. // Tapping app icon on Springboard Will enter foreground. Did become active.  // Pressing the lock button Will resign active. Did enter background. // Unlocking the device Will enter foreground. Did become active. 

Notice that the didEnterBackground and willEnterForeground notifications are now sent out even when (un)locking the device, making it impossible to tell between locking and backgrounding. Is this change documented somewhere? Is it a regression? Do you know another way to distinguish the two cases?

like image 453
zoul Avatar asked Oct 13 '11 12:10

zoul


People also ask

How do I make apps run when my phone is locked?

Apparently, you first have to enable the respective lock screen widgets on your device, and it's quite easy. Get to the Settings and tap the Security option. Next, under the 'Screen security' option, tap and enable the Widget box.

What is lock screen under notifications?

When chosen, the Lock screen displays notices, not message previews or content.</p>\n<p class=\"Tip\">To make the Lock screen notifications useful, double-tap one. The app that generated the notification starts, and you can see more details.


2 Answers

iOS 6

In my preliminary testing via the simulator, checking the application state with

[[UIApplication sharedApplication] applicationState] 

in either

- (void)applicationWillEnterForeground:(UIApplication *)application  - (void)applicationDidEnterBackground:(UIApplication *)application 

allows you to differentiate between a call to lock the device and just switching back to the homescreen. A lock screen will return 1 (UIApplicationStateInactive), whereas a home button press will register as a 2 (UIApplicationStateBackground).

It seems consistent and should work on an iOS device just as reliably as it does in the simulator.

iOS 7

The iOS 6 method no longer works in iOS 7. In order to do this now, you have to utilize CFNotificationCenter and listen for a darwin notification (labeled: com.apple.springboard.lockcomplete). You can find the github repo with the sample project here: https://github.com/binarydev/ios-home-vs-lock-button

Credit for the iOS 7 fix goes out to wqq

like image 108
Jose Rafael Santiago Jr. Avatar answered Sep 21 '22 13:09

Jose Rafael Santiago Jr.


I have looked into this quite a bit so I would love to be wrong here if someone knows something I don't, but technically, there is no documented way to tell the difference between locking the device, and sending to background.

One thing you can check however, is the UIApplicationState during the transition from foreground to background. Locking a device will give UIApplicationStateInactive and moving the App to the background will give UIApplicationStateBackground. But, since this behaviour is not officially documented it may change in the future.

A basic example:

- (void)applicationDidEnterBackground:(UIApplication *)application {     UIApplicationState state = [[UIApplication sharedApplication] applicationState];     NSLog(@"Device state: %@", state);     switch (state) {         case UIApplicationStateActive:             /* ... */             break;         case UIApplicationStateInactive:             /* Device was/is locked  */             break;         case UIApplicationStateBackground:             /* User pressed home button or opened another App (from an alert/email/etc) */             break;     } } 

UIApplicationState - The running states of an application

typedef enum {     UIApplicationStateActive,        UIApplicationStateInactive,     UIApplicationStateBackground } 

UIApplicationState

Constants

UIApplicationStateActive - The application is running in the foreground and currently receiving events. Available in iOS 4.0 and later.

UIApplicationStateInactive - The application is running in the foreground but is not receiving events. This might happen as a result of an interruption or because the application is transitioning to or from the background.

UIApplicationStateBackground - The application is running in the background.


According to the UIApplicationDelegate Protocol Reference:

applicationWillResignActive: didEnterBackground: // ... willEnterForeground: applicationDidBecomeActive: 

are the only methods that ever get called in both situations.


According to the iOS 4.3 to iOS 5.0 API Diff, these are the ONLY changes regarding UIApplication or UIApplicationDelegate, so I couldn't find where they documented any of these notification changes:

UIApplication.h Added -[UIApplication setNewsstandIconImage:] Added UIApplication.userInterfaceLayoutDirection Added UIApplicationDelegate.window Added UIApplication(UINewsstand) Added UIApplicationLaunchOptionsNewsstandDownloadsKey Added UIRemoteNotificationTypeNewsstandContentAvailability Added UIUserInterfaceLayoutDirection Added UIUserInterfaceLayoutDirectionLeftToRight Added UIUserInterfaceLayoutDirectionRightToLeft 
like image 43
chown Avatar answered Sep 21 '22 13:09

chown