在iOS7上区分屏幕锁定和主页按钮按下

时间:2013-10-25 17:22:48

标签: ios objective-c cocoa-touch ios7 uiapplication

我需要在applicationDidEnterBackground中做点什么。但我需要区分哪个用户操作导致“输入背景”:屏幕锁定或主页按钮按下。

我正在使用此代码,来自此post - How to differentiate between screen lock and home button press on iOS5?

UIApplicationState state = [application applicationState];
if (state == UIApplicationStateInactive) {
    NSLog(@"Sent to background by locking screen");
} else if (state == UIApplicationStateBackground) {
    NSLog(@"Sent to background by home button/switching to other app");
}

在iOS6上运行正常。但是在iOS7(设备和模拟器)上,无论用户点击主页还是锁定按钮,我总是得到UIApplicationStateBackground

有人知道可能导致这种情况的原因吗? iOS 7更新到多任务后台处理?或者我的应用程序的某些设置(我的应用程序的后台模式已关闭)?

还有替代解决方案吗?

3 个答案:

答案 0 :(得分:18)

这可以帮助你在iOS6和iOS上iOS7:)。

当用户按下锁定按钮时,您将收到com.apple.springboard.lockcomplete通知。

//new way
//put this in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
                                    NULL,
                                    displayStatusChanged,
                                    CFSTR("com.apple.springboard.lockcomplete"),
                                    NULL,
                                    CFNotificationSuspensionBehaviorDeliverImmediately);

//put this function in AppDelegate
static void displayStatusChanged(CFNotificationCenterRef center,
                                 void *observer,
                                 CFStringRef name,
                                 const void *object,
                                 CFDictionaryRef userInfo) {
    if (name == CFSTR("com.apple.springboard.lockcomplete")) {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kDisplayStatusLocked"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

//put this in onAppEnterBackground
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
    if (state == UIApplicationStateInactive) {
        NSLog(@"Sent to background by locking screen");
    } else if (state == UIApplicationStateBackground) {
        if (![[NSUserDefaults standardUserDefaults] boolForKey:@"kDisplayStatusLocked"]) {
            NSLog(@"Sent to background by home button/switching to other app");
        } else {
            NSLog(@"Sent to background by locking screen");
        }
    }

//put this in - (void)applicationWillEnterForeground:(UIApplication *)application
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"kDisplayStatusLocked"];
[[NSUserDefaults standardUserDefaults] synchronize];

CGFloat screenBrightness = [[UIScreen mainScreen] brightness];

NSLog(@"Screen brightness: %f", screenBrightness);

UIApplicationState state = [[UIApplication sharedApplication] applicationState];

if (state == UIApplicationStateInactive) {

    NSLog(@"Sent to background by locking screen");

} else if (state == UIApplicationStateBackground) {
    if (screenBrightness > 0.0) {
        NSLog(@"Sent to background by home button/switching to other app");
    } else {
        NSLog(@"Sent to background by locking screen");
    }
}

答案 1 :(得分:1)

此解决方案来自this answer,并为我工作。这有点hacky,但是由于它不使用 com.apple.springboard.lockcomplete com.apple.springboard.lockstate ,因此在应用商店上更容易被接受>。

以下代码进入您的AppDelegate:

func applicationDidEnterBackground(_ application: UIApplication) {
    if (DidUserPressLockButton()) {
        print("User pressed lock button")
    } else {
        print("user pressed home button")
    }
}

private func DidUserPressLockButton() -> Bool {
    let oldBrightness = UIScreen.main.brightness
    UIScreen.main.brightness = oldBrightness + (oldBrightness <= 0.01 ? (0.01) : (-0.01))
    return oldBrightness != UIScreen.main.brightness
}

该想法是尝试在应用程序进入后台后更改屏幕的亮度,并检查此更改是否成功。

免责声明:它在模拟器上不起作用,您将不得不在真实设备上对其进行测试。

答案 2 :(得分:0)

它在Swift中不起作用,你需要做一些修改才能使它在Swift中运行如下

1.创建一个名为LockNotifierCallback.m的objectiveC文件,如下所示:

static void displayStatusChanged(CFNotificationCenterRef center,
                                 void *observer,
                                 CFStringRef name,
                                 const void *object,
                                 CFDictionaryRef userInfo) {
    if ([(__bridge NSString *)name  isEqual: @"com.apple.springboard.lockcomplete"]) {
        NSLog(@"Screen Locked");
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kDisplayStatusLocked"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

@implementation LockNotifierCallback

+ (void(*)(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo))notifierProc {
return displayStatusChanged;
}

@end

创建一个头:     #import

@interface LockNotifierCallback : NSObject


+ (void(*)(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo))notifierProc;


@end

2.将此文件桥接到swift

3.add功能到APPdelegate.swift:

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), nil, LockNotifierCallback.notifierProc(), "com.apple.springboard.lockcomplete", nil, CFNotificationSuspensionBehavior.DeliverImmediately)

PS:UIApplicationState在这里不能很好地工作