iOS鎖屏事件監聽

私有API (慎用 不上appstore的話就可以用)

//AppDelegate.m
//監聽鎖屏事件
#define kNotificationLock CFSTR("com.apple.springboard.lockcomplete")
//監聽屏幕狀態變化事件
#define kNotificationChange CFSTR("com.apple.springboard.lockstate")

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

    //監聽鎖屏事件
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, screenLockStateChanged, kNotificationLock, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
    //監聽屏幕狀態變化事件
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, screenLockStateChanged, kNotificationChange, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);

    return YES;
}

static void screenLockStateChanged(CFNotificationCenterRef center,void* observer,CFStringRef name,const void* object,CFDictionaryRef userInfo){
    
    NSString* lockstate = (__bridge NSString*)name;
    if ([lockstate isEqualToString:(__bridge  NSString*)kNotificationLock]) {
        NSLog(@"鎖屏");
    }
    else{
        NSLog(@"解鎖");
    }
    
}

紅外線傳感器判斷是否息屏

//傳感器(紅外感應)打開 打開才能監聽 適當的時機去關閉就ok
    [[UIDevice currentDevice] setProximityMonitoringEnabled:YES];
    //設置監聽
    [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(sensorStateChange:)
                                                     name:UIDeviceProximityStateDidChangeNotification
                                                   object:nil];

- (void)sensorStateChange:(NSNotificationCenter *)notification {
    if ([[UIDevice currentDevice] proximityState] == YES) {
        NSLog(@"熄屏");
    }else{
        NSLog(@"亮屏");
    }
}

App不熄屏設置 適用於直播等長時間在activity的場景

[[UIApplication sharedApplication] setIdleTimerDisabled:YES];

網上說監聽這兩個通知可以監聽到鎖屏和解鎖的回調, 實際上聊勝於無 (屁都沒有)

UIApplicationProtectedDataWillBecomeUnavailable
UIApplicationProtectedDataDidBecomeAvailable

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(LOCK_SCREEN:)
                                                 name:UIApplicationProtectedDataWillBecomeUnavailable
                                               object:nil];
     
     [[NSNotificationCenter defaultCenter] addObserver:self
                                              selector:@selector(UN_LOCK_SCREEN:)
                                                  name:UIApplicationProtectedDataDidBecomeAvailable
                                                object:nil];

看似可行的方案 實則也不行🚫

//AppDelegate.m
//app進入後臺和鎖屏都會調用此方法
-(void)applicationDidEnterBackground:(NSNotification *)notification  {
       if ([self didUserPressLockButton]) {
            //User pressed lock button
             NSLog(@"Lock screen.");
        } else {
             NSLog(@"Home.");
            //user pressed home button
       }
}

-(BOOL)didUserPressLockButton{
     //獲取屏幕亮度
     CGFloat oldBrightness = [UIScreen mainScreen].brightness;
     //以較小的數量改變屏幕亮度
     [UIScreen mainScreen].brightness = oldBrightness + (oldBrightness <= 0.01 ? (0.01) : (-0.01));
     CGFloat newBrightness  = [UIScreen mainScreen].brightness;
     //恢復屏幕亮度
     [UIScreen mainScreen].brightness = oldBrightness;
     //判斷屏幕亮度是否能夠被改變
     return oldBrightness != newBrightness;
}

貌似就這一種是設置了密碼保護的手機才生效的方法 看似合理卻並不完美

要是沒有設置密碼鎖,這個方案也就失靈了( iOS無人要了 玩不下去了)

//AppDelegate.m
-(void)applicationProtectedDataWillBecomeUnavailable:(NSNotificationCenter *)notification{
        NSLog(@"🔐鎖屏");
    // 這裏可以post 一個通知 
}

- (void)applicationProtectedDataDidBecomeAvailable:(UIApplication *){
        NSLog(@"🔓解鎖");
// 這裏可以post 一個通知 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章