从iOS服务检测屏幕开/关

时间:2013-01-07 08:00:05

标签: objective-c ios notifications jailbreak broadcast

我正在开发一个在后台作为服务运行的网络监视器应用程序。屏幕打开或关闭时是否可以收到通知/电话?

使用以下代码存在于Android中:

private void registerScreenOnOffReceiver()
{
   IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
   filter.addAction(Intent.ACTION_SCREEN_OFF);
   registerReceiver(screenOnOffReceiver, filter);
}
然后在打开/关闭屏幕时调用screenOnOffReceiver。 iOS有类似的解决方案吗?

修改 到目前为止,我发现的最好的是UIApplicationProtectedDataWillBecomeUnavailable(Detect if iPhone screen is on/off),但它要求用户在设备上启用数据保护(密码保护)。

3 个答案:

答案 0 :(得分:15)

您可以使用Darwin notifications来收听事件。我不是百分百肯定,但它看起来像是在越狱的iOS 5.0.1 iPhone 4上运行,其中一个事件可能就是你所需要的:

com.apple.iokit.hid.displayStatus
com.apple.springboard.hasBlankedScreen
com.apple.springboard.lockstate

更新:此外,手机锁定时会发布以下通知(但不会解锁时):

com.apple.springboard.lockcomplete

要使用此功能,请注册此类事件(仅注册一个事件,但如果这对您不起作用,请尝试其他事件):

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                NULL, // observer
                                displayStatusChanged, // callback
                                CFSTR("com.apple.iokit.hid.displayStatus"), // event name
                                NULL, // object
                                CFNotificationSuspensionBehaviorDeliverImmediately);

其中displayStatusChanged是您的事件回调:

static void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
    NSLog(@"event received!");
    // you might try inspecting the `userInfo` dictionary, to see 
    //  if it contains any useful info
    if (userInfo != nil) {
        CFShow(userInfo);
    }
}

如果您真的希望此代码作为服务在后台运行,并且您已越狱,我建议您查看iOS Launch Daemons。与您只是在后台运行的应用程序相反,启动守护程序可以在重新启动后自动启动,您不必担心在后台运行任务的应用程序的iOS规则。

告诉我们这是如何运作的!

答案 1 :(得分:2)

使用较低级别的通知API,您可以在收到通知时查询lockstate:

#import <notify.h>

int notify_token;
notify_register_dispatch("com.apple.springboard.lockstate", &notify_token, dispatch_get_main_queue(), ^(int token) {
    uint64_t state = UINT64_MAX;
    notify_get_state(token, &state);
    NSLog(@"com.apple.springboard.lockstate = %llu", state);
});

当然,您的应用必须启动UIBackgroundTask才能获取通知,由于iOS允许的运行时间有限,这限制了此技术的实用性。

答案 2 :(得分:-2)

虽然iPhone屏幕被锁定了appdelegate方法 “ - (void)applicationWillResignActive:(UIApplication *)application”  将被称为你可以检查。希望它可以帮助你。