【问题标题】:Wanting to keep the screen on in Delphi app on Android想要在 Android 上的 Delphi 应用程序中保持屏幕开启
【发布时间】:2016-01-15 00:52:30
【问题描述】:

我想在我的 Android 版 Delphi 应用程序中保持屏幕开启。

我知道有两种方法:

  1. 使用窗口管理器和 FLAG_KEEP_SCREEN_ON

  2. 带有“唤醒锁”。

我遇到的问题是我似乎无法获得WindowManager 实例,更不用说从布局类中获得标志了,而且似乎没有定义唤醒锁(至少在 XE8 中)。

窗口标志似乎是最好的方法,但似乎没有成功的方法。

有人知道怎么做吗?

【问题讨论】:

标签: android delphi


【解决方案1】:

使用FLAG_KEEP_SCREEN_ONFormCreate() 中调用addFlags() 的解决方案在Delphi 10.1 Berlin 中与Android 6(可能还有其他组合)结合使用时不起作用。

你会得到以下异常:

带有消息的异常类 EJNIException 'android.view.ViewRootImpl$CalledFromWrongThreadException: 只有 创建视图层次结构的原始线程可以触及其视图。'。

不知何故,Android/Delphi 的线程发生了变化,因为这曾经可以工作(根据大量消息)。我让它工作的唯一方法(用那一行)是把这行放在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.

但是当你想在你的程序中打开和关闭这个标志时,你需要能够在你的表单代码中执行它。在这种情况下,您可以使用CallInUIThreadAndWaitFinishing() 让此命令在 UIThread 中运行。然后你没有得到提到的异常并且标志有效。

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;

【讨论】:

  • SharedActivity 已弃用,您现在可以改用“TAndroidHelper.Activity”。
  • ...并添加uses System.SysUtils, Androidapi.JNI.App
【解决方案2】:

要在 Delphi 中使用 FLAG_KEEP_SCREEN_ON 标志,请尝试以下操作:

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;

【讨论】:

  • 在荷兰论坛上,我们发现如果您在 FormCreate 中执行此操作,它将不起作用。在 Application.Initialize 之后将其放入您的主项目源中确实有效。见nldelphi.com/…
  • @Rik 讨论并没有说明它在 OnCreate 中不起作用。而且由于它是一个特定于窗口的设置,可以随时设置和清除,我不明白为什么它在 OnCreate 中不起作用。您是否有任何具体细节说明为什么它在 OnCreate 中不起作用?它在主 UI 线程中调用,与 DPR 代码相同
  • 关于它在 OnCreate 中不起作用的讨论是我指出的那个之前的几篇文章。在这里:nldelphi.com/…。顺便提一句。我在那次讨论中是 rvk,在我在 OnCreate 中发布了执行此操作的建议后我尝试了它,它在 Android 中给了我一个黑屏并且应用程序被挂起。把它放在 Application.Initialize 下它起作用了。也许它也可以放在一个按钮中(并在另一个按钮中清除标志),但我还没有尝试过。明天我会尝试,然后报告到底什么是有效的,什么是无效的。
  • 好的,测试过了。在 Delphi 10.1 Berlin 中,我总是遇到这个 Project Project1.apk raised exception class EJNIException with message 'android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.'. 的例外情况,要么这是 Berlin 10.1 中的错误(因为表单线程和主线程相同),要么在 Android 6.0.1 中有些奇怪。如果我没有捕捉到异常,应用程序就会崩溃。如果我用 try/except 捕捉到异常,所有工作正常并且屏幕保持打开状态(这让我相信这是一个 Delphi 问题)。
  • 它似乎在 10.2.1 上运行良好,但是在表单创建后我该如何管理它?所以每次用户选中一个复选框或其他东西时屏幕都不会关闭!
【解决方案3】:

根据 lowrider 的评论,这个答案效果很好:

Delphi XE5 Android. How to use PowerManager.WakeLock?

我确实要求不使用 FMX 框架(没有提及),但我能够在 XE8 中通过将 FMX.Helpers.Android 引用替换为 Androidapi.helpers 来实现这一点(只需要一个,而不是两个都需要)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多