![]() |
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:
Hat jemand einen Ansatz oder eine Lösung für iOS? Meine Google-Versuche sind alle ziemlich erfolglos geblieben. Ich finde nur Schrott...
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; Danke schonmal vorab! |
AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
Code:
var
UIApp : UIApplication; begin UIApp := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication); UIApp.setIdleTimerDisabled(True); end; ![]() |
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) |
AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
Zitat:
@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? |
AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
Zitat:
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. |
AW: Powersave deaktivieren (Win: ok, Android: ok, iOS: ???)
Man müsste nur den verlinkten Artikel lesen:
Zitat:
|
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) |
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. |
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. |
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 04:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz