android delphi service gps

delphi xe10 android service gps



(2)

Esta pregunta ya tiene una respuesta aquí:

Estoy usando Emabarcadero Delphi XE 10 Seattle Update 1 para crear un servicio Android, encontré este tutorial Link y creé una aplicación de servicio, lo que quiero hacer es obtener la ubicación actual cada 5 segundos con Location Sensor y guardarla en la base de datos . Lo estoy haciendo en mi forma principal, pero cuando cierro el programa, se detiene, por lo que no pude encontrar ningún artículo sobre cómo puedo sincronizar mi aplicación y servicio. He intentado agregar el temporizador y Locationsensor al formulario de servicio, pero Delphi no me permite agregarlo a ningún objeto de servicio, creo que necesito enviar un comando al servicio o de alguna manera necesito conectar el servicio y el programa, encontré una muestra que muestra cómo descargar imágenes con el servicio, pero es demasiado experto para un novato como yo :)


Mira este artículo. Daniele Spinetti resuelve un problema usando LocationSensor en servicio.

Coloque las unidades System.Sensors y System.Android.Sensors en su proyecto y realice cambios (Delphi 10 Seattle).

System.Sensors.pas

// about line 748 implementation uses System.Variants, System.Math, System.Character, {$IFDEF ANDROID} // -- patch // include the modified System.Android.Sensors System.Android.Sensors; {$ENDIF ANDROID}

System.Android.Sensors.pas

//about line 12 uses // -- patch // use the modified System.Sensors System.Sensors; ... // about line 70 class constructor TPermission.Create; var PackageInfo: JPackageInfo; PackageManager: JPackageManager; Activity: JActivity; LContext: JContext; begin // -- patch // Activity := TJNativeActivity.Wrap // (PANativeActivity(System.DelphiActivity)^.clazz) LContext := TJContextWrapper.Wrap(System.JavaContext); PackageManager := LContext.getPackageManager(); PackageInfo := PackageManager.getPackageInfo (LContext.getApplicationContext.getPackageName, TJPackageManager.JavaClass.GET_PERMISSIONS); FPermissions := PackageInfo.requestedPermissions; end; ... // about line 100 type TAndroidGeocoder = class(TGeocoder) private type TGeocoderRunnable = class(TJavaLocal, JRunnable) private FCoord: TLocationCoord2D; FLGeocoder: JGeocoder; public constructor Create(ACoord: TLocationCoord2D; AGeocoder: JGeocoder); procedure run; cdecl; end; private class var FGeocoder: JGeocoder; // FActivity: JActivity; // -- patch FActivity: JContextWrapper; // -- patch ... // about line 130 TUIAndroidLocationSensor = class(TCustomLocationSensor) private FPermitted: Boolean; // FActivity: JNativeActivity; // -- patch FActivity: JContext; // -- patch FLastValue: JLocation; FLocationManager: JLocationManager; FAccuracy: TLocationAccuracy; ... // about line 1500 constructor TUIAndroidLocationSensor.Create(AManager: TSensorManager); var LocationService: JObject; begin inherited; // FActivity := TJNativeActivity.Wrap // (PANativeActivity(System.DelphiActivity)^.clazz); // -- patch FActivity := TJContext.Wrap(System.JavaContext); // -- patch LocationService := FActivity.getSystemService (TJContext.JavaClass.LOCATION_SERVICE); if Assigned(LocationService) then FLocationManager := TJLocationManager.Wrap((LocationService as ILocalObject) .GetObjectID); end; ... // about line 1530 function RunIfPossible(var ARunnable: TLocationRunnable; var AListener: TLocationListener; AProviderName: JString): Boolean; var Provider: JLocationProvider; LHandler: JHandler; begin Result := False; if FLocationManager.isProviderEnabled(AProviderName) then begin if AListener = nil then AListener := TLocationListener.Create(Self); Provider := FLocationManager.getProvider(AProviderName); if Provider <> nil then begin ARunnable := TLocationRunnable.Create(FLocationManager, AListener, AProviderName); // FActivity.runOnUiThread(ARunnable); // --patch // -- patch // You can use post method of Handler instead runOnUiThread in this case. // more info here: http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html LHandler := TJHandler.JavaClass.init; LHandler.post(ARunnable); Result := True; end; end; end; ... // about line 1730 class constructor TAndroidGeocoder.Create; begin // -- patch // FActivity := TJNativeActivity.Wrap // (PANativeActivity(System.DelphiActivity)^.clazz); FActivity := TJContextWrapper.Wrap(System.JavaContext); FGeocoder := TJGeocoder.JavaClass.init(FActivity); end;

Entonces puede usar LocationSensor así:

uses System.Sensors, System.Android.Sensors; ... var FSensors: TSensorArray; Sensor: TCustomSensor; begin TSensorManager.Current.Active := true; FSensors := TSensorManager.Current.GetSensorsByCategory(TSensorCategory.Location); FSensor := nil; for Sensor in FSensors do begin if TCustomLocationSensor(Sensor).SensorType = TLocationSensorType.GPS then begin FSensor := TCustomLocationSensor(Sensor); Break; end; end; if not Assigned(FSensor) then Exit; { no location sensor is available } { start the sensor if it is not started } if not FSensor.Started then FSensor.Start;


si TTimer no funciona como esperaba, intente hacer todas sus cosas en un hilo anónimo y use TThread.CurrentThread.Sleep en el hilo principal

function TServiceModule.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer; begin Result := TJService.JavaClass.START_STICKY; TThread.CreateAnonymousThread(procedure begin repeat TThread.Current.Sleep(MSecsPerSec); TThread.CreateAnonymousThread(procedure DoStuff(); end).Start; TThread.Current.Sleep(MSecsPerSec); until (TThread.Current.CheckTerminated); end).Start; end;