[英]Differentiate between screen lock and home button press on iOS7
我需要在applicationDidEnterBackground
做一些事情。 但我需要区分哪个用户操作导致“输入背景”:屏幕锁定或按下主页按钮。
我正在使用这个代码,这是来自这篇文章 - 如何区分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更新到多任务后台处理? 或者我的应用程序的某些设置(我的应用程序的后台模式已关闭)?
还有替代解决方案吗?
这可以帮助你在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"); } }
这个解决方案取自这个答案并为我工作。 它有点hacky,但它更容易被appstore接受,因为它不使用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
}
我们的想法是在应用程序转到后台后尝试更改屏幕亮度,并检查此更改是否成功。
免责声明:它不适用于模拟器,您必须在真实设备上进行测试。
它在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在这里不能很好地工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.