Обнаружение включения / выключения экрана из сервиса iOS
Я занимаюсь разработкой приложения для мониторинга сети, которое работает в фоновом режиме в качестве службы. Можно ли получить уведомление / звонок при включении или выключении экрана?
Он существует в Android с помощью следующего кода:
private void registerScreenOnOffReceiver()
{
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(screenOnOffReceiver, filter);
}
Затем вызывается screenOnOffReceiver, когда экран включается / выключается. Есть ли подобное решение для iOS?
Редактировать: лучшее, что я нашел на данный момент, это UIApplicationProtectedDataWillBecomeUnavailable ( определить, включен ли экран iPhone), но для этого требуется, чтобы пользователь включил защиту данных (защиту паролем) на устройстве.
3 ответа
Вы можете использовать уведомления Дарвина, чтобы прослушивать события. Я не уверен на 100%, но мне кажется, после запуска на взломанном iOS 5.0.1 iPhone 4, что одним из этих событий может быть то, что вам нужно:
com.apple.iokit.hid.displayStatus
com.apple.springboard.hasBlankedScreen
com.apple.springboard.lockstate
Обновление: также, следующее сообщение отправляется, когда телефон блокируется (но не когда он разблокируется):
com.apple.springboard.lockcomplete
Чтобы использовать это, зарегистрируйтесь для такого события (это регистрируется только для одного события, но если это не работает для вас, попробуйте другие):
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
NULL, // observer
displayStatusChanged, // callback
CFSTR("com.apple.iokit.hid.displayStatus"), // event name
NULL, // object
CFNotificationSuspensionBehaviorDeliverImmediately);
где displayStatusChanged
Ваш обратный вызов события:
static void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
NSLog(@"event received!");
// you might try inspecting the `userInfo` dictionary, to see
// if it contains any useful info
if (userInfo != nil) {
CFShow(userInfo);
}
}
Если вы действительно хотите, чтобы этот код выполнялся в фоновом режиме как служба, и вы взломаны, я бы порекомендовал изучить демоны запуска iOS. В отличие от приложения, которое вы просто запускаете в фоновом режиме, демон запуска может запускаться автоматически после перезагрузки, и вам не нужно беспокоиться о правилах iOS для приложений, выполняющих задачи в фоновом режиме.
Дайте нам знать, как это работает!
Используя низкоуровневый API уведомлений, вы можете запросить состояние блокировки при получении уведомления:
#import <notify.h>
int notify_token;
notify_register_dispatch("com.apple.springboard.lockstate", ¬ify_token, dispatch_get_main_queue(), ^(int token) {
uint64_t state = UINT64_MAX;
notify_get_state(token, &state);
NSLog(@"com.apple.springboard.lockstate = %llu", state);
});
Конечно, ваше приложение должно будет запустить UIBackgroundTask для получения уведомлений, что ограничивает полезность этой техники из-за ограниченного времени выполнения, разрешенного iOS.
Пока экран iPhone заблокирован appdelegate, будет вызван метод "- (void)applicationWillResignActive:(UIApplication *)application", это можно проверить. Надеюсь, это поможет вам.