2013-01-16 5 views
12

Chciałem wykryć dwa wydarzenia:Czy jest daleko, aby wykryć zdarzenie, gdy urządzenie z systemem iOS przechodzi w tryb uśpienia (po zaciemnieniu ekranu)?

  1. urządzenie zostanie zablokowane/odblokowane.
  2. Urządzenie przechodzi w tryb uśpienia, a ekran czernieje.

Pierwszy z nich udało mi się osiągnąć tutaj: Is there a way to check if the iOS device is locked/unlocked?

Teraz chcę wykryć drugie zdarzenie, czy jest jakiś sposób, aby to zrobić?

+0

Czy to pytanie dotyczy prywatnego apisa na iPhone'a? – iDev

+0

Wszystko będzie wystarczające, nie mam zamiaru przesyłać mojej aplikacji w App Store. –

Odpowiedz

19

Zasadniczo mają już rozwiązanie, które Zgaduję, że znalazł jednego z moich ostatnich odpowiedzi :)

użyć zdarzenia com.apple.springboard.hasBlankedScreen.

Istnieje wiele zdarzeń, które występują, gdy wykroje ekranie, ale ten powinien wystarczyć:

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center 
           NULL, // observer 
           hasBlankedScreen, // callback 
           CFSTR("com.apple.springboard.hasBlankedScreen"), // event name 
           NULL, // object 
           CFNotificationSuspensionBehaviorDeliverImmediately); 

gdzie zwrotna jest:

static void hasBlankedScreen(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) 
{ 
    NSString* notifyName = (__bridge NSString*)name; 
    // this check should really only be necessary if you reuse this one callback method 
    // for multiple Darwin notification events 
    if ([notifyName isEqualToString:@"com.apple.springboard.hasBlankedScreen"]) { 
     NSLog(@"screen has either gone dark, or been turned back on!"); 
    } 
} 

Aktualizacja: jak @VictorRonin powiedział w swoim komentarzu poniżej, powinno być łatwo śledzić samemu, czy ekran jest obecnie na lub off. Pozwala to określić, czy zdarzenie hasBlankedScreen występuje podczas włączania i wyłączania ekranu. Na przykład po uruchomieniu aplikacji ustaw zmienną, aby wskazywała, że ​​ekran jest włączony. Za każdym razem, gdy pojawi się jakakolwiek interakcja z interfejsem użytkownika (naciśnięcie przycisku itp.), Wiesz, że ekran musi być włączony. Tak więc następny hasBlankedScreen otrzymasz powinien wskazać, że ekran jest off.

Ponadto chcę się upewnić, że mamy jasność co do terminologii. Urządzenie blokuje się automatycznie, gdy ekran zostanie automatycznie przyciemniony z powodu przekroczenia limitu czasu lub gdy użytkownik ręcznie naciśnie przycisk zasilania. Dzieje się tak niezależnie od tego, czy użytkownik ma skonfigurowany kod dostępu. W tym czasie zobaczysz zdarzenia com.apple.springboard.hasBlankedScreen i . Po ponownym włączeniu ekranu ponownie pojawi się com.apple.springboard.hasBlankedScreen. Ale nie zobaczysz com.apple.springboard.lockstate, dopóki użytkownik nie odblokuje urządzenia za pomocą machnięcia (i może hasła).


Aktualizacja 2:

Jest jeszcze inny sposób, aby to zrobić. Można użyć alternatywnego zestawu API słuchać tego zgłoszenia, a także get a state variable gdy zgłoszenie pochodzi:

#import <notify.h> 

int status = notify_register_dispatch("com.apple.springboard.hasBlankedScreen", 
             &notifyToken, 
             dispatch_get_main_queue(), ^(int t) { 
              uint64_t state; 
              int result = notify_get_state(notifyToken, &state); 
              NSLog(@"lock state change = %llu", state); 
              if (result != NOTIFY_STATUS_OK) { 
               NSLog(@"notify_get_state() not returning NOTIFY_STATUS_OK"); 
              } 
             }); 
if (status != NOTIFY_STATUS_OK) { 
    NSLog(@"notify_register_dispatch() not returning NOTIFY_STATUS_OK"); 
} 

i trzeba będzie mieć ivar lub jakiś inny uporczywy zmiennej do przechowywania token powiadomienia (nie tylko uczyń z niego zmienną lokalną w metodzie, która rejestruje!)

int notifyToken; 

Powinieneś zobaczyć zmienną state, uzyskanych poprzez notify_get_state(), przełączanie między 0 a 1, który pozwoli Ci odróżnić ekranu i wyłączać wydarzeń.

Chociaż this document is very old, wyświetla listę zdarzeń powiadamiania powiązanych ze stanem, które można pobrać przez notify_get_state().

Ostrzeżenie:see this related question for some complications with this last technique

+0

Próbowałem już tego, okazuje się, to powiadomienie przychodzi w obu scenariuszach, kiedy urządzenie idzie spać i kiedy urządzenie budzi się ze snu .: 16 stycznia 18:48:53 nieznane SpringBoard [15] : Publikowanie "com .apple.iokit.hid.displayStatus 'notifyState = 0 16 stycznia 18:48:53 nieznany Myapp [1921] : Powiadomienie Darwina NAZWA = com.apple.springboard.hasBlankedScreen an 16 18:50:29 unknown SpringBoard [15 ] : Publikowanie "com.apple.iokit.hid.displayStatus" notifyState = 1 16 stycznia 18:50:29 nieznany Myapp [1921] : Powiadomienie Darwina NAZWA = com.apple.springboard.hasBlankedScreen –

+1

Możesz zachować stan zmienne, czy urządzenie śpi teraz czy nie. –

+0

Czy poprawnie zauważam, że moja aplikacja nie otrzyma powiadomień lockstate lub lockcomplete, jeśli jest już w tle po wystąpieniu blokady? –

1

Można również zapisać się na powiadomienia: „com.apple.springboard.lockstate” i używać API SBGetScreenLockStatus do stanu określić, czy urządzenie jest zablokowane lub nie.

+0

Jak zadzwonić i używać? w rzeczywistości chcę tylko wykryć zdarzenie, gdy ekran jest czarny, tzn. ekran przechodzi z włączania/wyłączania. Z góry dziękuję. –

+0

Info: Nie jest to urządzenie z jailbreakiem. –

+0

Pierwsze powiadomienie jest używane z tym samym kodem, który Nate napisał. SBGetScreenLockStatus jest opisany w łączonym artykule. Te wydarzenia dodałem jako odpowiedź na "Urządzenie zostanie zablokowane/odblokowane". I działa na urządzeniu bez jailbreak. –

Powiązane problemy