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

zou*_*oul 38 cocoa-touch ios

我有一个应用程序,当使用主页按钮将其发送到后台时需要执行某些操作,而当使用顶部硬件按钮锁定设备时,需要执行其他操作.解决这些要求的标准方法是发出的通知和委托方法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.
Run Code Online (Sandbox Code Playgroud)

换句话说,在锁定和后台之间很容易区分.在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.
Run Code Online (Sandbox Code Playgroud)

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

Jos*_*Jr. 28

iOS 6

在我通过模拟器进行的初步测试中,检查应用程序状态

[[UIApplication sharedApplication] applicationState]
Run Code Online (Sandbox Code Playgroud)

在任何一个

- (void)applicationWillEnterForeground:(UIApplication *)application

- (void)applicationDidEnterBackground:(UIApplication *)application
Run Code Online (Sandbox Code Playgroud)

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

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

IOS 7

在iOS 6的方法不再是iOS的7作品现在,为了做到这一点,你必须利用CFNotificationCenter的,并听取了达尔文的通知(标注:com.apple.springboard.lockcomplete).你可以在这里找到带有示例项目的github repo:https://github.com/binarydev/ios-home-vs-lock-button

iOS 7修复的功劳归于wqq

  • 实际上,纯粹来自这些方法的名称,你不应该在`willEnterForeground:'中肯定地说,在不同的情况下状态是否会返回`1`或'2`,而状态*应该*永远是`didEnterBackground中的`2`:`.我不会依赖这种行为,即使对于下一个小的iOS版本也是如此. (2认同)
  • 实际上,无论是锁定屏幕还是不离开应用程序,或者实际通过主页按钮离开应用程序,didEnterBackground始终从5.0开始调用.我已经在iPad 1上进行了测试,并且两者都表现出相同的行为.这是因为当您锁定屏幕时,它将调用didEnterBackground,但UIApplicationStatus将是UIApplicationStateInactive,因为应用程序仍位于锁定屏幕后面的前景中.以任何方式离开应用程序都会产生UIApplicationStateBackground.我不认为这可能会在不久的将来版本中发生变化. (2认同)
  • 我可以确认这适用于iOS 5和iOS 6设备.谢谢! (2认同)

cho*_*own 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

UIApplicationState - 应用程序的运行状态

typedef enum {
    UIApplicationStateActive,   
    UIApplicationStateInactive,
    UIApplicationStateBackground
}
Run Code Online (Sandbox Code Playgroud)

UIApplicationState

常量

UIApplicationStateActive - 应用程序在前台运行并且当前正在接收事件.适用于iOS 4.0及更高版本.

UIApplicationStateInactive - 应用程序在前台运行但未接收事件.这可能是由于中断或应用程序正在转换到后台或从后台转换而发生的.

UIApplicationStateBackground - 应用程序在后台运行.


根据UIApplicationDelegate协议参考:

applicationWillResignActive:
didEnterBackground:
// ...
willEnterForeground:
applicationDidBecomeActive:
Run Code Online (Sandbox Code Playgroud)

是两种情况下唯一被调用的方法.


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

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

  • 只是一个FYI - 这个行为在iOS 8 + Swift中已经改变了.应用程序在前台时锁定设备现在使用`UIApplicationStateBackground` (2认同)