锁定解锁事件 iPhone
如何检测 iPhone 上的锁定/解锁事件? 假设它只适用于越狱设备,你能给我指出正确的 API 吗?
通过锁定事件,我的意思是显示或隐藏锁定屏幕(可能需要密码才能解锁,也可能不需要)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如何检测 iPhone 上的锁定/解锁事件? 假设它只适用于越狱设备,你能给我指出正确的 API 吗?
通过锁定事件,我的意思是显示或隐藏锁定屏幕(可能需要密码才能解锁,也可能不需要)。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(10)
您可以使用 Darwin 通知 ,监听事件。 根据我在越狱的 iOS 5.0.1 iPhone 4 上的测试,我认为以下事件之一可能正是您所需要的:
注意:根据海报的对我在这里回答的类似问题的评论,这也应该适用于未越狱的手机。
要使用此功能,请像这样注册事件(这仅注册上面的第一个事件,但您也可以为
lockcomplete
添加观察者):其中
lockStateChanged
是您的事件回调:lockstate
事件在设备锁定和解锁时发生,但lockcomplete
事件仅在设备锁定时触发。 确定事件是锁定事件还是解锁事件的另一种方法是使用notify_get_state()
。 对于锁定与解锁,您将获得不同的值,如此处所述。You can use Darwin notifications, to listen for the events. From my testing on a jailbroken iOS 5.0.1 iPhone 4, I think that one of these events might be what you need:
Note: according to the poster's comments to a similar question I answered here, this should work on a non-jailbroken phone, too.
To use this, register for the event like this (this registers for just the first event above, but you can add an observer for
lockcomplete
, too):where
lockStateChanged
is your event callback:The
lockstate
event occurs when the device is locked and unlocked, but thelockcomplete
event is only triggered when the device locks. Another way to determine whether the event is for a lock or unlock event is to usenotify_get_state()
. You'll get a different value for lock vs. unlock, as described here.绕回答案:
应用程序将在各种情况下退出活动被调用...并且从我的所有测试来看,即使您的应用程序在后台保持唤醒状态,也无法确定屏幕已锁定(CPU 速度不报告,总线速度保持不变,mach_time denom / numer 不变)...
但是,苹果似乎在设备锁定时关闭了加速计... 在屏幕锁定时启用 iPhone 加速计
(在 iPhone 4 上测试的 iOS4.2 有这种行为)
因此...
在您的应用程序委托中:
我知道...这是一种 hack,但到目前为止它对我来说就像一个魅力。 如果您发现任何阻止此功能运行的问题,请进行更新。
Round about answer:
Application will resign active gets called in all sorts of scenarios... and from all my testing, even if your application stays awake while backgrounded, there are no ways to determine that the screen is locked (CPU speed doesn't report, BUS speed remains the same, mach_time denom / numer doesn't change)...
However, it seems Apple does turn off the accelerometer when the device is locked... Enable iPhone accelerometer while screen is locked
(tested iOS4.2 on iPhone 4 has this behavior)
Thus...
In your application delegate:
I know... It's kind of a hack, but it has worked like a charm for me so far. Please update if you see any issues that prevent this from working.
有一种更漂亮的方法可以区分任务切换和屏幕锁定引发的
applicationWillResignActive:
回调,它甚至不涉及未记录的功能,例如加速度计状态。当应用程序移至后台时,首先向应用程序委托发送
applicationWillResignActive:
,然后发送applicationDidEnterBackground:
。 当应用程序因按锁定按钮或来电而中断时,不会调用后一个方法。 我们可以使用此信息来区分这两种情况。假设您希望在屏幕被锁定时在
screenLockActivated
方法中回调。 神奇之处在于:说明:
默认情况下,我们假设每次调用
applicationWillResignActive:
都是由于活动->非活动状态转换(如锁定屏幕时),但我们慷慨地让系统证明通过延迟对screenLockActivated
的调用,可以在超时(在本例中为单个运行循环周期)内实现相反的效果。 如果屏幕被锁定,系统将完成当前的运行循环周期,而不会触及任何其他委托方法。 但是,如果这是一个 active->background 状态转换,它还会在循环结束之前调用applicationDidEnterBackground:
,这允许我们简单地从那里取消先前安排的请求,从而阻止它避免在不应该的时候被调用。享受!
There is a prettier way of telling apart task switching and screen locking-originated
applicationWillResignActive:
callbacks which doesn't even involve undocumented features such as the accelerometer state.When the app is moving to the background, the app delegate is first sent an
applicationWillResignActive:
, then anapplicationDidEnterBackground:
. When the app is interrupted by pressing the Lock button or by an incoming phone call, the latter method is not called. We can use this information to distinguish between the two scenarios.Say you want to be called back in the
screenLockActivated
method if the screen gets locked. Here's the magic:Explanation:
By default, we assume that every call to
applicationWillResignActive:
is because of an active->inactive state transition (as when locking the screen) but we generously let the system prove the contrary within a timeout (in this case, a single runloop cycle) by delaying the call toscreenLockActivated
. In case the screen gets locked, the system finishes the current runloop cycle without touching any other delegate methods. If, however, this is an active->background state transition, it also invokesapplicationDidEnterBackground:
before the end of the cycle, which allows us to simply cancel the previously scheduled request from there, thus preventing it from being called when it's not supposed to.Enjoy!
截至撰写本文时,有两种相当可靠的方法来检测设备锁定:
数据保护
通过启用 数据保护权利 您的应用可以订阅
applicationProtectedDataWillBecomeUnavailable:
和
applicationProtectedDataDidBecomeAvailable:
通知,用于以高概率确定使用密码/TouchID 身份验证的设备何时锁定/解锁。 确定设备是否使用密码/TouchIDLAContext
可以查询。注意事项:此方法依赖于手机被锁定时“受保护的数据变得不可用”。 当手机使用 TouchID 并按下睡眠/锁定按钮时,手机将被锁定,受保护的数据将变得不可用,并且将立即需要密码才能再次解锁。 这意味着受保护的数据变得不可用本质上表明手机已被锁定。 当某人仅使用密码时,情况不一定如此,因为他们可以将“需要密码”时间设置为从立即到4小时之间的任何时间嗯>。 在这种情况下,手机将报告能够处理受保护的数据,但锁定手机不会导致受保护的数据在相当长的时间内变得不可用。
生命周期计时
如果您的应用程序位于前台,两个生命周期事件之间的时间差将会发生明显变化
UIApplicationWillResignActiveNotification
和UIApplicationDidEnterBackgroundNotification
取决于触发它们的原因。(此功能已在 iOS 10 中进行测试,可能会在未来版本中更改)
按主页按钮会导致两者之间出现显着延迟(即使启用了“简化运动”设置):
在应用程序运行时锁定设备打开会在两个事件之间产生更小的延迟(<~0.2s):
As of the time of writing there are two fairly reliable ways to detect device locking:
Data Protection
By enabling the Data Protection entitlement your app can subscribe to the
applicationProtectedDataWillBecomeUnavailable:
andapplicationProtectedDataDidBecomeAvailable:
notifications to determine with high probability when a device that uses passcode/TouchID Authentication is locked/unlocked. To determine if a device uses a passcode/TouchIDLAContext
can be queried.Caveats: This method relies on the "protected data becoming unavailable" coinciding with the phone being locked. When the phone is using TouchID and the sleep/lock button is pressed then the phone is locked, protected data becomes unavailable, and a passcode will immediately be required to unlock it again. This means that protected data becoming unavailable essentially indicates that the phone has been locked. This is not necessarily true when someone is using just a passcode since they can set the "requires passcode" time to anywhere from immediately to something like 4 hours. In this case the phone will report being able to handle protected data but locking the phone will not result in protected data becoming unavailable for quite some time.
Lifecycle Timing
If your app is in the foreground there will be a noticeable change in time difference between the two lifecycle events
UIApplicationWillResignActiveNotification
andUIApplicationDidEnterBackgroundNotification
depending on what triggers them.(This was tested in iOS 10 and may change in future releases)
Pressing the home button results in a significant delay between the two (even when the Reduced Motion setting is enabled):
Locking the device while the app is open creates a more trivial (<~0.2s) delay between the two events:
在 iOS 8 中,您锁定屏幕或按主页按钮,所有这些都会使应用程序在后台推送,但您不知道哪个操作员会导致这种情况。 我的解决方案与Nits007ak相同,使用notify_register_dispatch来获取状态。
只要应用程序在前台或后台运行。 不挂起,就可以获得这个事件。
您可以使用notify_token作为notify_get_state的参数来获取任何地方的当前状态,当您想知道状态并且屏幕状态不变时,这非常有用。
in iOS 8, you lock the screen or push the home button, all of those make app push in background, but you don't know which operator result in this. My solution same with Nits007ak,use notify_register_dispatch to get state.
As long as the app is running, in foreground or background. not suspend, you can get this event.
And you can use notify_token as parameter of notify_get_state to get current state anywhere, this is useful when you want know the state and the screen state don't change.
如果设置了密码,则可以在 AppDelegate 中使用这些事件
If passcode is set, you can use these event in AppDelegate
在使用此代码之前只需导入 #import notify.h 即可。 享受!!
Just import #import notify.h before using this code. enjoy!!
通过大量的试验和错误,发现监视黑屏、锁定完成和锁定状态事件可以提供一致的锁屏指示器。 您需要监视状态转换。
要让屏幕锁定指示器在后台运行,您需要在应用程序启动时调用以下命令来实现后台处理。
From a lot of trial and error, discovered monitoring the blank screen, lock complete and lock state events gives a consistent lock screen indicator. You'll need to monitor a state transition.
To have the screen lock indicators run in the background, you need to implement background processing calling the following upon app launching.
如果您的应用程序正在运行并且用户锁定设备,您的应用程序委托将收到“应用程序将退出活动:”的调用。 如果您的应用程序在锁定时运行,则当设备解锁时,它将收到“应用程序已变为活动状态:”的调用。 但是,如果用户接到电话然后选择忽略它,您的应用程序也会收到相同的电话。 据我所知,你无法分辨出差异。
如果您的应用程序在任何这些时间都没有运行,则无法收到通知,因为您的应用程序没有运行。
If your app is running and the user locks the device your app delegate will receive a call to 'application Will Resign Active:'. If your app was running when locked, it will receive a call to 'application Did Become Active:' when the device is unlocked. But you get the same calls to your app if the user gets a phone call and then chooses to ignore it. You can't tell the difference as far as I know.
And if your app wasn't running at any of these times there is no way to be notified since your app isn't running.
获取屏幕锁定和解锁事件的最简单方法是在视图控制器中使用 NSNotificationCenter 添加事件观察器。 我在 viewdidload 方法中添加了以下观察者。 这就是我所做的:
然后我将以下选择器添加到视图控制器中。 当屏幕解锁时,将调用此选择器。
如果您想在屏幕锁定时检测事件,可以将 UIApplicationWillEnterForegroundNotification 替换为 UIApplicationDidEnterBackgroundNotification。
The simplest way to get screen lock and unlock events are by adding event observers using NSNotificationCenter in your viewcontroller. I added the following observer in the viewdidload method. This is what i did:
Then I added the following selector to the viewcontroller. This selector will get called when the screen is unlocked.
If you want to detect the event when screen gets locked, you can replace UIApplicationWillEnterForegroundNotification with UIApplicationDidEnterBackgroundNotification.