在iOS7上检测应用程序何时从locking屏幕变为活动状态

从locking屏幕变为活动状态时(locking状态),我的应用程序具有不同的行为,或者从其他任何情况变为活动状态。

在iOS 6和更低,我可以检测到这一点

UIApplicationState state = [[UIApplication sharedApplication] applicationState]; if (UIApplicationStateInactive == state) // Coming from locked screen (iOS 6) else // Coming from Springboard, another app, etc... 

但在iOS 7上,两种情况下的状态值均为UIApplicationStateBackground 。 这是预期的行为? 如何正确检测应用程序是否从锁屏启动?

注册的开发者,我已经在NDA解除之前在devforums上发布了,请看这里

我能够弄清楚这一点,迄今似乎是可靠的。 它只适用于设备,而不是模拟器,并且已经在运行iOS 7的iPhone 5s,5和4S上进行了testing。

似乎没有办法来检测从iOS 7上启动应用程序的位置,但有一种方法可以检测是否要进入锁屏vs跳板。 诀窍是读取applicationDidEnterBackground的屏幕亮度。 当应用程序由于按下lockingbutton或自动locking超时而击中了背景时,iOS 7上的亮度将为0.0。否则,当按下主屏幕button或从多任务select器启动另一个应用程序时,该值将大于0或通知中心。

 - (void)applicationDidEnterBackground:(UIApplication *)application { CGFloat screenBrightness = [[UIScreen mainScreen] brightness]; NSLog(@"Screen brightness: %f", screenBrightness); self.backgroundedToLockScreen = screenBrightness <= 0.0; } 

现在我有一个伊娃拥有这个信息,我可以在applicationWillEnterForeground使用它来确定我的应用程序stream。

 - (void)applicationWillEnterForeground:(UIApplication *)application { if (self.backgroundedToLockScreen) { ... // app was backgrounded to lock screen } else { ... // app was backgrounded on purpose by tapping the home button or switching apps. } self.backgroundedToLockScreen = NO; } 

这与iOS 6的行为并不完全相同。 在iOS 6上,您可以检查UIApplicationState以检测您来自哪里,并且该解决scheme回答类似但不完全相同的问题,即应用程序背景显示时的位置。 例如,由于屏幕locking超时,应用程序可能是后台,但是另一个应用程序的通知会唤醒设备,用户直接从locking屏幕去到那里,然后返回到我的应用程序。 我的应用程序可能已经确定用户进入了锁屏,但是当他们回来时,他们实际上来自活动屏幕。 对于我的应用程序,这种差异是微不足道的,但你的微软可能会有所不同。

那么更旧的操作系统支持呢? 我的应用程序也支持iOS 6,所以我也需要得到旧的行为。 简单。 只是应用程序状态监视到前台方法:

 - (void)applicationWillEnterForeground:(UIApplication *)application { UIApplicationState state = [[UIApplication sharedApplication] applicationState]; if (UIApplicationStateInactive == state || // detect if coming from locked screen (iOS 6) self.backgroundedToLockScreen) // detect if backgrounded to the locked screen (iOS 7) { ... // app is coming from or was backgrounded to lock screen } else { ... // app was backgrounded on purpose by tapping the home button or switching apps } self.backgroundedToLockScreen = NO; } 

我不确定亮度读数有多可靠,或者在未来的操作系统版本中是否会发生变化,但同时,这种破解似乎是最好的。 希望这可以帮助。

实际上,只有通过应用程序委托方法来设置您的应用程序行为时,正确的方式。

 - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } 

这两个应用程序在后台运行时调用,并通过多任务UI或通话或其他中断后变为活动状态。

当从Springboard打开应用程序并且不在后台运行时,调用此方法:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. return YES; }