我有一个应用程序需要在使用“主页”按钮将其发送到后台时执行某些操作,而使用顶部硬件按钮锁定设备时需要执行其他操作。解决这些要求的标准方法是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.
请注意,即使(非)锁定设备,现在也会发送didEnterBackground
和willEnterForeground
通知,从而无法在锁定和后台之间进行分析。这个变化是否记录在某处?这是回归吗?你知道另一种区分这两种情况的方法吗?
答案 0 :(得分:28)
在我通过模拟器进行的初步测试中,使用
检查应用程序状态[[UIApplication sharedApplication] applicationState]
中的任何一个
- (void)applicationWillEnterForeground:(UIApplication *)application
- (void)applicationDidEnterBackground:(UIApplication *)application
允许您区分锁定设备的呼叫和仅切换回主屏幕。锁定屏幕将返回1(UIApplicationStateInactive),而主页按钮按下将注册为2(UIApplicationStateBackground)。
它似乎是一致的,应该在iOS设备上运行,就像在模拟器中一样可靠。
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,这些是关于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
答案 2 :(得分:3)
这更像是一种解决方法/黑客,但根据我的经验,这是非常可靠的。 当设备被屏幕锁定时(不仅仅是主页按钮,如果这是一个单词:)) - 绑定网络(UDP)套接字被破坏。 我之前使用的是GCDAsyncUDPSocket(也是AsyncUDPSocket),它们都会在设备关闭时可靠地触发网络/损坏的管道错误。 在我的情况下,无论如何我需要UDP套接字,对于其他应用程序它可能有点臭,但是,如果你真的需要在这里进行区分,只需在没有任何动作的情况下绑定/侦听UDP套接字就不会太糟糕。
本说明将[自毁];是5分钟(所以Apple不会发现)。
答案 3 :(得分:2)
这是Apple的iOS编程指南所说的:
按下“睡眠/唤醒”按钮是另一种中断 导致您的应用暂时停用。当用户按下时 此按钮,系统禁用触摸事件,将应用程序移动到 background,但设置应用程序的applicationState属性的值 到UIApplicationStateInactive(相对于 UIApplicationStateBackground),最后锁定屏幕。
因此,您应该查看UIApplication
中applicationState
的{{1}}媒体资源。如果是applicationDidEnterBackground:
,则用户按下主页按钮。但如果UIApplicationStateBackground
用户锁定了设备。
答案 4 :(得分:1)
有thread about this issue on Apple Developer Forums(仅限注册开发人员,抱歉)。要点是新行为是设计的。有一个新的API功能要求区分这两个用例,但没有任何工作。