是否可以区分锁定设备和将应用程序发送到后台?

时间:2011-10-13 12:44:07

标签: ios cocoa-touch

我有一个应用程序需要在使用“主页”按钮将其发送到后台时执行某些操作,而使用顶部硬件按钮锁定设备时需要执行其他操作。解决这些要求的标准方法是UIApplication发出的通知和委托方法。在iOS 4上,它们看起来像这样:

// 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.

换句话说,在锁定和后台之间很容易区分。在iOS 5上,行为发生了变化:

// 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.

请注意,即使(非)锁定设备,现在也会发送didEnterBackgroundwillEnterForeground通知,从而无法在锁定和后台之间进行分析。这个变化是否记录在某处?这是回归吗?你知道另一种区分这两种情况的方法吗?

5 个答案:

答案 0 :(得分:28)

iOS 6

在我通过模拟器进行的初步测试中,使用

检查应用程序状态
[[UIApplication sharedApplication] applicationState]

中的任何一个

- (void)applicationWillEnterForeground:(UIApplication *)application

- (void)applicationDidEnterBackground:(UIApplication *)application

允许您区分锁定设备的呼叫和仅切换回主屏幕。锁定屏幕将返回1(UIApplicationStateInactive),而主页按钮按下将注册为2(UIApplicationStateBackground)。

它似乎是一致的,应该在iOS设备上运行,就像在模拟器中一样可靠。

iOS 7

iOS 6方法在iOS 7中不再有效。为了立即执行此操作,您必须使用CFNotificationCenter并侦听darwin通知(标记为:com.apple.springboard.lockcomplete)。您可以在此处找到带有示例项目的github repo:https://github.com/binarydev/ios-home-vs-lock-button

iOS 7修复的信用额度为wqq

答案 1 :(得分:7)

我已经对此进行了相当多的研究,所以如果有人知道我不知道的事情,我希望在这里出错,但从技术上讲,没有记录的方式来区分锁定之间的区别。设备,并发送到后台。

然而,您可以检查的一件事是从前景到后台过渡期间的UIApplicationState。锁定设备将提供UIApplicationStateInactive,将应用移至后台将显示UIApplicationStateBackground。但是,由于此行为未正式记录,因此将来可能会发生变化。

一个基本的例子:

- (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 - 应用程序的运行状态

typedef enum {
    UIApplicationStateActive,   
    UIApplicationStateInactive,
    UIApplicationStateBackground
}
     

UIApplicationState

     

<强>常量

  UIApplicationStateActive - 申请表   正在前台运行并且当前正在接收事件。可得到   在iOS 4.0及更高版本中。

     

UIApplicationStateInactive - 应用程序正在运行   前景,但没有接收事件。结果可能会发生这种情况   中断或因为应用程序正在转换为或   来自背景。

     

UIApplicationStateBackground - 申请表是   在后台运行。


根据UIApplicationDelegate Protocol Reference

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

是在这两种情况下被调用的唯一方法。


根据iOS 4.3 to iOS 5.0 API Diff,这些是关于UIApplicationUIApplicationDelegate的唯一更改,因此我无法找到他们记录这些通知更改的位置:

UIApplication.h
Added -[UIApplication setNewsstandIconImage:]
Added UIApplication.userInterfaceLayoutDirection
Added UIApplicationDelegate.window
Added UIApplication(UINewsstand)
Added UIApplicationLaunchOptionsNewsstandDownloadsKey
Added UIRemoteNotificationTypeNewsstandContentAvailability
Added UIUserInterfaceLayoutDirection
Added UIUserInterfaceLayoutDirectionLeftToRight
Added UIUserInterfaceLayoutDirectionRightToLeft

答案 2 :(得分:3)

这更像是一种解决方法/黑客,但根据我的经验,这是非常可靠的。 当设备被屏幕锁定时(不仅仅是主页按钮,如果这是一个单词:)) - 绑定网络(UDP)套接字被破坏。 我之前使用的是GCDAsyncUDPSocket(也是AsyncUDPSocket),它们都会在设备关闭时可靠地触发网络/损坏的管道错误。 在我的情况下,无论如何我需要UDP套接字,对于其他应用程序它可能有点臭,但是,如果你真的需要在这里进行区分,只需在没有任何动作的情况下绑定/侦听UDP套接字就不会太糟糕。

本说明将[自毁];是5分钟(所以Apple不会发现)。

答案 3 :(得分:2)

这是Apple的iOS编程指南所说的:

  

按下“睡眠/唤醒”按钮是另一种中断   导致您的应用暂时停用。当用户按下时   此按钮,系统禁用触摸事件,将应用程序移动到   background,但设置应用程序的applicationState属性的值   到UIApplicationStateInactive(相对于   UIApplicationStateBackground),最后锁定屏幕。

http://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

因此,您应该查看UIApplicationapplicationState的{​​{1}}媒体资源。如果是applicationDidEnterBackground:,则用户按下主页按钮。但如果UIApplicationStateBackground用户锁定了设备。

答案 4 :(得分:1)

thread about this issue on Apple Developer Forums(仅限注册开发人员,抱歉)。要点是新行为是设计的。有一个新的API功能要求区分这两个用例,但没有任何工作。