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.
我有一个 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.