锁定解锁事件 iPhone

发布于 2024-07-15 17:31:39 字数 121 浏览 7 评论 0 原文

如何检测 iPhone 上的锁定/解锁事件? 假设它只适用于越狱设备,你能给我指出正确的 API 吗?

通过锁定事件,我的意思是显示或隐藏锁定屏幕(可能需要密码才能解锁,也可能不需要)。

How can I detect lock/unlock events on the iPhone? Assuming it's only possible for jailbroken devices, can you point me to the correct API?

By lock events, I mean showing or hiding the Lock Screen (which might need a password to unlock, or not).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

乱了心跳 2024-07-22 17:31:39

您可以使用 Darwin 通知 ,监听事件。 根据我在越狱的 iOS 5.0.1 iPhone 4 上的测试,我认为以下事件之一可能正是您所需要的:

com.apple.springboard.lockstate
com.apple.springboard.lockcomplete

注意:根据海报的对我在这里回答的类似问题的评论,这也应该适用于未越狱的手机。

要使用此功能,请像这样注册事件(这仅注册上面的第一个事件,但您也可以为 lockcomplete 添加观察者):

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                (void*)self, // observer (can be NULL)
                                lockStateChanged, // callback
                                CFSTR("com.apple.springboard.lockstate"), // event name
                                NULL, // object
                                CFNotificationSuspensionBehaviorDeliverImmediately);

其中 lockStateChanged 是您的事件回调:

static void lockStateChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
    NSLog(@"event received!");
    if (observer != NULL) {
        MyClass *this = (MyClass*)observer;
    }

    // you might try inspecting the `userInfo` dictionary, to see 
    //  if it contains any useful info
    if (userInfo != nil) {
        CFShow(userInfo);
    }
}

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:

com.apple.springboard.lockstate
com.apple.springboard.lockcomplete

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):

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                (void*)self, // observer (can be NULL)
                                lockStateChanged, // callback
                                CFSTR("com.apple.springboard.lockstate"), // event name
                                NULL, // object
                                CFNotificationSuspensionBehaviorDeliverImmediately);

where lockStateChanged is your event callback:

static void lockStateChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
    NSLog(@"event received!");
    if (observer != NULL) {
        MyClass *this = (MyClass*)observer;
    }

    // you might try inspecting the `userInfo` dictionary, to see 
    //  if it contains any useful info
    if (userInfo != nil) {
        CFShow(userInfo);
    }
}

The lockstate event occurs when the device is locked and unlocked, but the lockcomplete event is only triggered when the device locks. Another way to determine whether the event is for a lock or unlock event is to use notify_get_state(). You'll get a different value for lock vs. unlock, as described here.

梦纸 2024-07-22 17:31:39

绕回答案:

应用程序将在各种情况下退出活动被调用...并且从我的所有测试来看,即使您的应用程序在后台保持唤醒状态,也无法确定屏幕已锁定(CPU 速度不报告,总线速度保持不变,mach_time denom / numer 不变)...

但是,苹果似乎在设备锁定时关闭了加速计... 在屏幕锁定时启用 iPhone 加速计
(在 iPhone 4 上测试的 iOS4.2 有这种行为)

因此...

在您的应用程序委托中:

- (void)applicationWillResignActive:(UIApplication *)application
{
    NSLog(@"STATUS - Application will Resign Active");
    // Start checking the accelerometer (while we are in the background)
    [[UIAccelerometer sharedAccelerometer] setDelegate:self];
    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:1]; // Ping every second
    _notActiveTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(deviceDidLock) userInfo:nil repeats:NO]; // 2 seconds for wiggle

}
//Deprecated in iOS5
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    NSLog(@"STATUS - Update from accelerometer");
    [_notActiveTimer invalidate];
    _notActiveTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(deviceDidLock) userInfo:nil repeats:NO];
}

- (void)deviceDidLock
{
    NSLog(@"STATUS - Device locked!");
    [[UIAccelerometer sharedAccelerometer] setDelegate:nil];
    _notActiveTimer = nil;
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    NSLog(@"STATUS - Application did become active");
    [[UIAccelerometer sharedAccelerometer] setDelegate:nil];
    [_notActiveTimer invalidate];
    _notActiveTimer = nil;
}

我知道...这是一种 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:

- (void)applicationWillResignActive:(UIApplication *)application
{
    NSLog(@"STATUS - Application will Resign Active");
    // Start checking the accelerometer (while we are in the background)
    [[UIAccelerometer sharedAccelerometer] setDelegate:self];
    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:1]; // Ping every second
    _notActiveTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(deviceDidLock) userInfo:nil repeats:NO]; // 2 seconds for wiggle

}
//Deprecated in iOS5
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    NSLog(@"STATUS - Update from accelerometer");
    [_notActiveTimer invalidate];
    _notActiveTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(deviceDidLock) userInfo:nil repeats:NO];
}

- (void)deviceDidLock
{
    NSLog(@"STATUS - Device locked!");
    [[UIAccelerometer sharedAccelerometer] setDelegate:nil];
    _notActiveTimer = nil;
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    NSLog(@"STATUS - Application did become active");
    [[UIAccelerometer sharedAccelerometer] setDelegate:nil];
    [_notActiveTimer invalidate];
    _notActiveTimer = nil;
}

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.

梓梦 2024-07-22 17:31:39

有一种更漂亮的方法可以区分任务切换和屏幕锁定引发的 applicationWillResignActive: 回调,它甚至不涉及未记录的功能,例如加速度计状态。

当应用程序移至后台时,首先向应用程序委托发送 applicationWillResignActive:,然后发送 applicationDidEnterBackground:。 当应用程序因按锁定按钮或来电而中断时,不会调用后一个方法。 我们可以使用此信息来区分这两种情况。

假设您希望在屏幕被锁定时在 screenLockActivated 方法中回调。 神奇之处在于:

- (void)applicationWillResignActive:(UIApplication*)aApplication
{
    [self performSelector:@selector(screenLockActivated)
               withObject:nil
               afterDelay:0];
}

- (void)applicationDidEnterBackground:(UIApplication*)aApplication
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
}

- (void)screenLockActivated
{
    NSLog(@"yaay");
}

说明:

默认情况下,我们假设每次调用 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 an applicationDidEnterBackground:. 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:

- (void)applicationWillResignActive:(UIApplication*)aApplication
{
    [self performSelector:@selector(screenLockActivated)
               withObject:nil
               afterDelay:0];
}

- (void)applicationDidEnterBackground:(UIApplication*)aApplication
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
}

- (void)screenLockActivated
{
    NSLog(@"yaay");
}

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 to screenLockActivated. 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 invokes applicationDidEnterBackground: 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!

野味少女 2024-07-22 17:31:39

截至撰写本文时,有两种相当可靠的方法来检测设备锁定:


数据保护

通过启用 数据保护权利 您的应用可以订阅 applicationProtectedDataWillBecomeUnavailable:applicationProtectedDataDidBecomeAvailable: 通知,用于以高概率确定使用密码/TouchID 身份验证的设备何时锁定/解锁。 确定设备是否使用密码/TouchID LAContext可以查询。

注意事项:此方法依赖于手机被锁定时“受保护的数据变得不可用”。 当手机使用 TouchID 并按下睡眠/锁定按钮时,手机将被锁定,受保护的数据将变得不可用,并且将立即需要密码才能再次解锁。 这意味着受保护的数据变得不可用本质上表明手机已被锁定。 当某人仅使用密码时,情况不一定如此,因为他们可以将“需要密码”时间设置为从立即4小时之间的任何时间嗯>。 在这种情况下,手机将报告能够处理受保护的数据,但锁定手机不会导致受保护的数据在相当长的时间内变得不可用。


生命周期计时

如果您的应用程序位于前台,两个生命周期事件之间的时间差将会发生明显变化 UIApplicationWillResignActiveNotificationUIApplicationDidEnterBackgroundNotification 取决于触发它们的原因。

(此功能已在 iOS 10 中进行测试,可能会在未来版本中更改)

按主页按钮会导致两者之间出现显着延迟(即使启用了“简化运动”设置):

15:23:42.517 willResignActive
15:23:43.182 didEnterBackground
15:23:43.184 difference: 0.666346

在应用程序运行时锁定设备打开会在两个事件之间产生更小的延迟(<~0.2s):

15:22:59.236 willResignActive
15:22:59.267 didEnterBackground
15:22:59.267 difference: 0.031404

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: and applicationProtectedDataDidBecomeAvailable: 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/TouchID LAContext 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 and UIApplicationDidEnterBackgroundNotification 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):

15:23:42.517 willResignActive
15:23:43.182 didEnterBackground
15:23:43.184 difference: 0.666346

Locking the device while the app is open creates a more trivial (<~0.2s) delay between the two events:

15:22:59.236 willResignActive
15:22:59.267 didEnterBackground
15:22:59.267 difference: 0.031404
无风消散 2024-07-22 17:31:39

在 iOS 8 中,您锁定屏幕或按主页按钮,所有这些都会使应用程序在后台推送,但您不知道哪个操作员会导致这种情况。 我的解决方案与Nits007ak相同,使用notify_register_dispatch来获取状态。

#import <notify.h>
        int notify_token
        notify_register_dispatch("com.apple.springboard.lockstate",
                             ¬ify_token,
                             dispatch_get_main_queue(),
                             ^(int token)
                             {
                                 uint64_t state = UINT64_MAX;
                                 notify_get_state(token, &state);
                                 if(state == 0) {
                                     NSLog(@"unlock device");
                                 } else {
                                     NSLog(@"lock device");
                                 }
                             }
                             );

只要应用程序在前台或后台运行。 不挂起,就可以获得这个事件。

您可以使用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.

#import <notify.h>
        int notify_token
        notify_register_dispatch("com.apple.springboard.lockstate",
                             ¬ify_token,
                             dispatch_get_main_queue(),
                             ^(int token)
                             {
                                 uint64_t state = UINT64_MAX;
                                 notify_get_state(token, &state);
                                 if(state == 0) {
                                     NSLog(@"unlock device");
                                 } else {
                                     NSLog(@"lock device");
                                 }
                             }
                             );

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.

2024-07-22 17:31:39

如果设置了密码,则可以在 AppDelegate 中使用这些事件

-(void)applicationProtectedDataWillBecomeUnavailable:(UIApplication *)application
{
}

- (void)applicationProtectedDataDidBecomeAvailable:(UIApplication *)application
{
}

If passcode is set, you can use these event in AppDelegate

-(void)applicationProtectedDataWillBecomeUnavailable:(UIApplication *)application
{
}

- (void)applicationProtectedDataDidBecomeAvailable:(UIApplication *)application
{
}
雨的味道风的声音 2024-07-22 17:31:39

在使用此代码之前只需导入 #import notify.h 即可。 享受!!

-(void)registerAppforDetectLockState {

    int notify_token;
        notify_register_dispatch("com.apple.springboard.lockstate", ¬ify_token,dispatch_get_main_queue(), ^(int token) {

        uint64_t state = UINT64_MAX;
        notify_get_state(token, &state);

        if(state == 0) {
            NSLog(@"unlock device");
        } else {
            NSLog(@"lock device");
        }

        NSLog(@"com.apple.springboard.lockstate = %llu", state);
        UILocalNotification *notification = [[UILocalNotification alloc]init];
        notification.repeatInterval = NSDayCalendarUnit;
        [notification setAlertBody:@"Hello world!! I come becoz you lock/unlock your device :)"];
        notification.alertAction = @"View";
        notification.alertAction = @"Yes";
        [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:1]];
        notification.soundName = UILocalNotificationDefaultSoundName;
        [notification setTimeZone:[NSTimeZone  defaultTimeZone]];

        [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

    });
}

Just import #import notify.h before using this code. enjoy!!

-(void)registerAppforDetectLockState {

    int notify_token;
        notify_register_dispatch("com.apple.springboard.lockstate", ¬ify_token,dispatch_get_main_queue(), ^(int token) {

        uint64_t state = UINT64_MAX;
        notify_get_state(token, &state);

        if(state == 0) {
            NSLog(@"unlock device");
        } else {
            NSLog(@"lock device");
        }

        NSLog(@"com.apple.springboard.lockstate = %llu", state);
        UILocalNotification *notification = [[UILocalNotification alloc]init];
        notification.repeatInterval = NSDayCalendarUnit;
        [notification setAlertBody:@"Hello world!! I come becoz you lock/unlock your device :)"];
        notification.alertAction = @"View";
        notification.alertAction = @"Yes";
        [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:1]];
        notification.soundName = UILocalNotificationDefaultSoundName;
        [notification setTimeZone:[NSTimeZone  defaultTimeZone]];

        [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

    });
}
隐诗 2024-07-22 17:31:39

通过大量的试验和错误,发现监视黑屏、锁定完成和锁定状态事件可以提供一致的锁屏指示器。 您需要监视状态转换。

// call back
void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
    // notification comes in order of
    // "com.apple.springboard.hasBlankedScreen" notification
    // "com.apple.springboard.lockcomplete" notification only if locked
    // "com.apple.springboard.lockstate" notification

    AppDelegate *appDelegate = CFBridgingRelease(observer);

    NSString *eventName = (__bridge NSString*)name;
    NSLog(@"Darwin notification NAME = %@",name);

    if([eventName isEqualToString:@"com.apple.springboard.hasBlankedScreen"])
    {
        NSLog(@"SCREEN BLANK");

        appDelegate.bDeviceLocked = false; // clear
    }
    else if([eventName isEqualToString:@"com.apple.springboard.lockcomplete"])
    {
        NSLog(@"DEVICE LOCK");

        appDelegate.bDeviceLocked = true; // set
    }
    else if([eventName isEqualToString:@"com.apple.springboard.lockstate"])
    {
        NSLog(@"LOCK STATUS CHANGE");

        if(appDelegate.bDeviceLocked) // if a lock, is set
        {
            NSLog(@"DEVICE IS LOCKED");
        }
        else
        {
            NSLog(@"DEVICE IS UNLOCKED");
        }
    }
}

-(void)registerforDeviceLockNotif
{
    // screen and lock notifications
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    CFBridgingRetain(self), // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.springboard.hasBlankedScreen"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);

    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    CFBridgingRetain(self), // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.springboard.lockcomplete"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);

    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    CFBridgingRetain(self), // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.springboard.lockstate"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);
}

要让屏幕锁定指示器在后台运行,您需要在应用程序启动时调用以下命令来实现后台处理。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.backgroundTaskIdentifier =
    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{

        [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier];
    }];

    [self registerforDeviceLockNotif];
}

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.

// call back
void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
    // notification comes in order of
    // "com.apple.springboard.hasBlankedScreen" notification
    // "com.apple.springboard.lockcomplete" notification only if locked
    // "com.apple.springboard.lockstate" notification

    AppDelegate *appDelegate = CFBridgingRelease(observer);

    NSString *eventName = (__bridge NSString*)name;
    NSLog(@"Darwin notification NAME = %@",name);

    if([eventName isEqualToString:@"com.apple.springboard.hasBlankedScreen"])
    {
        NSLog(@"SCREEN BLANK");

        appDelegate.bDeviceLocked = false; // clear
    }
    else if([eventName isEqualToString:@"com.apple.springboard.lockcomplete"])
    {
        NSLog(@"DEVICE LOCK");

        appDelegate.bDeviceLocked = true; // set
    }
    else if([eventName isEqualToString:@"com.apple.springboard.lockstate"])
    {
        NSLog(@"LOCK STATUS CHANGE");

        if(appDelegate.bDeviceLocked) // if a lock, is set
        {
            NSLog(@"DEVICE IS LOCKED");
        }
        else
        {
            NSLog(@"DEVICE IS UNLOCKED");
        }
    }
}

-(void)registerforDeviceLockNotif
{
    // screen and lock notifications
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    CFBridgingRetain(self), // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.springboard.hasBlankedScreen"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);

    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    CFBridgingRetain(self), // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.springboard.lockcomplete"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);

    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    CFBridgingRetain(self), // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.springboard.lockstate"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);
}

To have the screen lock indicators run in the background, you need to implement background processing calling the following upon app launching.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.backgroundTaskIdentifier =
    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{

        [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier];
    }];

    [self registerforDeviceLockNotif];
}
甜味超标? 2024-07-22 17:31:39

如果您的应用程序正在运行并且用户锁定设备,您的应用程序委托将收到“应用程序将退出活动:”的调用。 如果您的应用程序在锁定时运行,则当设备解锁时,它将收到“应用程序已变为活动状态:”的调用。 但是,如果用户接到电话然后选择忽略它,您的应用程序也会收到相同的电话。 据我所知,你无法分辨出差异。

如果您的应用程序在任何这些时间都没有运行,则无法收到通知,因为您的应用程序没有运行。

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.

最笨的告白 2024-07-22 17:31:39

获取屏幕锁定和解锁事件的最简单方法是在视图控制器中使用 NSNotificationCenter 添加事件观察器。 我在 viewdidload 方法中添加了以下观察者。 这就是我所做的:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(applicationEnteredForeground:)
                                             name:UIApplicationWillEnterForegroundNotification
                                           object:nil];

然后我将以下选择器添加到视图控制器中。 当屏幕解锁时,将调用此选择器。

 - (void)applicationEnteredForeground:(NSNotification *)notification {
    NSLog(@"Application Entered Foreground");
    }

如果您想在屏幕锁定时检测事件,可以将 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:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(applicationEnteredForeground:)
                                             name:UIApplicationWillEnterForegroundNotification
                                           object:nil];

Then I added the following selector to the viewcontroller. This selector will get called when the screen is unlocked.

 - (void)applicationEnteredForeground:(NSNotification *)notification {
    NSLog(@"Application Entered Foreground");
    }

If you want to detect the event when screen gets locked, you can replace UIApplicationWillEnterForegroundNotification with UIApplicationDidEnterBackgroundNotification.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文