I'm trying to create a custom phone app, and one of the features i'm trying to implement is to turn the screen off when the phone is brought close to face to avoid accidental touches.
I have read about the proximity sensor in the android documentation, and saw that this exact feature is implemented via a PROXIMITY_SCREEN_OFF_WAKE_LOCK
WakeLock.
I have created a test app to test this feature in isolation, which includes two buttons: one to require the wake lock and one to release it.
class MainActivity: AppCompatActivity() {
private lateinit var mPowerManager:PowerManager
private lateinit var mWakeLock:PowerManager.WakeLock
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mPowerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
mWakeLock = mPowerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "TEST_PROXIMITY_SENSOR_TAG:wake_lock_tag")
button_activate.setOnClickListener {
if (!mWakeLock.isHeld)
mWakeLock.acquire()
}
button_deactivate.setOnClickListener {
if (mWakeLock.isHeld)
mWakeLock.release()
}
}
}
And added the following WakeLock permission to my AndroidManifest.xml
<uses-permission android:name="android.permission.WAKE_LOCK" />
For the most part, this code works fine. However, sometimes when I unblock the proximity sensor the screen doesn't turn on for 10-30 seconds instead of immediately.
At first I though this was a hardware problem with the physical device I was testing with (Nexus 5, android Pie), but I have added additional logging of the proximity sensor values to the activity.
override fun onCreate(savedInstanceState: Bundle?) {
...
mSensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)
mSensorManager.registerListener(
this as SensorEventListener,
mSensor,
SensorManager.SENSOR_DELAY_NORMAL
)
}
override fun onSensorChanged(event: SensorEvent?) {
Log.d(TAG,"${event?.values?.get(0)}")
}
The sensor reported correct measurements. And when the screen was turned off wrongly by the WakeLock, the sensor reported "far".
I have tested the same scenario with the default dialer app, but it works fine. What's the problem with my implementation? I have looked at the AOSP dialer code and Signal's android app, but I couldn't find a noticeable difference.