Search code examples
androidandroid-layoutandroid-layoutparams

FLAG_KEEP_SCREEN_ON working in reverse


This is an odd one.

I was previously using: android:keepScreenOn="true"

in my layout file to keep the screen on in an activity and this worked fine.

However I wanted to improve the so that the screen is only kept on when the web app is in a particular state. (The user should still be able to turn the screen off if they wish, I effectively just want to disable the timeout - which the above in the layout file achieves whenever the activity is active.)

To do this I have a JavaScript interface add to the WebView which casks the following two methods.

I have commented out the keepScreenOn setting in the layout.

@JavascriptInterface
public void keepScreenOn(){
    Toast.makeText(mContext, "Keeping screen on", Toast.LENGTH_LONG).show();
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@JavascriptInterface
public void allowScreenOff(){
    Toast.makeText(mContext, "Allowing screen off", Toast.LENGTH_LONG).show();
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

Now the correct Toast is displayed, but the "keep screen on" action is reversed.

i.e. when I get the Toast saying the screen will be kept on it times out and switches of after a couple of minutes. BUT when I get the Toast saying that the screen will be allowed to turn off the screen actually stays on without ever timing out.

I don't understand how this can be.


OK, the plot thickens.

It seems it may not always be a reversal of the operation, but could be a random work/not working situation.

Also, looking in the log in Android Studio, I'm getting an error that says:

01-26 20:22:51.358 2182-5629/com.nooriginalthought.bluebadgeparking E/ViewRootImpl: com.nooriginalthought.bluebadgeparking.websiteViewActivity : Only the original thread that created a view hierarchy can touch its views.

when the method is called.

BUT it does work sometimes.

The methods shown above are within the websiteViewActivity class, but are not within the onCreate method. I'm afraid I don't know if this is relevant or how to ensure the addFlags and clearFlags are run in the correct thread if it is relevant.

[Edit: This question explains how to get things running on the UI thread and has got rid of the 'Only the original thread' error.]

And why does it sometimes work (I can't say if the error show up in the log when it works or not as I've only seen it working when testing away from my PC)?


Solution

  • The text "Only the original thread that created a view hierarchy can touch its views" means that you are executing this code from non-main thread, which is also called a UI Thread.

    The WebView usually executes javascript in a background thread so that's why you get this error.

    Try using "runOnUiThread()"

    runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(mContext, "Keeping screen on", Toast.LENGTH_LONG).show();
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            }
        });