3

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)?

Community
  • 1
  • 1
Fat Monk
  • 2,077
  • 1
  • 26
  • 59
  • I'm currently testing the runOnUIthread fix in the post lined in my edit to see if this resolves the original issue (not just the error). Looking good so far. – Fat Monk Jan 26 '16 at 21:37
  • The question linked in my edit (which has the same solution as GeNia's answer) has resolved the problem. I still don't know why I saw such odd behaviour, though, instead of just not working. – Fat Monk Jan 27 '16 at 22:45

2 Answers2

0

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);
        }
    });
geNia
  • 985
  • 9
  • 20
  • Thanks GeNia. That's exactly what I found in the thread lined in my edit. A very easy fix for shifting things into the UI thread. I must read up on the implications of this, but will keep it in mind for similar problems in the future. – Fat Monk Jan 26 '16 at 21:35
-1
private Window wind;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  //your code

    wind = this.getWindow();
    wind.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
    wind.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    wind.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    wind.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
udaykumar
  • 21
  • 1
  • 5
  • I don't think this is what I want. I believe that the code above will wake the phone and display the activity. All I want is for the screen to stay on (i.e. not dim or turn off after a timeout) while the Web App is in a particular state - with the user still being able to turn the screen off if they wish. For this I believe I only need `FLAG_KEEP_SCREEN_ON` but it seems to be working in reverse. – Fat Monk Jan 26 '16 at 10:07