Reputation: 121
I'm wanting to keep the screen on in my Delphi app for Android.
I know that there are two ways:
with the window manager and FLAG_KEEP_SCREEN_ON
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
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
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
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