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

Сохранять отображение, когда датчик приближения закрыт

Я хочу перехватить датчик приближения, не выключая дисплей.

Я знаю по документации, что у меня есть две переменные Bool:

proximityMonitoringEnabled
proximityState

и этот код

[UIDevice currentDevice].proximityMonitoringEnabled = YES;

Когда датчик приближения обнаруживает что-то, он выключает дисплей, так же, как и при удержании телефона в ухе при телефонном звонке.

Как включить отображение дисплея, когда датчик приближения закрыт?

4b9b3361

Ответ 1

Документация на яблоки отмечает, что "не все устройства iPhone OS имеют датчики приближения". Чтобы определить, поддерживает ли устройство ваше приложение, поддерживает мониторинг близости, установите для свойства proximityMonitoringEnabled значение YES, а затем проверьте его значение:

UIDevice *device = [UIDevice currentDevice];
[device setProximityMonitoringEnabled:YES];

if (device.proximityMonitoringEnabled == YES) {
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(proximityChanged:) 
                                                 name:@"UIDeviceProximityStateDidChangeNotification"
                                               object:device];
}

- (void) proximityChanged:(NSNotification *)notification {
    UIDevice *device = [notification object];
    NSLog(@"In proximity: %i", device.proximityState);
}

Источник: http://www.whatsoniphone.com/blog/new-in-iphone-30-tutorial-series-part-4-proximity-detection/

Помогает определить текущее состояние датчика.

Открытый API, который позволяет использовать экран:

[UIScreen mainScreen].wantsSoftwareDimming = YES;
[UIScreen mainScreen].brightness = $your_brightness_value;

Найдено здесь: Изменить на пожеланияПрограммное обеспечение в iOS 6?

Ответ 2

Прочитав разные форумы по этой теме, в настоящее время это невозможно для нас в публичном api, чтобы предотвратить экранирование экрана iPhone при приближении датчика приближения. Единственное, что вы можете сделать с датчиком, это сказать, когда оно покрыто или нет через центр уведомлений, но снова вы не можете контролировать его естественное поведение (когда он тускнеет/затушевывает экран).

Ответ 3

Хотя для этого нет публичного API, вы можете подключиться к IOKit IOHIDEventSystem и слушать уведомления о затемнении экрана:

// Create and open an event system.
IOHIDEventSystemRef system = IOHIDEventSystemCreate(NULL);

// Set the PrimaryUsagePage and PrimaryUsage that the AppleProxShim service uses
int page = 65280;
int usage = 8;

// Create a dictionary to match the service with
CFStringRef keys[2];
CFNumberRef nums[2];
keys[0] = CFStringCreateWithCString(0, "PrimaryUsagePage", 0);
keys[1] = CFStringCreateWithCString(0, "PrimaryUsage", 0);
nums[0] = CFNumberCreate(0, kCFNumberSInt32Type, &page);
nums[1] = CFNumberCreate(0, kCFNumberSInt32Type, &usage);
CFDictionaryRef dict = CFDictionaryCreate(0, (const void**)keys, (const void**)nums, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// Get the total of matching services with the above criteria
CFArrayRef srvs = (CFArrayRef)IOHIDEventSystemCopyMatchingServices(system, dict, 0, 0, 0, 0);

// Get the service
IOHIDServiceRef serv = (IOHIDServiceRef)CFArrayGetValueAtIndex(srvs, 0);
int interval = 1 ;

// Set an interval of 1 , to activate the sensor  
IOHIDServiceSetProperty((IOHIDServiceRef)serv, CFSTR("ReportInterval"), CFNumberCreate(0, kCFNumberSInt32Type, &interval));

// add your event handler
IOHIDEventSystemOpen(system, handle_event, NULL, NULL, NULL);
int defaultInterval = 0;
IOHIDServiceSetProperty((IOHIDServiceRef)serv, CFSTR("ReportInterval"), CFNumberCreate(0, kCFNumberSInt32Type, &defaultInterval));

// close handles and release the IOHIDEventSystemRef
IOHIDEventSystemClose(system, NULL);
CFRelease(system);

Указатель функции обработчика событий будет выглядеть примерно так:

void handle_event(void* target, void* refcon, IOHIDServiceRef service, IOHIDEventRef event) {
    if (IOHIDEventGetType(event) == kIOHIDEventTypeProximity) { // Proximity Event Received
        // not necessary, but if you want the value from the sensor, get it from IOHIDEventGetIntegerValue
        int proximityValue = IOHIDEventGetIntegerValue(event, (IOHIDEventField)kIOHIDEventFieldProximityDetectionMask); // Get the value of the ProximityChanged Field (0 or 64)

        // Call dimScreen with the boolean NO
        int (*SBSSpringBoardServerPort)() = (int (*)())dlsym(RTLD_DEFAULT, "SBSSpringBoardServerPort");
        int port = SBSSpringBoardServerPort(); 
        void (*_SBDimScreen)(int _port,BOOL shouldDim) = (void (*)(int _port,BOOL shouldDim))dlsym(RTLD_DEFAULT, "SBDimScreen");

        // This is where the logic to dim the screen based on the sensor value would go.  In this case, I'm hardcoding NO instead of the value of proximityValue from above
        // BOOL dim = proximityValue == 0 ? NO : YES;
        _SBDimScreen(port, NO); 
    }
}

Вызов _SBDimScreen может даже не понадобиться, так как наличие пустого указателя функции может остановить все события датчика приближения.

Код, измененный из примера инструмента командной строки на странице AppleProxShim на iPhoneDevWiki.

Ответ 4

Для включения/выключения датчика приближения используйте следующий API.

[UIDevice currentDevice].proximityMonitoringEnabled = NO; // Disables the Proximity Sensor and won't turnoff the display when sensor covered

[UIDevice currentDevice].proximityMonitoringEnabled = YES; // Enables the Proximity Sensor and will turnoff the display when sensor covered

Не все устройства iOS имеют датчики приближения. Чтобы определить, доступен ли мониторинг близости, попробуйте включить его. Если значение свойства proximityMonitoringEnabled остается НЕТ, мониторинг близости недоступен.

Ответ 5

fo swift/iOS 10/xcode 8.2

UIDevice.current.isProximityMonitoringEnabled = true/false..