Jump to content
at3s

LocationSensor returns NaN as Longitude and Latitude at the first calling

Recommended Posts

I have a screen with the: 

LocationSensor: TLocationSensor;

And code:

procedure Tfrm.FormCreate(Sender: TObject);
begin
  LocationSensor.Active := True;
end;

procedure Tfrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  LocationSensor.Active := False;
  Action := TCloseAction.caFree;
end;

procedure ShowLocation();
var
  mapPosition: TMapCoordinate;
begin
  frm := Tfrm.Create(Application);
  try
    mapPosition := TMapCoordinate.Create(frm.LocationSensor.Sensor.Latitude, frm.LocationSensor.Sensor.Longitude);

    ShowMessage(FloatToStr(frm.LocationSensor.Sensor.Latitude) + ' | ' + FloatToStr(frm.LocationSensor.Sensor.Longitude));
  finally
    frm.Show;
    frm.BringToFront;
  end;
end;

When I call ShowLocation(); in Android 12, it returns 'NaN | NaN' first time, after that each calling returns correct coordinates.

 

Is it a known issue or did I miss something?

Edited by at3s

Share this post


Link to post
44 minutes ago, Rollo62 said:

Have you performed a PermissionRequest before?

Yes, and a location finding works fine at the second and next times.

When I did a trick with the repeat ... until + ShowMessage - after few times it found a location.

But when I commented ShowMessage, it stopped to work at first execution.

Weird behaviour.

Share this post


Link to post

Ok. Somehow fixed using OnLocationChanged event.

Share this post


Link to post

Yes, the location is called asynchronously.

 

I also would not stress the system directly in FormCreate, with the activation of Location, where it is still loading and initializating.
Better to do that at a later time, maybe FormShow, or even better, manually controlled on demand by your own code only.

 

I'm not sure if you asked for PermissionRequest correctly, because I cannot see something similar like this in your code.

The result should be in mainUI thread, but to ensure that this is true you can use ForceQueue, to protect this against mysterious situations.

I know that Android systems might forgive many of such issues in debug mode, but clearly is at high risk to fail in release and PlayStore.

12 hours ago, at3s said:

Yes,

procedure Tfrm.FormShow(Sender: TObject);
begin
    DoLocationActivate;
end;

procedure Tfrm.DoLocationActivate;
begin
    TPermissionsService.DefaultService.RequestPermissions(
        [LPermissionLocationF, LPermissionLocationC]
        // PermissionResult
      , procedure ( const APermissions: TClassicStringDynArray;  const AGrantResults: TClassicPermissionStatusDynArray )
        begin
            if      (     ( Length( AGrantResults )  <> 2                           )
                      or (        ( AGrantResults[0] <> TPermissionStatus.Granted ) ) 
                      or (        ( AGrantResults[1] <> TPermissionStatus.Granted ) ) 
                    ) then
            begin
                exit;  //user doesnt grant access
            end;

            TThread.ForceQueue(   // this should not be necessary, but just to ensure that Active := True is really called in the main thread only
                procedure
                begin
                    LocationSensor.Active := True;
                end );
        
        end );
end;

 

Edited by Rollo62
  • Thanks 1

Share this post


Link to post
11 hours ago, Rollo62 said:

Yes, the location is called asynchronously.

 

I also would not stress the system directly in FormCreate, with the activation of Location, where it is still loading and initializating.
Better to do that at a later time, maybe FormShow, or even better, manually controlled on demand by your own code only.

 

I'm not sure if you asked for PermissionRequest correctly, because I cannot see something similar like this in your code.

The result should be in mainUI thread, but to ensure that this is true you can use ForceQueue, to protect this against mysterious situations.

I know that Android systems might forgive many of such issues in debug mode, but clearly is at high risk to fail in release and PlayStore.


procedure Tfrm.FormShow(Sender: TObject);
begin
    DoLocationActivate;
end;

procedure Tfrm.DoLocationActivate;
begin
    TPermissionsService.DefaultService.RequestPermissions(
        [LPermissionLocationF, LPermissionLocationC]
        // PermissionResult
      , procedure ( const APermissions: TClassicStringDynArray;  const AGrantResults: TClassicPermissionStatusDynArray )
        begin
            if      (     ( Length( AGrantResults )  <> 2                           )
                      or (        ( AGrantResults[0] <> TPermissionStatus.Granted ) ) 
                      or (        ( AGrantResults[1] <> TPermissionStatus.Granted ) ) 
                    ) then
            begin
                exit;  //user doesnt grant access
            end;

            TThread.ForceQueue(   // this should not be necessary, but just to ensure that Active := True is really called in the main thread only
                procedure
                begin
                    LocationSensor.Active := True;
                end );
        
        end );
end;

 

Yes, there is PermissionRequest in the code, but I did not provide it here.

It executes before a screen showing.

 

Your code works fine and it's more elegant and correct than my trick with the OnLocationChanged event, thanks for an answer.

Share this post


Link to post
13 hours ago, at3s said:

Yes, there is PermissionRequest in the code, but I did not provide it here.

It executes before a screen showing.

Yes, but if you touch the Location already in FormCreate, then the permission request comes later, and this will be problematic.

That was my point.

Share this post


Link to post
21 minutes ago, Rollo62 said:

Yes, but if you touch the Location already in FormCreate, then the permission request comes later, and this will be problematic.

That was my point.

Thank you for your respond.

Permission request is before screen create procedure calling, so it's ok, thanks again.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×