Reputation: 1959
I have a service that needs to extend the system screen-on timeout when something happens in the service (there is no user interaction.) Ideally, I could just reset the "user activity timer" with PowerManager's userActivity (long when, boolean noChangeLights) method. However, that needs a permission only system apps can be granted.
So, what I've done is acquire a SCREEN_BRIGHT_WAKE_LOCK wakelock with the ON_AFTER_RELEASE flag. According to documentation, with this flag "the user activity timer will be reset when the WakeLock is released, causing the illumination to remain on a bit longer".
This works, but I have some problems.
1) If the wakelock is released after the default screen timeout, the screen no longer dims. Example: Screen timeout is 15s. The service keeps the wakelock for 30s and then releases it, causing the screen to stay on an extra 15s. The screen just turns off after 15s, it doesn't dim first like usual.
2) If the wakelock is released when the screen has dimmed and about to go off, sometimes it flashes bright for a second and then dims again right away (instead of coming out of dim and going bright directly). This can happen many times quickly causing screen flicker if the wakelock is acquired and released multiple tiems during the dimming period.
How can I achieve what I really want, which is to reset the "user activity timer" as if the user had touched the device?
Upvotes: 3
Views: 998
Reputation: 155
For your 1), first it is device or OS dependent. On some of my older devices with Android 4.0.X it worked with a dim phase after the wakelock release call. On newer devices, 4.3 and 4.4 it goes off immediately, no dim Phase. What I do know is aquire 2 wakelocks, SCREEN_BRIGHT_WAKE_LOCK with no ON_AFTER_RELEASE and SCREEN_DIM_WAKE_LOCK with ON_AFTER_RELEASE. With that I have dim phase after releasing both locks on all devices. Sample Code:
private WakeLock alarmWakeLock = null;
private WakeLock alarmWakeLockDim = null;
public void wakeUp()
{
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
alarmWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP , "WakeLock");
if ((alarmWakeLock != null) && (alarmWakeLock.isHeld() == false))
alarmWakeLock.acquire(Globals.ALARM_TIMEOUT);
alarmWakeLockDim = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "WakeLockDim");
if ((alarmWakeLockDim != null) && (alarmWakeLockDim.isHeld() == false))
alarmWakeLockDim.acquire(Globals.TALARM_TIMEOUT);
}
public void sleep()
{
if ( alarmWakeLock != null && alarmWakeLock.isHeld() )
{
alarmWakeLock.release();
alarmWakeLock = null;
}
if ( alarmWakeLockDim != null && alarmWakeLockDim.isHeld() )
{
alarmWakeLockDim.release();
alarmWakeLockDim = null;
}
}
I defined Globals.ALARM_TIMEOUT with 5 Minutes ( 5*60*1000 ), you have to choose a value that fit your needs.
Upvotes: 2