检测应用程序何时从锁屏到iOS7上的其他应用程序变为活动状态

时间:2013-10-18 14:53:15

标签: ios cocoa-touch background multitasking uiapplicationdelegate

我的应用在从锁定屏幕变为活动状态时(在激活时锁定)或从其他任何设备变为活动状态时会有不同的行为。

在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上,请参阅here

2 个答案:

答案 0 :(得分:10)

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

似乎没有办法在iOS 7上检测应用程序的启动位置,但 是一种检测你是否 的方法锁屏与跳板。诀窍是在applicationDidEnterBackground中读取屏幕亮度。当应用程序由于按下锁定按钮或自动锁定超时而到达背景时,iOS 7上的亮度将为0.0。否则,将是> 0按下主页按钮或从多任务选择器或通知中心启动另一个应用程序时。

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

现在我有一个拿着这个信息的ivar,我可以在applicationWillEnterForeground中使用它来确定我的应用流程。

- (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以检测您来自哪里,此解决方案可以回答类似但不完全相同的问题,即当应用程序背景时您的去向。例如,由于屏幕锁定超时,应用程序可能是背景,但随后另一个应用程序的通知唤醒了设备,用户直接从锁定屏幕转到那里,然后返回到我的应用程序。我的应用程序将确定用户进入锁屏的背景,但当他们回来时,他们实际上来自活动屏幕。对于我的应用程序,这种差异可以忽略不计,但您的milage可能会有所不同。

那么旧的操作系统支持呢?我的应用程序也支持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;
}

我不确定亮度读数的可靠性,或者它是否会在未来的操作系统版本中发生变化,但与此同时,这个黑客似乎是我们能得到的最好的。希望这会有所帮助。

答案 1 :(得分:-1)

实际上,在变为活动状态时设置应用行为的唯一正确方法是通过应用委托方法。

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