2010-06-10 20 views
11

Mi aplicación le permite al usuario acceder a su correo de voz corporativo. Normalmente, durante una llamada telefónica cuando el usuario sostiene el dispositivo hasta su oreja, la pantalla se apaga para que accidentalmente no presione los botones con su cara. Me gustaría hacer que mi aplicación haga lo mismo cuando el usuario está escuchando su correo de voz.android: apague la pantalla cuando está cerca de la cara

¿Alguien sabe cómo hacer esto?

Respuesta

3

Lo que está viendo es el uso de un sensor de proximidad. Para dispositivos que tienen uno, puede acceder a él a través del SensorManager.

+0

Sí, estaba investigando eso, pero estaba teniendo problemas para descubrir la implementación real. ¿Has visto algún ejemplo de cómo usarlo? – mtmurdock

+0

@mtmurdock: no, lo siento, no he visto ninguno. Solo sé que ese es el sensor en cuestión. – CommonsWare

20

Si puede ver el código fuente abierto sin causar problemas, consulte la fuente del Android Phone Application. Específicamente src/com/android/phone/PhoneApp.java y src/com/android/phone/InCallScreen.java.

De src/com/android/teléfono/PhoneApp.java:

//Around line 519 
// Wake lock used to control proximity sensor behavior. 
if ((pm.getSupportedWakeLockFlags() 
      & PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) != 0x0) { 
    mProximityWakeLock = pm.newWakeLock(
     PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, 
     LOG_TAG); 
} 

.... 
// Around line 1334 
if (((state == Phone.State.OFFHOOK) || mBeginningCall)&& !screenOnImmediately) { 
    // Phone is in use! Arrange for the screen to turn off 
    // automatically when the sensor detects a close object. 
    if (!mProximityWakeLock.isHeld()) { 
     if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: acquiring..."); 
     mProximityWakeLock.acquire(); 
    } else { 
     if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: lock already held."); 
    } 
} else { 
    // Phone is either idle, or ringing. We don't want any 
    // special proximity sensor behavior in either case. 
    if (mProximityWakeLock.isHeld()) { 
    if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: releasing..."); 
    // Wait until user has moved the phone away from his head if we are 
    // releasing due to the phone call ending. 
    // Qtherwise, turn screen on immediately 
    int flags = 
     (screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE); 
    mProximityWakeLock.release(flags); 
    } 
} 

Además, si nos fijamos en el código de la clase PowerManager, se documenta PROXIMITY_SCREEN_OFF_WAKE_LOCK (pero oculta) y debe hacer lo que quiera (No estoy seguro de qué nivel de API funciona esto, sin embargo), pero no en la tabla por alguna razón.

/** 
* Wake lock that turns the screen off when the proximity sensor activates. 
* Since not all devices have proximity sensors, use 
* {@link #getSupportedWakeLockFlags() getSupportedWakeLockFlags()} to determine if 
* this wake lock mode is supported. 
* 
* {@hide} 
*/ 
public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = WAKE_BIT_PROXIMITY_SCREEN_OFF; 

Si no tiene miedo de utilizar una función potencial no documentada, debería hacer exactamente lo que necesita.

+0

Eso es mucho para tamizar a través de ... me temo que no pude encontrar mucho allí, a menos que pueda señalarme a algunas partes más específicas – mtmurdock

+0

Allí, se agregó información completa - no quería antes en la información del caso desde el código fuente abierto causaría un problema. – Dre

+0

hay API privadas en ese código. – Taranfx

4

a partir del nivel de la API 21 (Lollipop) se puede obtener el bloqueo estela de proximidad esto simplemente así:

if(powerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) { 
     PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG); 
     wakeLock.setReferenceCounted(false); 
     return wakeLock; 
    } else { 
     return null; 
    } 
} 

, entonces usted debe adquirir y liberar la cerradura.

PD: PowerManager#getSupportedWakeLockFlags estaba oculto, pero ahora existe nomore. Han inventado isWakeLockLevelSupported en su lugar.

+1

Aunque dice que se requiere API nivel 21, parece ser compatible con versiones anteriores, ya que la bandera siempre estaba allí, simplemente oculta. – kotucz

Cuestiones relacionadas