robert83 2 Posted March 31, 2021 Hello everyone, I am using Delphi 10.3.3 got here Android 10 (also Android 8). Battery Optimization is off . The problem only happens if my Device is on the charger. After approximately 48hrs it dies . I tried to solve this by waking the device up periodically (after 8hrs) . Today it last sent data to the server at 3:00 , so I thought it is dead. But to my big surprise , it still woke up at 08:00 . Unfortunately after touching the screen , to try to open something . Android forced me to close the app. Here is the part of the code : (excuse me for the length, it looks to be long , but is is the bare minimum , I thought I'd include every procedure and function I use in order to perhaps help someone smarter then me see if I am leaking memory or doing something horrible, note : this very same code is NOT crashing or hanging after weeks if Device is not on the charger) procedure TMain.Timer1Timer(Sender: TObject); var SyncTime : TDateTime; TransferTime : TDateTime; begin if FDEviceName = 'error' then Exit; Timer1.Enabled:=false; SyncTime:=inireadDt(FilePath+'/Configuration/settings.conf','Tasks','SyncTime'); if MinutesBetween(now,SyncTime) >= 1 then begin if isDeviceIdleMode = false then begin BatteryLevel := GetBatteryLevel; GetWifiStatus; SendDeviceStatus; iniwrite(FilePath+'/Configuration/settings.conf','Tasks','SyncTime',now); if GetBatteryCharging = 0 then WakeTime := 0; if GetBatteryCharging in [1,2] then inc(WakeTime); // to prevent app from dying we wake up device on the charger after 8 hrs if WakeTime = 480 then begin WakeUpNow; WakeTime:=0; end; end; end; Timer1.Enabled:=true; end; function TMain.GetBatteryLevel; var Filter: JIntentFilter; Battery: JIntent; begin Result:=-1; try Filter := TJIntentFilter.Create; Filter.addAction(TJIntent.JavaClass.ACTION_BATTERY_CHANGED); Battery := TAndroidHelper.Context.registerReceiver(NIL, filter); Result := Battery.getIntExtra(StringToJString('level'), -1); except Result:=-1; end; end; function TMain.GetBatteryCharging; var Filter: JIntentFilter; Battery: JIntent; begin Result:=-1; try Filter := TJIntentFilter.Create; Filter.addAction(TJIntent.JavaClass.ACTION_BATTERY_CHANGED); Battery := TAndroidHelper.Context.registerReceiver(NIL, filter); Result := Battery.getIntExtra(StringToJString('plugged'), -1); except Result:=-1; end; end; procedure TMain.WakeUpNow; var PowerManager : JPowerManager; WakeLock : JPowerManager_WakeLock; begin PowerManager := TJPowerManager.Wrap(TAndroidHelper.Context.getSystemService(TJContext.JavaClass.POWER_SERVICE)); WakeLock := PowerManager.newWakeLock(TJPowerManager.JavaClass.FULL_WAKE_LOCK or TJPowerManager.JavaClass.ACQUIRE_CAUSES_WAKEUP,StringToJString('NE_PACK')); WakeLock.acquire; WakeLock.release; WakeLock:=nil; end; procedure TMain.GetWifiStatus; var obj: JObject; WifiMgr : JWifiManager; WifiInfo : JWifiInfo; begin // ACCESS_FINE_LOCATION Permission and muss ALLOW LOCATION Services on Phone SignalStrength := 0; SSID := '-'; try obj := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.WIFI_SERVICE); WifiMgr := TJWifiManager.Wrap((obj as ILocalObject).GetObjectID); WifiInfo := WifiMgr.getConnectionInfo; case WifiInfo.getRssi of -49..0 : SignalStrength:=4; -59..-50 : SignalStrength:=3; -70..-60 : SignalStrength:=2; else SignalStrength:=1; end; SSID := JStringToString(WifiInfo.getSSID); except SignalStrength := 0; SSID := '-'; end; end; procedure TMain.SendDeviceStatus; var SQLConnection : TSQLConnection; Temp : TServerMethods1Client; begin try SQLConnection := TSQLConnection.Create(nil); try SQLConnection.DriverName:='DataSnap'; SQLConnection.Params.Clear; SQLConnection.Params.Add('DriverUnit=Data.DBXDataSnap'); SQLConnection.Params.Add('DriverAssemblyLoader=Borland.Data.TDBXClientDriverLoader,Borland.Data.DbxClientDriver,Version=24.0.0.0,Culture=neutral,PublicKeyToken=91d62ebb5b0d1b1b'); SQLConnection.Params.Add('DriverName=DataSnap'); SQLConnection.Params.Add('HostName='+FServerIP); SQLConnection.Params.Add('Port='+FServerPort); SQLConnection.Params.Add('Filters={}'); SQLConnection.Params.Add('CommunicationIPVersion=IP_IPv4'); SQLConnection.Params.Add('CommunicationProtocol=tcp/ip'); SQLConnection.Params.Add('DatasnapContext=datasnap/'); SQLConnection.Params.Add('DSProxyPort=8888'); SQLConnection.Params.Add('CommunicationTimeout=500'); SQLConnection.Params.Add('ConnectTimeout=500'); SQLConnection.Connected:=true; Temp := TServerMethods1Client.Create(SQLConnection.DBXConnection); try FOwner := IntToStr(WakeTime); Temp.DEVICE_STATUS(FDeviceName,FOwner,SSID,SoftwareVersion,SignalStrength,BatteryLevel); finally Temp.Free; end; SQLConnection.Close; finally SQLConnection.Free; end; except on E : Exception do begin // nothing end; end; end; Here is the Log file from the last crash : 03-31 07:15:16.070 30336 30374 F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 30374 (RenderThread), pid 30336 (rcadero.NE_PACK) 03-31 07:15:16.296 14307 14307 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 03-31 07:15:16.296 14307 14307 F DEBUG : Build fingerprint: 'Zebra/TC21PG/TC21:10/10-16-10.00-QG-U14-STD-HEL-04/18:user/release-keys' 03-31 07:15:16.296 14307 14307 F DEBUG : Revision: '0' 03-31 07:15:16.296 14307 14307 F DEBUG : ABI: 'arm' 03-31 07:15:16.297 14307 14307 F DEBUG : Timestamp: 2021-03-31 07:15:16+0200 03-31 07:15:16.297 14307 14307 F DEBUG : pid: 30336, tid: 30374, name: RenderThread >>> com.embarcadero.NE_PACK <<< 03-31 07:15:16.297 14307 14307 F DEBUG : uid: 10227 03-31 07:15:16.297 14307 14307 F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- 03-31 07:15:16.297 14307 14307 F DEBUG : Abort message: 'terminating with uncaught exception of type std::__1::system_error: thread constructor failed: Try again' 03-31 07:15:16.297 14307 14307 F DEBUG : r0 00000000 r1 000076a6 r2 00000006 r3 c5d2eb20 03-31 07:15:16.297 14307 14307 F DEBUG : r4 c5d2eb34 r5 c5d2eb18 r6 00007680 r7 0000016b 03-31 07:15:16.297 14307 14307 F DEBUG : r8 c5d2eb30 r9 c5d2eb20 r10 c5d2eb50 r11 c5d2eb40 03-31 07:15:16.298 14307 14307 F DEBUG : ip 000076a6 sp c5d2eaf0 lr ef7e34fb pc ef7e350e 03-31 07:15:16.411 14307 14307 F DEBUG : 03-31 07:15:16.411 14307 14307 F DEBUG : backtrace: 03-31 07:15:16.412 14307 14307 F DEBUG : #00 pc 0006050e /apex/com.android.runtime/lib/bionic/libc.so (abort+166) (BuildId: 8549daf46b82d53f76c6449b777e63ee) 03-31 07:15:16.412 14307 14307 F DEBUG : #01 pc 0003606b /system/lib/libc++.so (abort_message+86) (BuildId: ed0f2f56655f3bf72ea2135f610dee0b) 03-31 07:15:16.412 14307 14307 F DEBUG : #02 pc 000361f3 /system/lib/libc++.so (demangling_terminate_handler()+178) (BuildId: ed0f2f56655f3bf72ea2135f610dee0b) 03-31 07:15:16.412 14307 14307 F DEBUG : #03 pc 00046837 /system/lib/libc++.so (std::__terminate(void (*)())+2) (BuildId: ed0f2f56655f3bf72ea2135f610dee0b) 03-31 07:15:16.412 14307 14307 F DEBUG : #04 pc 00046091 /system/lib/libc++.so (__cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*)+12) (BuildId: ed0f2f56655f3bf72ea2135f610dee0b) 03-31 07:15:16.412 14307 14307 F DEBUG : #05 pc 00045ffd /system/lib/libc++.so (__cxa_throw+72) (BuildId: ed0f2f56655f3bf72ea2135f610dee0b) 03-31 07:15:16.412 14307 14307 F DEBUG : #06 pc 000826cf /system/lib/libc++.so (std::__1::__throw_system_error(int, char const*)+82) (BuildId: ed0f2f56655f3bf72ea2135f610dee0b) 03-31 07:15:16.412 14307 14307 F DEBUG : #07 pc 0000e65f /system/lib/libEGL.so (android::egl_cache_t::setBlob(void const*, long, void const*, long)+230) (BuildId: 338a4d9b681c482215c94f50c9c7e1b8) 03-31 07:15:16.412 14307 14307 F DEBUG : #08 pc 0000e515 /system/lib/libEGL.so (android::setBlob(void const*, long, void const*, long)+20) (BuildId: 338a4d9b681c482215c94f50c9c7e1b8) 03-31 07:15:16.412 14307 14307 F DEBUG : #09 pc 001000eb /vendor/lib/egl/libGLESv2_adreno.so (BuildId: 98c923de8a462f5fbc3bd0621f98282b) 03-31 07:15:16.412 14307 14307 F DEBUG : #10 pc 000945dd /vendor/lib/egl/libGLESv2_adreno.so (BuildId: 98c923de8a462f5fbc3bd0621f98282b) 03-31 07:15:16.412 14307 14307 F DEBUG : #11 pc 001cd267 /system/lib/libhwui.so (GrGLCompileAndAttachShader(GrGLContext const&, unsigned int, unsigned int, char const*, int, GrGpu::Stats*, SkSL::Program::Settings const&)+86) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #12 pc 001cc245 /system/lib/libhwui.so (GrGLProgramBuilder::compileAndAttachShaders(char const*, int, unsigned int, unsigned int, SkTDArray<unsigned int>*, SkSL::Program::Settings const&, SkSL::Program::Settings::Inputs const&)+32) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #13 pc 001cb57b /system/lib/libhwui.so (GrGLProgramBuilder::CreateProgram(GrRenderTarget*, GrSurfaceOrigin, GrPrimitiveProcessor const&, GrTextureProxy const* const*, GrPipeline const&, GrProgramDesc*, GrGLGpu*)+866) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #14 pc 001c7957 /system/lib/libhwui.so (GrGLGpu::ProgramCache::refProgram(GrGLGpu*, GrRenderTarget*, GrSurfaceOrigin, GrPrimitiveProcessor const&, GrTextureProxy const* const*, GrPipeline const&, bool)+190) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #15 pc 001c6dfd /system/lib/libhwui.so (GrGLGpu::flushGLState(GrRenderTarget*, GrSurfaceOrigin, GrPrimitiveProcessor const&, GrPipeline const&, GrPipeline::FixedDynamicState const*, GrPipeline::DynamicStateArrays const*, int, bool)+72) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #16 pc 001c68ff /system/lib/libhwui.so (GrGLGpu::draw(GrRenderTarget*, GrSurfaceOrigin, GrPrimitiveProcessor const&, GrPipeline const&, GrPipeline::FixedDynamicState const*, GrPipeline::DynamicStateArrays const*, GrMesh const*, int)+86) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #17 pc 001c689f /system/lib/libhwui.so (GrGLGpuRTCommandBuffer::onDraw(GrPrimitiveProcessor const&, GrPipeline const&, GrPipeline::FixedDynamicState const*, GrPipeline::DynamicStateArrays const*, GrMesh const*, int, SkRect const&)+30) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #18 pc 001858d3 /system/lib/libhwui.so (GrGpuRTCommandBuffer::draw(GrPrimitiveProcessor const&, GrPipeline const&, GrPipeline::FixedDynamicState const*, GrPipeline::DynamicStateArrays const*, GrMesh const*, int, SkRect const&)+166) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #19 pc 00185633 /system/lib/libhwui.so (GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(GrOp const*, SkRect const&, GrProcessorSet&&, unsigned int, GrUserStencilSettings const*)+310) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #20 pc 003d800f /system/lib/libhwui.so (_ZN12_GLOBAL__N_121ShadowCircularRRectOp9onExecuteEP14GrOpFlushStateRK6SkRect$3d75113d8bcc59e80cffa524fd584b8c+50) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #21 pc 001b435f /system/lib/libhwui.so (GrOp::execute(GrOpFlushState*, SkRect const&)+50) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #22 pc 001b41bf /system/lib/libhwui.so (GrRenderTargetOpList::onExecute(GrOpFlushState*)+282) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.412 14307 14307 F DEBUG : #23 pc 001f9deb /system/lib/libhwui.so (GrDrawingManager::flush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess, GrFlushFlags, int, GrBackendSemaphore*, void (*)(void*), void*)+1086) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.413 14307 14307 F DEBUG : #24 pc 001f9921 /system/lib/libhwui.so (GrDrawingManager::prepareSurfaceForExternalIO(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess, GrFlushFlags, int, GrBackendSemaphore*, void (*)(void*), void*)+128) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.413 14307 14307 F DEBUG : #25 pc 001f97eb /system/lib/libhwui.so (GrRenderTargetContext::prepareForExternalIO(SkSurface::BackendSurfaceAccess, GrFlushFlags, int, GrBackendSemaphore*, void (*)(void*), void*)+86) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.413 14307 14307 F DEBUG : #26 pc 001f978b /system/lib/libhwui.so (SkGpuDevice::flush()+22) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.413 14307 14307 F DEBUG : #27 pc 001b87fd /system/lib/libhwui.so (android::uirenderer::skiapipeline::SkiaPipeline::renderFrame(android::uirenderer::LayerUpdateQueue const&, SkRect const&, std::__1::vector<android::sp<android::uirenderer::RenderNode>, std::__1::allocator<android::sp<android::uirenderer::RenderNode>>> const&, bool, android::uirenderer::Rect const&, sk_sp<SkSurface>, SkMatrix const&)+140) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.413 14307 14307 F DEBUG : #28 pc 001b852b /system/lib/libhwui.so (android::uirenderer::skiapipeline::SkiaOpenGLPipeline::draw(android::uirenderer::renderthread::Frame const&, SkRect const&, SkRect const&, android::uirenderer::LightGeometry const&, android::uirenderer::LayerUpdateQueue*, android::uirenderer::Rect const&, bool, android::uirenderer::LightInfo const&, std::__1::vector<android::sp<android::uirenderer::RenderNode>, std::__1::allocator<android::sp<android::uirenderer::RenderNode>>> const&, android::uirenderer::FrameInfoVisualizer*)+266) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.413 14307 14307 F DEBUG : #29 pc 001f4ff5 /system/lib/libhwui.so (android::uirenderer::renderthread::CanvasContext::draw()+236) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.413 14307 14307 F DEBUG : #30 pc 001f45c1 /system/lib/libhwui.so (android::uirenderer::renderthread::DrawFrameTask::run()+156) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.413 14307 14307 F DEBUG : #31 pc 00202789 /system/lib/libhwui.so (android::uirenderer::WorkQueue::process()+164) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.413 14307 14307 F DEBUG : #32 pc 002025e1 /system/lib/libhwui.so (android::uirenderer::renderthread::RenderThread::threadLoop()+72) (BuildId: f865daa467db141161db34e821858eaa) 03-31 07:15:16.413 14307 14307 F DEBUG : #33 pc 0000da2b /system/lib/libutils.so (android::Thread::_threadLoop(void*)+214) (BuildId: abcd5dd14a985ca140ae57aced79ae67) 03-31 07:15:16.413 14307 14307 F DEBUG : #34 pc 000aaa3b /apex/com.android.runtime/lib/bionic/libc.so (__pthread_start(void*)+20) (BuildId: 8549daf46b82d53f76c6449b777e63ee) Help would be much appriciated. Thank you for your time. Share this post Link to post
Rollo62 536 Posted March 31, 2021 Probably the deprecated FULL_WAKEUP or the ACQUIRE_CAUSES_WAKEUP could cause problems. https://developer.android.com/reference/android/os/PowerManager#FULL_WAKE_LOCK Do you really need to wake up the screen fully ? This seems to be a function that may stress internal behaviours much, I usually start the screen manually and keep the screen awake then, that works OK. Share this post Link to post
robert83 2 Posted March 31, 2021 Hi, I only do this FULL_WAKEUP because it keeps my software running actually longer . (But only when on charger. ) So I only wake up in order to help my software stay alive, i would be fine without this... maybe I will do it with PARTIAL_WAKE_LOCK instead. If the Device is NOT on the charger ... it runs for weeks (with or without FULL_WAKEUP). Share this post Link to post
Rollo62 536 Posted March 31, 2021 (edited) I think its no problem to re-start a WakeUp several times, e.g. by timer every 10 sec., to keep it alive. The user won't notice this. Edited March 31, 2021 by Rollo62 Share this post Link to post
robert83 2 Posted March 31, 2021 I have altered the WakeUpNow procedure a bit : procedure TMain.WakeUpNow; var PowerManager : JPowerManager; WakeLock : JPowerManager_WakeLock; begin PowerManager := TJPowerManager.Wrap(TAndroidHelper.Context.getSystemService(TJContext.JavaClass.POWER_SERVICE)); // WakeLock := PowerManager.newWakeLock(TJPowerManager.JavaClass.FULL_WAKE_LOCK or TJPowerManager.JavaClass.ACQUIRE_CAUSES_WAKEUP,StringToJString('NE_PACK')); WakeLock := PowerManager.newWakeLock(TJPowerManager.JavaClass.PARTIAL_WAKE_LOCK,StringToJstring('NE_PACK')); WakeLock.acquire; WakeLock.release; WakeLock:=nil; end; I am not 100% sure , but this will wake up the CPU and imediatelly allow it to go back to sleep or whatever it was doing. I also altered the Timer1.Timer1Timer Procedure a bit , for more security I start a Anonymous Thread for this job. Also I have changed the Connection and Communication Timeout to 100ms instead of 500ms . procedure TMain.Timer1Timer(Sender: TObject); var SyncTime : TDateTime; TransferTime : TDateTime; begin if FDEviceName = 'error' then Exit; Timer1.Enabled:=false; SyncTime:=inireadDt(FilePath+'/Configuration/settings.conf','Tasks','SyncTime'); if MinutesBetween(now,SyncTime) >= 1 then begin if isDeviceIdleMode = false then begin // created a thread and set the timeout to 100 intead of 500 TThread.CreateAnonymousThread(procedure() begin BatteryLevel := GetBatteryLevel; GetWifiStatus; SendDeviceStatus; end).Start; iniwrite(FilePath+'/Configuration/settings.conf','Tasks','SyncTime',now); if GetBatteryCharging = 0 then WakeTime := 0; if GetBatteryCharging in [1,2] then inc(WakeTime); // to prevent app from dying we wake up device on the charger after 8 hrs if WakeTime = 480 then begin WakeUpNow; WakeTime:=0; end; end; end; Timer1.Enabled:=true; end; Now I will have to wait. Unfortunately for me it takes almost 2 Days to find out if this solved my problem . Or not. Share this post Link to post
Rollo62 536 Posted March 31, 2021 3 hours ago, robert83 said: Now I will have to wait. Unfortunately for me it takes almost 2 Days to find out if this solved my problem . Or not. Good luck. So this means the changes work at least fine for a short period now ? So I thought your original issue should some kind of reproduceable, or was it more or less unpredictable ? Nevertheless, I think that permanently re-ensuring that you really want to stay wake should solve it, since that starts a new wake session hopefully. Share this post Link to post
robert83 2 Posted March 31, 2021 it is Reproducible 🙂 it dies after approx 48hrs 😞 . Always but only on Charger. I made now this above version and another where I only send data every 15 minutes to see if that makes a difference. If neither of them does . Then I will simply check if I am on charger and send data for maybe 8 hrs and after that stop until someone turns the device on . Maybe I am attacking this from a completely wrong standpoint, maybe the Android Device is not meant to be used like this. (if I only have the timer... it works, I am dying 100% because of sending data, and this only happens on the Charger, which is perhaps happening because on the Charger the Android Device is doing a lot more Maintenance jobs and maybe killing my app to release memory for itself... ) Share this post Link to post
Rollo62 536 Posted March 31, 2021 (edited) Maybe the Android Kiosk Mode is something to be considered too. https://www.manageengine.com/mobile-device-management/how-to/kiosk-for-android.html https://snow.dog/blog/kiosk-mode-android https://www.sdgsystems.com/post/implementing-kiosk-mode-in-android-part-1 Edited March 31, 2021 by Rollo62 Share this post Link to post
robert83 2 Posted March 31, 2021 I am running in Kiosk mode 🙂 ( sorry I thought it was irrelevant... ) but this only helps that much if my app dies... it is simply restart... but only if the user actually interacts with the thing. Share this post Link to post
robert83 2 Posted April 6, 2021 I would not believe this if not seeing it with my own eyes . it looks like I need to check if I am in Interactive mode . If I am not in interactive mode then I must do the Reports Back to the Server less often . 15 Minutes instead of 1 Minutes for example. And behold I started the App on 31.03.2021 14:02:40 , and it is 06.04.2021 06:11 and is still running . All other Versions with Anonymous Threads etc. all died. Only this one with 15 Minutes between the jobs survived. I've read somewhere that an app is only allowed to execute once in 10 minutes if in Doze mode. But can't seem to recall where . Maybe this was the reason why it was killed after two days when running on a 1 Minute Interval. The code looks like this : if isInteractive = true then SyncPeriod := 1 else SyncPeriod := 15; SyncTime:=inireadDt(FilePath+'/Configuration/settings.conf','Tasks','SyncTime'); if MinutesBetween(now,SyncTime) >= SyncPeriod then begin if isDeviceIdleMode = false then begin BatteryLevel := GetBatteryLevel; GetWifiStatus; SendDeviceStatus; iniwrite(FilePath+'/Configuration/settings.conf','Tasks','SyncTime',now); end; end; Share this post Link to post