【问题标题】:Differentiate between screen lock and home button press on iOS7区分iOS7上的屏幕锁定和主页按钮按下
【发布时间】:2013-11-04 22:20:41
【问题描述】:

我需要在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 更新多任务后台处理?或者我的应用程序的某些设置(我的应用程序的后台模式已关闭)?

还有其他解决方案吗?

【问题讨论】:

  • 我觉得我说得不够清楚。我阅读了您链接上的帖子,但这在 iOS7 中不再起作用。我不认为它是重复的。但无论如何,我编辑我的问题以使其清楚。
  • 澄清的好主意,加上编辑会将您的帖子推回到顶部,以便其他人再次看到它。 :D
  • @Perisheroy 我也有同样的问题。你找到解决这个问题的方法了吗?如果找到请帮助我。

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


【解决方案1】:

这对 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];

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");
    }
}

【讨论】:

  • 如果您发现重复的问题,正确的操作,一旦您有 15 个代表,就是将帖子标记为重复。简单地在网站上发布相同的复制/粘贴答案不是我们的目的,这会产生噪音。
  • @jmort253 对不起,我不知道我应该这样做。我是新用户,但我认为我的回答是正确的。
  • 不适合我。在 iOS 7(模拟器和设备)上测试它。我认为这不是使用 [[UIScreen mainScreen] 亮度] 的正确方法。根据苹果图书馆的文档,这只是这个应用程序中屏幕亮度的设置,而不是当前屏幕亮度级别。
  • @Perisheroy 我确信它可以在 iOS7 设备上运行,我已经在我和我朋友的 iOS7 iPhone5 上进行了测试。您可以在 appDelegate.m 中将代码 sn-p 放入 - (void)applicationDidEnterBackground:(UIApplication *)application。它不适用于 iOS 模拟器,抱歉我之前没有提到。
  • 这目前在最新的 iOS 7 模拟器中不起作用。如果您愿意,我可以提供一个视频来展示这一点。
【解决方案2】:

它在 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 在这里不能完美运行

【讨论】:

    【解决方案3】:

    此解决方案取自 this answer 并为我工作。它有点 hacky,但它更容易被应用商店接受,因为它不使用 com.apple.springboard.lockcompletecom.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
    }
    

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

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

    【讨论】:

    • 事情是当应用程序已经在后台然后用户锁定屏幕它无法检测到动作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    相关资源
    最近更新 更多