M3wP
M3wP

Reputation: 121

Wanting to keep the screen on in Delphi app on Android

I'm wanting to keep the screen on in my Delphi app for Android.

I know that there are two ways:

  1. with the window manager and FLAG_KEEP_SCREEN_ON

  2. with a "wake lock".

The problems I have are that I can't seem to get a WindowManager instance, let alone get the flag from a layouts class, and wake locks don't seem to be defined (at least in XE8).

The window flag seems like the best way to go, but there appears to be no way of success.

Does anyone know how to do this?

Upvotes: 4

Views: 4672

Answers (3)

Rik
Rik

Reputation: 2032

The solution of calling addFlags() in FormCreate() with FLAG_KEEP_SCREEN_ON doesn't work in Delphi 10.1 Berlin in combination with Android 6 (and probably other combinations).

You will get the following exception:

exception class EJNIException with message 'android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.'.

Somehow the threading of Android/Delphi has changed because this used to work (according to lots of messages). The only way I got it to work (with that one line) was putting this line in the main project-code under Application.Initialize;.

uses
  Androidapi.Helpers,
  Androidapi.JNI.GraphicsContentViewText;

begin
  Application.Initialize;
  SharedActivity.getWindow.addFlags(TJWindowManager_LayoutParams.JavaClass.FLAG_KEEP_SCREEN_ON);
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
end.

But when you want to switch this flag on and off during your program you need to be able to execute it in your form-code. In that case you can use CallInUIThreadAndWaitFinishing() to let this command run in the UIThread. Then you don't get the mentioned exception and the flag works.

uses
  FMX.Helpers.Android,
  Androidapi.Helpers,
  Androidapi.JNI.GraphicsContentViewText;

procedure TMainForm.btnKeepScreenOnAddClick(Sender: TObject);
begin
  CallInUIThreadAndWaitFinishing(
    procedure
    begin
      SharedActivity.getWindow.addFlags(
        TJWindowManager_LayoutParams.JavaClass.FLAG_KEEP_SCREEN_ON);
    end);
end;

procedure TMainForm.btnKeepScreenOnClearClick(Sender: TObject);
begin
  CallInUIThreadAndWaitFinishing(
    procedure
    begin
      SharedActivity.getWindow.clearFlags(
        TJWindowManager_LayoutParams.JavaClass.FLAG_KEEP_SCREEN_ON);
    end);
end;

Upvotes: 9

Remy Lebeau
Remy Lebeau

Reputation: 596256

To use the FLAG_KEEP_SCREEN_ON flag in Delphi, try something like this:

uses
  Androidapi.JNI.App,
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.Helpers;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  SharedActivity.getWindow.addFlags(TJWindowManager_LayoutParams.JavaClass.FLAG_KEEP_SCREEN_ON);
end;

Upvotes: 5

M3wP
M3wP

Reputation: 121

As per the comment from lowrider, this answer worked well:

Delphi XE5 Android. How to use PowerManager.WakeLock?

I did require that no FMX framework be used (without mentioning), but I was able to achieve this in XE8 by replacing the FMX.Helpers.Android reference with Androidapi.helpers (only one, not both was required).

Upvotes: 1

Related Questions