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

在iOS7上区分屏幕锁定和主页按钮按下,ios,objective-c,cocoa-touch,ios7,uiapplication,Ios,Objective C,Cocoa Touch,Ios7,Uiapplication,我需要在applicationIdentinterbackground中执行一些操作。但我需要区分哪些用户操作导致“输入背景”:屏幕锁定或主页按钮按下 我使用的代码如下: 它在iOS6上运行良好。但在iOS7(设备和模拟器)上,无论用户单击home还是lock按钮,我都会得到UIApplicationStateBackground 有人知道是什么导致了这一切吗?iOS 7对多任务后台处理的更新?或者我的应用程序的某些设置(我的应用程序的后台模式已关闭) 还有其他解决方案吗?这可以在iOS6和iO

我需要在
applicationIdentinterbackground
中执行一些操作。但我需要区分哪些用户操作导致“输入背景”:屏幕锁定或主页按钮按下

我使用的代码如下:

它在iOS6上运行良好。但在iOS7(设备和模拟器)上,无论用户单击home还是lock按钮,我都会得到
UIApplicationStateBackground

有人知道是什么导致了这一切吗?iOS 7对多任务后台处理的更新?或者我的应用程序的某些设置(我的应用程序的后台模式已关闭)


还有其他解决方案吗?

这可以在iOS6和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];


它在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
同时创建一个头部: #进口

@interface LockNotifierCallback : NSObject


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


@end
2.将此文件桥接到swift

3.向APPdelegate.swift添加函数:

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

PS:UIApplicationState在这里不能完美工作

此解决方案是从我那里获得并为我工作的。它有点黑客化,但由于它不使用com.apple.springboard.lockcomplete或com.apple.springboard.lockstate,因此更容易在appstore上被接受

以下代码进入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
}
func应用程序标识符背景(u应用程序:UIApplication){
如果(DidUserPressLockButton()){
打印(“用户按下锁定按钮”)
}否则{
打印(“用户按下主页按钮”)
}
}
private func DidUserPressLockButton()->Bool{
让oldBrightness=UIScreen.main.brightness

UIScreen.main.brightness=旧亮度+(可能是重复的,我想我说得不够清楚。我在你的链接上读了这篇文章,但在iOS7中已经不起作用了。我不认为这是重复的。但无论如何,我编辑我的问题是为了让它清楚。澄清这一点是个好主意,再加上编辑会将你的文章推到顶部,以便其他人再次看到它。)D@Perisheroy我也有e同样的问题。你找到解决这个问题的方法了吗?如果找到了,请帮助我。如果你发现了一个重复的问题,正确的做法是,一旦你有15个代表,将帖子标记为重复。简单地在网站上发布相同的复制/粘贴答案不是我们要做的,这会产生噪音。@jmort253抱歉,我不知道我应该这样做这是。我是新用户,但我想我的答案是对的。不适合我。在iOS 7(模拟器和设备)上测试它。我认为这不是使用[[UIScreen mainScreen]亮度的正确方法]。根据apple library文档,这只是此应用程序中的屏幕亮度设置,不需要当前的屏幕亮度级别。@Deserroy我确信它可以在iOS7设备上工作,我已经在我和我朋友的iOS7 iPhone 5上进行了测试。您可以将代码片段放入
-(void)applicationIdentinterbackground:(UIApplication*)应用程序
在您的appDelegate.m上。它在iOS模拟器上不起作用,很抱歉我以前没有提到。这在最新的iOS 7模拟器上目前不起作用。如果您愿意,我可以提供一个视频来显示这一点。问题是当应用程序已经在后台时,用户锁定屏幕,无法检测到操作。
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), nil, LockNotifierCallback.notifierProc(), "com.apple.springboard.lockcomplete", nil, CFNotificationSuspensionBehavior.DeliverImmediately)
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
}