Есть ли возможность обнаружить событие, когда устройство iOS переходит в спящий режим (когда экран становится черным)?

Я хотел обнаружить два события:

  1. Устройство заблокировано / разблокировано.
  2. Устройство переходит в режим сна, и экран чернеет.

Первое, чего я смог достичь здесь: есть ли способ проверить, заблокировано / разблокировано устройство iOS?

Теперь я хочу обнаружить второе событие, есть ли способ сделать это?

2 ответа

У вас в принципе уже есть решение, которое, я думаю, вы нашли в одном из моих недавних ответов:)

Использовать com.apple.springboard.hasBlankedScreen событие.

Когда экран гаснет, происходит несколько событий, но этого должно быть достаточно:

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

где обратный вызов:

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

Обновление: как @VictorRonin сказал в своем комментарии ниже, должно быть легко следить за тем, включен ли экран в данный момент. Это позволяет определить, является ли hasBlankedScreen событие происходит, когда экран включается или выключается. Например, когда ваше приложение запускается, установите переменную, чтобы указать, что экран включен. Кроме того, каждый раз, когда происходит какое-либо взаимодействие с пользовательским интерфейсом (нажатие кнопки и т. Д.), Вы знаете, что экран должен быть включен. Итак, следующий hasBlankedScreen Вы должны указать, что экран выключен.

Кроме того, я хочу убедиться, что мы четко понимаем терминологию. Устройство блокируется, когда экран автоматически темнеет из-за тайм-аута, или когда пользователь вручную нажимает кнопку питания. Это происходит независимо от того, настроен ли у пользователя пароль. В это время вы увидите com.apple.springboard.hasBlankedScreen и com.apple.springboard.lockcomplete События.

Когда экран снова включится, вы увидите com.apple.springboard.hasBlankedScreen снова. Но вы не увидите com.apple.springboard.lockstate пока пользователь фактически не разблокирует устройство с помощью прокрутки (и, возможно, пароль).


Обновление 2:

Есть еще один способ сделать это. Вы можете использовать альтернативный набор API для прослушивания этого уведомления, а также получить переменную состояния при получении уведомления:

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

и вам нужно будет хранить ivar или другую постоянную переменную для хранения токена уведомления (не делайте это локальной переменной в методе, который регистрируется!)

int notifyToken;

Вы должны увидеть state переменная, полученная через notify_get_state(), переключайтесь между 0 и 1, что позволит вам различать события включения и выключения экрана.

Хотя этот документ очень старый, он перечисляет, какие события уведомлений имеют ассоциированное состояние, которое можно получить с помощью notify_get_state(),

Предупреждение: см. Этот связанный вопрос для некоторых осложнений с этой последней техникой

Вы также можете подписаться на уведомление: "com.apple.springboard.lockstate" и использовать API SBGetScreenLockStatus для определения состояния, заблокировано ли устройство или нет.

Другие вопросы по тегам