2014-11-26 40 views
12

Voglio intercettare il sensore di prossimità senza spegnere il display.Mantenere il display acceso quando il sensore di prossimità è coperto

So che dalla documentazione che ho due variabili Bool:

proximityMonitoringEnabled 
proximityState 

e questo codice

[UIDevice currentDevice].proximityMonitoringEnabled = YES; 

Quando il sensore di prossimità rileva qualcosa si spegne il display, allo stesso modo lo fa quando stai tenendo il telefono all'orecchio quando sei in una telefonata.

Come si mantiene il display acceso quando il sensore di prossimità è coperto?

+0

Ciao, grazie per la risposta.Ok, con il tuo codice posso sapere lo stato del sensore di prossimità, ma se lo stato è "SI", il display non è ancora visibile? –

+0

aggiornato la mia risposta –

risposta

7

la documentazione di Apple osserva che “Non tutti i dispositivi iPhone OS sono dotati di sensori di prossimità.” Per determinare se il dispositivo vostra applicazione è in esecuzione supporta il monitoraggio di prossimità, impostare la proprietà proximityMonitoringEnabled a SÌ, quindi controllare il suo valore:

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

Fonte: http://www.whatsoniphone.com/blog/new-in-iphone-30-tutorial-series-part-4-proximity-detection/

Aiuterà a rilevare lo stato corrente del sensore.

API pubblica che consente schermo dim:

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

Trovato qui: Change to wantsSoftwareDimming in iOS 6?

+0

grazie, ti farò sapere se funziona il prima possibile! –

+1

ciao, quindi posso rispondere solo ora. Sono in grado di fare qualcosa quando il sensore è coperto, ma il display è ancora spento! –

+0

@SimonePistecchia Perché non aggiorni la tua domanda con quello che hai provato in modo che possiamo aiutarti ulteriormente. – Unheilig

7

Dopo aver letto diversi forum sul tema, il suo momento non è possibile per noi nella API pubblica per impedire lo schermo iPhone da diventa nero quando il sensore di prossimità è coperto. L'unica cosa che puoi fare con il sensore è dire quando è coperta o no attraverso il centro notifiche, ma di nuovo non puoi controllare il suo comportamento naturale (quando oscura/oscura lo schermo).

0

Utilizzare la seguente API per abilitare/disabilitare il sensore di prossimità.

[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 

Non tutti i dispositivi iOS hanno sensori di prossimità. Per determinare se il monitoraggio di prossimità è disponibile, provare ad abilitarlo. Se il valore della proprietà proximityMonitoringEnabled rimane NO, il monitoraggio della prossimità non è disponibile.

+0

L'ho provato con iPhone 6 con iOS 9.2.1. –

3

Anche se non v'è alcuna API pubblica per fare questo, è possibile collegare in s IOHIDEventSystemIOKit' e ascoltare per lo schermo che oscura le notifiche:

// 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); 

vostro gestore di eventi puntatore a funzione sarà simile a questa:

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

La chiamata _SBDimScreen potrebbe non essere nemmeno necessaria, poiché un puntatore a funzione vuota potrebbe interrompere tutti gli eventi del sensore di prossimità.

Codice modificato dall'esempio dello strumento della riga di comando sulla pagina AppleProxShim su iPhoneDevWiki.

+0

Grazie per un'ottima risposta! Speriamo che diventi possibile senza usare 'IOKit' ad un certo punto. –

+0

Grazie @DanielStorm, buona fortuna! Aggiornerà se questo è mai esposto con un'API pubblica. – JAL

0

fo swift/iOS 10/Xcode 8,2

UIDevice.current.isProximityMonitoringEnabled = true/false..