Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Powersave deaktivieren (Win: ok, Android: ok, iOS: ???) (https://www.delphipraxis.net/195724-powersave-deaktivieren-win-ok-android-ok-ios.html)

knaeuel 20. Mär 2018 12:37

Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
 
Hallo zusammen,

ich habe heute meine Zeit bisher damit verbracht, herauszufinden, wie ich auf den 3 genannten Plattformen den Powersave-Modus vorübergehend deaktivieren kann.

iOS: Für iOS hab ich noch keine Lösung gefunden. HILFE! :)
Android: kurz getestet, funzt (längerer Test folgt heute über Nacht)
Windows: Programm läuft und meckert nicht, echter Test folgt heute Abend

Ich habe jetzt noch nicht aufgeräumt und man könnte stilistisch sofort was verbessern, aber mir gehts erstmal um die Funktionalität.

hier schonmal der funktionierende Code:

Delphi-Quellcode:
unit Powermanagement;

interface

{$IFDEF ANDROID}
function Acquire_PARTIAL_WAKE_LOCK: Boolean;
function Acquire_SCREEN_DIM_WAKE_LOCK: Boolean;
function Acquire_SCREEN_BRIGHT_WAKE_LOCK: Boolean;
function Acquire_FULL_WAKE_LOCK: Boolean;
procedure ReleaseWakeLock;
{$ENDIF}

{$IFDEF MSWINDOWS}
type EXECUTION_STATE = UINT32;//System.DWORD; 4 byte unsigned int


//If the function succeeds, the return value is the previous thread execution state.
//If the function fails, the return value is NULL.
function SetThreadExecutionState(esFlags: EXECUTION_STATE): EXECUTION_STATE; stdcall; external 'kernel32.dll';


const
  //Away mode should be used only by media-recording and media-distribution
  //applications that must perform critical background processing on desktop
  //computers while the computer appears to be sleeping.
  ES_AWAYMODE_REQUIRED = UINT32($00000040); //Enables away mode. This value must be specified with ES_CONTINUOUS.
  {$EXTERNALSYM ES_AWAYMODE_REQUIRED}
  ES_SYSTEM_REQUIRED  = UINT32($00000001); //Forces the system to be in the working state by resetting the system idle timer.
  {$EXTERNALSYM ES_SYSTEM_REQUIRED}
  ES_DISPLAY_REQUIRED = UINT32($00000002); //Forces the display to be on by resetting the display idle timer.
  {$EXTERNALSYM ES_DISPLAY_REQUIRED}
  ES_CONTINUOUS       = UINT32($80000000); //anweisungen mit ES_CONTINUOUS bleiben
  {$EXTERNALSYM ES_CONTINUOUS}              //aktiv, bis nochmal ES_CONTINUOUS gesendet wird
{$ENDIF}

implementation

uses
{$IFDEF ANDROID}
  Androidapi.JNI,
  Androidapi.JNIBridge,
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.JavaTypes,
  Androidapi.Helpers,
  Androidapi.JNI.Os, // enthält wakelock - added in Berlin
  FMX.Helpers.Android,
{$ENDIF}
  System.SysUtils;

{$IFDEF ANDROID}
function GetPowerManager: JPowerManager;
var
  PowerServiceNative: JObject;
begin
  PowerServiceNative := TAndroidHelper.Context.getSystemService(// veraltet: SharedActivityContext.getSystemService(
    TJContext.JavaClass.POWER_SERVICE);
  if not Assigned(PowerServiceNative) then
    raise Exception.Create('Could not locate Power Service');
  Result := TJPowerManager.Wrap(
    (PowerServiceNative as ILocalObject).GetObjectID);
  if not Assigned(Result) then
    raise Exception.Create('Could not access Power Manager');
end;

var
  // *** this is in Androidapi.JNI.Os (since Delphi 10.1 Berlin)
  // WakeLock: JWakeLock = nil;
  WakeLock: JPowerManager_WakeLock = nil;

//ANDROID:
// es gibt noch 2 weitere Flags, die sich auf die Wakelocks mit
// eingeschaltetem Bildschirm beziehen:
// ON_AFTER_RELEASE
// ACQUIRE_CAUSES_WAKEUP   -> siehe web developer.android.com

// bei PARTIAL_WAKE_LOCK ist die CPU immer an (User hat keinerlei Einfluss)
// bei den Modi mit eingeschaltetem Bildschirm kann der User über
// Drücken des Powerknopfes alles (inkl. CPU) in den Schlafzustand schicken
// und damit den Wakelock "überschreiben"
//ENDE ANDROID

//PARTIAL_WAKE_LOCK: CPU ON; Screen OFF; Keyboard OFF
function Acquire_PARTIAL_WAKE_LOCK: Boolean;
var
  PowerManager: JPowerManager;
begin
  Result := Assigned(WakeLock);
  if not Result then
  begin
    PowerManager := GetPowerManager;
    WakeLock := PowerManager.newWakeLock(
      TJPowerManager.JavaClass.PARTIAL_WAKE_LOCK,
      StringToJString('Delphi'));
    Result := Assigned(WakeLock);
  end;
  if Result then
  begin
    if not WakeLock.isHeld then
    begin
      WakeLock.acquire;
      Result := WakeLock.isHeld
    end;
  end;
end;

//SCREEN_DIM_WAKE_LOCK: CPU ON; Screen DIM; Keyboard OFF
function Acquire_SCREEN_DIM_WAKE_LOCK: Boolean;
var
  PowerManager: JPowerManager;
begin
  Result := Assigned(WakeLock);
  if not Result then
  begin
    PowerManager := GetPowerManager;
    WakeLock := PowerManager.newWakeLock(
      TJPowerManager.JavaClass.SCREEN_DIM_WAKE_LOCK,
      StringToJString('Delphi'));
    Result := Assigned(WakeLock);
  end;
  if Result then
  begin
    if not WakeLock.isHeld then
    begin
      WakeLock.acquire;
      Result := WakeLock.isHeld
    end;
  end;
end;

//SCREEN_BRIGHT_WAKE_LOCK: CPU ON; Screen BRIGHT; Keyboard OFF
function Acquire_SCREEN_BRIGHT_WAKE_LOCK: Boolean;
var
  PowerManager: JPowerManager;
begin
  Result := Assigned(WakeLock);
  if not Result then
  begin
    PowerManager := GetPowerManager;
    WakeLock := PowerManager.newWakeLock(
      TJPowerManager.JavaClass.SCREEN_BRIGHT_WAKE_LOCK,
      StringToJString('Delphi'));
    Result := Assigned(WakeLock);
  end;
  if Result then
  begin
    if not WakeLock.isHeld then
    begin
      WakeLock.acquire;
      Result := WakeLock.isHeld
    end;
  end;
end;

//FULL_WAKE_LOCK: CPU ON; Screen BRIGHT; Keyboard BRIGHT
function Acquire_FULL_WAKE_LOCK: Boolean;
var
  PowerManager: JPowerManager;
begin
  Result := Assigned(WakeLock);
  if not Result then
  begin
    PowerManager := GetPowerManager;
    WakeLock := PowerManager.newWakeLock(
      TJPowerManager.JavaClass.FULL_WAKE_LOCK,
      StringToJString('Delphi'));
    Result := Assigned(WakeLock);
  end;
  if Result then
  begin
    if not WakeLock.isHeld then
    begin
      WakeLock.acquire;
      Result := WakeLock.isHeld
    end;
  end;
end;

procedure ReleaseWakeLock;
begin
  if Assigned(WakeLock) then
  begin
    WakeLock.release;
    WakeLock := nil
  end;
end;
{$ENDIF}

end.

In meinem Fall kann der Bildschirm ruhig ausgehen, Tastatur sowieso, nur die CPU soll weiter arbeiten. Der Aufruf erfolgt dann für dieses Beispiel so:

Delphi-Quellcode:
procedure PowerSaveON;
begin
{$IFDEF ANDROID}
  ReleaseWakeLock;
{$ENDIF}
{$IFDEF MSWINDOWS}
  SetThreadExecutionState(ES_CONTINUOUS);
{$ENDIF}
end;

procedure PowerSaveOFF;
begin
{$IFDEF ANDROID}
  Acquire_PARTIAL_WAKE_LOCK;
{$ENDIF}
{$IFDEF MSWINDOWS}
  SetThreadExecutionState(ES_CONTINUOUS or ES_SYSTEM_REQUIRED or ES_AWAYMODE_REQUIRED);
{$ENDIF}
end;
Hat jemand einen Ansatz oder eine Lösung für iOS? Meine Google-Versuche sind alle ziemlich erfolglos geblieben. Ich finde nur Schrott...

Danke schonmal vorab!

MEissing 20. Mär 2018 16:09

AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
 
Code:
var
  UIApp : UIApplication;
begin
  UIApp := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication);
  UIApp.setIdleTimerDisabled(True);
end;
http://www.malcolmgroves.com/blog/?p=1387

KodeZwerg 20. Mär 2018 18:56

AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
 
Dürfte ich OT mal eine Frage stellen, ich hatte mir mal einen VideoPlayer gebastelt der den Nachteil hatte das Windows irgendwann sich abschaltete (keine Maus/Tastatur eingaben), daraufhin hab ich ein wenig recherchiert und bin auch auf das SetThreadExecutionState() aufmerksam geworden.
Bei mir sollte halt der Bildschirm und das System an bleiben, ich nutzte allerdings ES_SYSTEM_REQUIRED und ES_DISPLAY_REQUIRED.
Als ich nun deine Kommentare dazu las frag ich mich, war meine Methode falsch? (für Windows)

knaeuel 23. Mär 2018 08:48

AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
 
Zitat:

Zitat von MEissing (Beitrag 1396795)
Code:
var
  UIApp : UIApplication;
begin
  UIApp := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication);
  UIApp.setIdleTimerDisabled(True);
end;
http://www.malcolmgroves.com/blog/?p=1387

Herzlichen Dank! :thumb:

@KodeZwerg:
Für mich hört sich das nicht falsch an. Du wolltest ja vermutlich den Bildschirm anlassen und nicht nur das System => war wohl genau richtig, was du gemacht hast. Oder wie kamst du da drauf?

knaeuel 26. Mär 2018 14:22

AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
 
Zitat:

Zitat von MEissing (Beitrag 1396795)
Code:
var
  UIApp : UIApplication;
begin
  UIApp := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication);
  UIApp.setIdleTimerDisabled(True);
end;
http://www.malcolmgroves.com/blog/?p=1387

Ich war noch auf der Suche nach "UIApplication".

Die kontextbezogene Hilfe in Delphi 10.2 (Version 25.0.29899.2631) funktioniert so gut wie gar nicht. Bei mir öffnet sich immer nur die Standard-Hilfe "Hilfe zum Quelltexteditor" - könnt ich reinschlagen, wenn ich das - mal wieder - angezeigt bekomme.

Suche auf dem Docwiki bringt ebenfalls nichts. Nachfragen wie "Meintest du 'UI Application'?" was dann zu Metropolis UI Applications führt, bringen nicht weiter.

Aber dann habe ich entdeckt, dass MEissing einen Blog-Link hinzugefügt hatte. In dem Blog kann man nachlesen, dass die benötigte Unit "iOSapi.UIKit" heißt. Erstaunlich, dass man diese Info der Embarcadero-Hilfe nicht abringen kann. man man man... warum ist das so schlecht geworden? das hat früher funktioniert.

DeddyH 26. Mär 2018 14:29

AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
 
Man müsste nur den verlinkten Artikel lesen:
Zitat:

A TUIApplication factory class, and a UIApplication interface are defined in the iOSapi.UIKit.pas file that ships with Delphi.

KodeZwerg 26. Mär 2018 18:20

AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
 
Sorry ich habe völlig falsch beschrieben bzw vergessen das was ich meinte zu erwähnen.
Ich muss für Windows das "SetThreadExecutionState()" (mit meinen erwähnten Definitionen) in einer Timer-Event immer wieder aufrufen lassen, ein einmaliger Aufruf brachte mich nicht ans Ziel, daß das System weder einschläft noch das sich der Monitor auf Standby schaltet.
Liegt es an mir oder ist das für Windows normal? (mich stört es nicht da es kaum Resourcen kostet)

HolgerX 26. Mär 2018 19:54

AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
 
Hmm..

das mit dem SetThreadExecutionState() funktioniert nur unter Windows XP.

Ab W7 sind da andere APIs notwendig...

PowerCreateRequest
PowerSetRequest
PowerClearRequest

Es können verschiedene PowerRequests von verschiedenen Threads innerhalb eines Processes erstellt werden.

Mit powercfg (Batch, AsAdmin) können aktuelle Threads aufgelistet werden, welche nicht durch PowerSave unterbrochen werden sollen.

KodeZwerg 26. Mär 2018 22:39

AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
 
PowerCreateRequest, PowerSetRequest, PowerClearRequest
Ich kenne noch gar keinen, da muss ich mal was nachholen und mich ein wenig belesen.

SetThreadExecutionState() funktioniert auch mit Windows 10, kann sein das es nur noch als Abwärtskompatibilität enthalten ist, ala WinExec(), wie gesagt, da muss ich erst noch ein wenig lesen.

Danke für die Information!

ps: das es noch funktioniert merke ich an einer unter WindowsXP programmierten Anwendung die ich bei Rechnerstart laden lasse.

HolgerX 27. Mär 2018 07:08

AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
 
Hmm..


Bei den PowerSave.. genügt es einmal zum Programmstart PowerCreateRequest/PowerSetRequest zu verwenden.
Hingegen funktioniert SetThreadExecutionState (soweit ich mich noch erinnern kann ;) ) nur unter XP ohne Timer...

Hatte vor Jahren für einen Mediaplayer damit experimentiert ;)

Hier dann abhängign vom OS unter XP/Vista das SetThreadExecutionState und ab W7 PowerCreateRequest/PowerSetRequest verwendet.
Ich fand es auch interessant, dass man sich den Status aller Programme per powercfg auflisten lassen konnte und somit direkt prüfen kann, ob der Eintrag auch richtig angekommen ist ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:44 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz