You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 10.3 FMX应用TLocationSensor激活时崩溃问题求助

Delphi 10.3 FMX TLocationSensor启用精确定位时崩溃问题排查

环境信息

  • Delphi版本:10.3
  • Android API版本:28
  • 测试设备:三星Galaxy A52S 5G

测试场景与现象

  • 无位置权限:应用正常运行,TLocationSensor未激活
  • 授予「始终允许」权限但关闭精确定位:应用正常运行,TLocationSensor未激活
  • 授予「始终允许」权限且启用精确定位:应用崩溃,但TLocationSensor处于激活状态

原始代码

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.Controls.Presentation,
  FMX.StdCtrls, System.Sensors, System.Sensors.Components;

type
  TForm1 = class(TForm)
    LocationSensor1: TLocationSensor;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

问题原因

  1. Delphi 10.3对Android API28的位置服务适配存在缺陷,TLocationSensor在获取精确定位时,未正确处理原生位置服务回调中的异常或空值,触发崩溃。
  2. 三星Galaxy A52S 5G的位置服务实现与标准Android存在差异,进一步放大了适配问题。
  3. API28开始对「始终允许」的位置权限要求更严格,缺少ACCESS_BACKGROUND_LOCATION权限声明可能加剧异常。

解决方案

1. 延迟激活传感器并添加异常捕获

不要在设计时设置Active := True,改为运行时先检查权限,再手动激活,同时捕获可能的异常。

2. 补充必要权限

在AndroidManifest.xml中添加ACCESS_BACKGROUND_LOCATION权限(API28及以上版本,「始终允许」权限需要此声明)。

3. 升级Delphi版本(可选)

条件允许的话,升级到Delphi 10.4及以上版本,这些版本修复了大量Android位置服务的适配问题。

修改后的示例代码

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.Controls.Presentation,
  FMX.StdCtrls, System.Sensors, System.Sensors.Components, Androidapi.Helpers, Androidapi.JNI.Os;

type
  TForm1 = class(TForm)
    LocationSensor1: TLocationSensor;
    procedure FormCreate(Sender: TObject);
    procedure LocationSensor1LocationChanged(Sender: TObject; const OldLocation, NewLocation: TLocationCoord2D);
  private
    function CheckLocationPermissions: Boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
begin
  if CheckLocationPermissions then
  begin
    try
      LocationSensor1.Active := True;
    except
      on E: Exception do
        ShowMessage('激活位置传感器失败:' + E.Message);
    end;
  end;
end;

function TForm1.CheckLocationPermissions: Boolean;
var
  FineLocPerm, BackgroundLocPerm: string;
begin
  FineLocPerm := JStringToString(TJManifest_permission.JavaClass.ACCESS_FINE_LOCATION);
  BackgroundLocPerm := JStringToString(TJManifest_permission.JavaClass.ACCESS_BACKGROUND_LOCATION);
  
  Result := (TAndroidHelper.Context.checkSelfPermission(StringToJString(FineLocPerm)) = TJPackageManager.JavaClass.PERMISSION_GRANTED)
            and (TAndroidHelper.Context.checkSelfPermission(StringToJString(BackgroundLocPerm)) = TJPackageManager.JavaClass.PERMISSION_GRANTED);
end;

procedure TForm1.LocationSensor1LocationChanged(Sender: TObject; const OldLocation, NewLocation: TLocationCoord2D);
begin
  try
    // 处理位置更新逻辑
    ShowMessage(Format('当前位置:纬度%.4f,经度%.4f', [NewLocation.Latitude, NewLocation.Longitude]));
  except
    on E: Exception do
      ShowMessage('处理位置数据失败:' + E.Message);
  end;
end;

end.

补充AndroidManifest.xml权限

在项目的AndroidManifest.xml中添加以下权限声明:

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

内容的提问来源于stack exchange,提问作者KissGe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 18:35:06