I'm trying to write a FireMonkey app, which must do some work in background (not very intensive task), even if the user of the device switches to another app or the display turns off. In this task I periodically send an HTTP request (with TIdHTTP) to a server to get a small piece of data and to test if the app is still running.
By default, Android is closing apps in background or when the user turns off the display. I tried two methods to keep my app running:
Adding the app through the Androids UI to the list of "protected apps" (disabling power optimizations for the app / "keep running while screen is off").
I created a local service (TAndroidService) with the sticky flag (START_STICKY) through the project wizard and moved the task code there.
Starting service from host application:
// LIntent and LServiceName are stored in TForm1
procedure TForm1.StartMyService();
begin
LIntent := TJIntent.Create();
LServiceName := 'com.embarcadero.services.MyService';
LIntent.setClassName(TAndroidHelper.Context.getPackageName(), TAndroidHelper.StringToJString(LServiceName));
TAndroidHelper.Activity.startService(LIntent);
end;
The OnStartCommand event in the service looks like this:
function TMyServiceDM.AndroidServiceStartCommand(const Sender: TObject;
const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
Result := TJService.JavaClass.START_STICKY;
LThread := TThread.CreateAnonymousThread(procedure
begin
while True do
begin
// ... Task performed here periodically and exits loop when needed ...
// Sleep for 1 minute
LThread.Sleep(60000);
end;
// Before thread stops, also stop the Java service
JavaService.stopSelf(StartId);
end);
LThread.FreeOnTerminate := False;
LThread.Start();
end;
The app keeps working in background and even if the display is turned off BUT only while the device is connected through a cable with a power source (e. g. over a USB cable with my machine). If the power cable is removed, the app seems to stop instantly when the screen turns off, even if the app stays in foreground.
Do I do something wrong? How can I keep my service doing its job in background (like messenger apps which do something similar)? I know, that Android 6.0 (API level 23) and upwards use a feature called "Doze" and Google want their devs to use FCM (Firebase Cloud Messaging). I read about it only recently and hoped that at least disabling the power optimizations for the app would fix this problem, but no.