Ответ 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",
¬ifyToken,
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()
.
Предупреждение: см. этот связанный вопрос для некоторых осложнений с этим последним методом