Подтвердить что ты не робот

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

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

  • Устройство блокируется/разблокируется.
  • Устройство переходит в спящий режим, и экран затемнен.

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

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

4b9b3361

Ответ 1

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

Используйте событие 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().

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

Ответ 2

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