Delphi GPS 传感器不显示坐标

Delphi GPS Sensor doesn't show coordinates

我有一个 fmx 表格,上面只有一个 LocationSensor、一个 Memo 和一个 Button,并使用下面的代码在备忘录中显示坐标。当我打开 phone 上的 GPS 时,当我单击按钮时会显示“1”和“2”,这似乎有效,但我的备忘录中没有添加任何行。我尝试了不同的代码示例,但没有一个代码示例适合我以任何方式显示坐标。

我使用 Samsung A3 (SM-A310F),最初是 stock rom (Android 7),现在使用 Lineage 17.1(基于 Android 10)来测试它,并在两个版本上进行测试到目前为止,GPS 坐标没有任何效果。我使用 Delphi 10.3.3 社区版。

我做错了什么?

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes,
  System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.ScrollBox,
  FMX.Memo, FMX.Controls.Presentation, FMX.StdCtrls, System.Sensors,
  System.Sensors.Components,

  Androidapi.JNI.Location,
  Androidapi.JNIBridge,
  FMX.Helpers.Android,
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.Helpers;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    LocationSensor1: TLocationSensor;
    procedure Button1Click(Sender: TObject);
    procedure LocationSensor1LocationChanged(Sender: TObject;
      const OldLocation, NewLocation: TLocationCoord2D);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
  locationManager: JLocationManager;
begin

  LocationSensor1.Active := true;

  locationManager := TJLocationManager.Wrap
    (((SharedActivity.getSystemService(TJContext.JavaClass.LOCATION_SERVICE))
    as ILocalObject).GetObjectID);

  if locationManager.isProviderEnabled(TJLocationManager.JavaClass.GPS_PROVIDER)
  then
  begin
    showmessage('1');
  end;

  if locationManager.isProviderEnabled
    (TJLocationManager.JavaClass.NETWORK_PROVIDER) then
  begin
    showmessage('2');
  end;
end;

procedure TForm1.LocationSensor1LocationChanged(Sender: TObject;
  const OldLocation, NewLocation: TLocationCoord2D);
begin
  Memo1.Lines.Add(FloatToStr(NewLocation.Longitude));
  Memo1.Lines.Add(FloatToStr(NewLocation.Latitude));
end;

end.

更新:我找到了西班牙文的解决方案(见下文)

我在 YouTube 上找到了西班牙语的解决方案:https://www.youtube.com/watch?v=iiPFpzGICws 它将我链接到这个文件:https://drive.google.com/file/d/1kGHlaaSfSfeAcOsiWG7mAsH5Vl_kXdzS/view

我不懂任何西班牙语,但我试图理解他的工作,现在我将在我的应用程序中重用他的版本。这是迄今为止我在 Internet 上找到的唯一版本,而且效果非常好。

因此,如果链接被删除,请在此处提供代码:

unit Form_Principal;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
  FMX.WebBrowser, FMX.StdCtrls, FMX.Controls.Presentation, FMX.Objects,
  System.Permissions, System.Sensors, System.Sensors.Components;

type
  TForm1 = class(TForm)
    WebBrowser: TWebBrowser;
    Layout1: TLayout;
    Switch: TSwitch;
    Label1: TLabel;
    Layout2: TLayout;
    RoundRect1: TRoundRect;
    lbl_endereco: TLabel;
    LocationSensor: TLocationSensor;
    procedure FormCreate(Sender: TObject);
    procedure SwitchClick(Sender: TObject);
    procedure LocationSensorLocationChanged(Sender: TObject; const OldLocation,
      NewLocation: TLocationCoord2D);
    procedure lbl_enderecoClick(Sender: TObject);
  private
    { Private declarations }
    Location: TLocationCoord2D;
    FGeocoder: TGeocoder;

    {$IFDEF ANDROID}
     Access_Fine_Location, Access_Coarse_Location : string;
     procedure DisplayRationale(Sender: TObject;
              const APermissions: TArray<string>; const APostRationaleProc: TProc);
     procedure LocationPermissionRequestResult
                (Sender: TObject; const APermissions: TArray<string>;
                const AGrantResults: TArray<TPermissionStatus>);
    {$ENDIF}

    procedure OnGeocodeReverseEvent(const Address: TCivicAddress);

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

uses FMX.DialogService

{$IFDEF ANDROID}
,Androidapi.Helpers, Androidapi.JNI.JavaTypes, Androidapi.JNI.Os
{$ENDIF}

;

{$IFDEF ANDROID}

procedure TForm1.DisplayRationale(Sender: TObject;
  const APermissions: TArray<string>; const APostRationaleProc: TProc);
var
  I: Integer;
  RationaleMsg: string;
begin
  for I := 0 to High(APermissions) do
  begin
    if (APermissions[I] = Access_Coarse_Location) or (APermissions[I] = Access_Fine_Location) then
      RationaleMsg := 'O app precisa de acesso ao GPS para obter sua localização'
  end;

  TDialogService.ShowMessage(RationaleMsg,
    procedure(const AResult: TModalResult)
    begin
      APostRationaleProc;
    end)
end;

procedure TForm1.LocationPermissionRequestResult
  (Sender: TObject; const APermissions: TArray<string>;
const AGrantResults: TArray<TPermissionStatus>);
var
         x : integer;
begin
  if (Length(AGrantResults) = 2) and
    (AGrantResults[0] = TPermissionStatus.Granted) and
    (AGrantResults[1] = TPermissionStatus.Granted) then
    Form1.LocationSensor.Active := true
  else
  begin
    Switch.IsChecked := false;
    TDialogService.ShowMessage
      ('Não é possível acessar o GPS porque o app não possui acesso')
  end;

end;

{$ENDIF}

procedure TForm1.OnGeocodeReverseEvent(const Address: TCivicAddress);
var
        msg : string;
begin
        msg :=  Address.AdminArea + ', ' +
                Address.CountryCode + ', ' +
                Address.CountryName + ', ' +
                Address.FeatureName + ', ' +
                Address.Locality + ', ' +
                Address.PostalCode + ', ' +
                Address.SubAdminArea + ', ' +
                Address.SubLocality + ', ' +
                Address.SubThoroughfare + ', ' +
                Address.Thoroughfare;

        TDialogService.ShowMessage(msg);
end;

procedure TForm1.LocationSensorLocationChanged(Sender: TObject;
  const OldLocation, NewLocation: TLocationCoord2D);
var
        lt, lg, url : string;
begin
        Location := NewLocation;
        lt := StringReplace(Format('%2.6f', [NewLocation.Latitude]), ',', '.', [rfReplaceAll]);
        lg := StringReplace(Format('%2.6f', [NewLocation.Longitude]), ',', '.', [rfReplaceAll]);

        LocationSensor.Active := false;
        Switch.IsChecked := false;

        url := 'https://maps.google.com/maps?q=' + lt + ',' + lg;
        WebBrowser.Navigate(url);
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
        {$IFDEF ANDROID}
        Access_Coarse_Location := JStringToString(TJManifest_permission.JavaClass.ACCESS_COARSE_LOCATION);
        Access_Fine_Location := JStringToString(TJManifest_permission.JavaClass.ACCESS_FINE_LOCATION);
        {$ENDIF}
end;



procedure TForm1.lbl_enderecoClick(Sender: TObject);
begin
        try
                // Tratando a instancia TGeocoder...
                if not Assigned(FGeocoder) then
                begin
                        if Assigned(TGeocoder.Current) then
                                FGeocoder := TGeocoder.Current.Create;

                        if Assigned(FGeocoder) then
                                FGeocoder.OnGeocodeReverse := OnGeocodeReverseEvent;
                end;

                // Tratar a traducao do endereco...
                if Assigned(FGeocoder) and not FGeocoder.Geocoding then
                        FGeocoder.GeocodeReverse(Location);
        except
                showmessage('Erro no serviço Geocoder');
        end;
end;

procedure TForm1.SwitchClick(Sender: TObject);
begin
        if Switch.IsChecked then
        begin
                {$IFDEF ANDROID}
                PermissionsService.RequestPermissions([Access_Coarse_Location,
                                                       Access_Fine_Location],
                                                       LocationPermissionRequestResult,
                                                       DisplayRationale);
                {$ENDIF}

                {$IFDEF IOS}
                LocationSensor.Active := true;
                {$ENDIF}
        end;
end;




end.