1

I need to track all the time the user location, even when the user is not using my app. However my knowledge of android/ios architecture is little low to know how to do this.

Do I need to make my full app alive in memory at all time (and I think this will be a little waste of resources) or do I need to create a small app like service (don't even know if it's possible) to do this job?

Dovydas Šopa
  • 2,282
  • 8
  • 26
  • 34
  • First you would have to research a bit how it is done with native tools, and then apply learned principles in Delphi. As-is this question is too broad. For Android you can start by looking at [Best way to get user GPS location...](http://stackoverflow.com/questions/28535703/best-way-to-get-user-gps-location-in-background-in-android) and [Location strategies](https://developer.android.com/guide/topics/location/strategies.html) – Dalija Prasnikar Apr 19 '17 at 11:11

1 Answers1

2

Try to use android service with START_STICKY attribute. In background thread you can listen for location changes (do not use standard LocationSensor - just implement java interface based solution).

You can also find examples of background operations for iOS.

For android you might be interested in unit Androidapi.JNI.Location

TLocationListener = class(TJavaLocal, JLocationListener)
  public
    procedure onLocationChanged(location: JLocation); cdecl;
    procedure onProviderDisabled(provider: JString); cdecl;
    procedure onProviderEnabled(provider: JString); cdecl;
    procedure onStatusChanged(provider: JString; status: Integer; extras: JBundle); cdecl;
end

And for your service module you have to declare some variables

TServiceModule = class(TAndroidService)
  function AndroidServiceStartCommand(const Sender: TObject;
    const Intent: JIntent; Flags, StartId: Integer): Integer;
private
  FLocationManager: JLocationManager;
  FLocationManagerService: JObject;
  FLocationListener: JLocationListener;

function TServiceModule.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  Result := TJService.JavaClass.START_STICKY;

  FLocationManagerService := TAndroidHelper.Context.getSystemService(
    TJContext.JavaClass.LOCATION_SERVICE);
  FLocationManager := TJLocationManager.Wrap(
    (FLocationManagerService as ILocalObject).GetObjectID);

  if FLocationManager.isProviderEnabled(
    TJLocationManager.JavaClass.GPS_PROVIDER) then
  begin
    FLocationListener := TLocationListener.Create;
      FLocationManager.requestLocationUpdates(TJLocationManager.JavaClass.GPS_PROVIDER,
        0, 0, FLocationListener, TJLooper.JavaClass.getMainLooper);
  • by google android developer guide https://developer.android.com/reference/android/app/Service.html "START_STICKY is used for services that are explicitly started and stopped as needed". "if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service" – Tomasz Andrzejewski Apr 19 '17 at 19:19
  • thanks tomasz, but in this way how to make that the service will start when the device is started? –  Apr 19 '17 at 21:14
  • You have to create boroadcast receiver (java code). Here you got example http://stackoverflow.com/questions/34210439/how-to-autorun-application-with-background-service-in-delphi – Tomasz Andrzejewski Apr 20 '17 at 07:17
  • here you got full example from DelphiWorlds https://github.com/DelphiWorlds/KastriFree/tree/master/Demos/AndroidLocation – Tomasz Andrzejewski Sep 11 '18 at 08:23