Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wanting to keep the screen on in Delphi app on Android

Tags:

android

delphi

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?

like image 846
M3wP Avatar asked Sep 14 '25 18:09

M3wP


2 Answers

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;
like image 143
Rik Avatar answered Sep 16 '25 08:09

Rik


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;
like image 24
Remy Lebeau Avatar answered Sep 16 '25 09:09

Remy Lebeau