Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Longer screen timeout for a specific Android activity?

Tags:

android

There are similar posts to this, but none are quite what I'm looking for. I'd like to change the screen timeout for a specific activity. I want to avoid using WakeLock if possible and I don't want to change the device's system-wide timeout delay setting.

Is there any way of doing this short of manually tracking user activity and using a wake lock?

=----=

Clarification: for example, how can you set the screen inactivity timeout (the time it takes for the screen to turn off after there is no input) to be some value like 3 minutes?

It is possible to do this by setting the System settings, but this affects the entire device (even after the app is closed), so this is not a good solution.

Thanks!

like image 811
Sheado Avatar asked Feb 13 '14 23:02

Sheado


Video Answer


1 Answers

First, a note on changing the System Settings to increase timeout for your activity. Intuitively I don't like this approach since you're making a system-wide change just to accomodate your application. Moreover, when changing System Settings in this manner it's hard to guarantee that you will be able to set it back(i.e. you forget to set it back / your app crashes before you set it).

A quick summary of the solution:

  • Use the Activity.onUserInteraction() method on Activity that is called for key, touch, trackball events.
  • When there is User interaction call View.setKeepScreenOn() on the root view of your activity(or some view within your activity that is persistent).
  • Use a simple Handler to post delayed messages to disable keeping the screen on after a certain amount of time.

Now, onto the code:

private ViewGroup mActivityTopLevelView;

private static final int DISABLE_KEEP_SCREEN_ON = 0;
private static final int SCREEN_ON_TIME_MS = 1000*60*3;

@Override
protected void onResume() {
    super.onResume();
    Log.d(TAG, "onResume");
    setScreenOn(true);
}

@Override
protected void onPause() {
    super.onPause();
    Log.d(TAG, "onPause");
    setScreenOn(false);
}

@Override
public void onUserInteraction() {

    super.onUserInteraction();
    Log.d(TAG, "onUserInteraction");
    setScreenOn(true);
}

private void setScreenOn(boolean enabled)
{
    // Remove any previous delayed messages
    Log.d(TAG, "setScreenOn to " + enabled);
    mHandler.removeMessages(DISABLE_KEEP_SCREEN_ON);

    if( enabled )
    {
        // Send a new delayed message to disable the screen on
        // NOTE: After we call setKeepScreenOn(false) the screen will still stay on for
        // the system SCREEN_OFF_TIMEOUT. Thus, we subtract it out from our desired time.
        int systemScreenTimeout = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, 0);
        int totalDelay = SCREEN_ON_TIME_MS - systemScreenTimeout;
        if( totalDelay > 0 )
        {
            mActivityTopLevelView.setKeepScreenOn(true);
            Log.d(TAG, "Send delayed msg DISABLE_KEEP_SCREEN_ON with delay " + totalDelay);
            mHandler.sendEmptyMessageDelayed(DISABLE_KEEP_SCREEN_ON, totalDelay);
        }
    }
    else
    {
        mActivityTopLevelView.setKeepScreenOn(false);
    }
}

private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if(msg.what == DISABLE_KEEP_SCREEN_ON)
        {
            setScreenOn(false);
        }
    }
};

Tested on Android 5.1.0.

like image 78
Trevor Carothers Avatar answered Sep 29 '22 18:09

Trevor Carothers