zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

Android实例-OrientationSensor方向传感器(XE8+小米2)

Android实例 小米 方向 传感器 XE8
2023-09-14 08:57:11 时间

 

相关资料:

《修复 XE8 for Android 方向传感器 headingX,Y,Z 不会动的问题》:http://www.cnblogs.com/onechen/p/4497282.html

 

结果:

1.用XE8的话,会有个问题,就是Heading的值不刷新,一直是0。不过网上有修改方法,此文章也收录了一下。在本文中搜索“Heading的值不刷新begin”可以查看修改了什么。

 

实例代码:

  1 unit Unit1;
  2 
  3 interface
  4 
  5 uses
  6   System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  7   FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Sensors,
  8   FMX.Controls.Presentation, FMX.StdCtrls, System.Sensors.Components,
  9   FMX.Layouts;
 10 
 11 type
 12   TForm1 = class(TForm)
 13     OrientationSensor1: TOrientationSensor;
 14     Label1: TLabel;
 15     Layout1: TLayout;
 16     Layout2: TLayout;
 17     Switch1: TSwitch;
 18     Label2: TLabel;
 19     Label3: TLabel;
 20     Label4: TLabel;
 21     Label5: TLabel;
 22     Label6: TLabel;
 23     Label7: TLabel;
 24     SpeedButton1: TSpeedButton;
 25     SpeedButton2: TSpeedButton;
 26     Timer1: TTimer;
 27     procedure OrientationSensor1SensorChoosing(Sender: TObject;
 28       const Sensors: TSensorArray; var ChoseSensorIndex: Integer);
 29     procedure SpeedButton1Click(Sender: TObject);
 30     procedure Timer1Timer(Sender: TObject);
 31     procedure FormActivate(Sender: TObject);
 32     procedure SpeedButton2Click(Sender: TObject);
 33     procedure Switch1Click(Sender: TObject);
 34   private
 35     { Private declarations }
 36   public
 37     { Public declarations }
 38   end;
 39 
 40 var
 41   Form1: TForm1;
 42 
 43 implementation
 44 
 45 {$R *.fmx}
 46 {$R *.NmXhdpiPh.fmx ANDROID}
 47 
 48 procedure TForm1.FormActivate(Sender: TObject);
 49 begin
 50   {$IFDEF IOS}
 51   {$IFNDEF CPUARM}
 52   lbOrientationSensor.Text := 'Simulator - no sensors';
 53   Switch1.Enabled := False;
 54   {$ENDIF}
 55   {$ENDIF}
 56 end;
 57 
 58 //Tilt与Heading的切换
 59 procedure TForm1.OrientationSensor1SensorChoosing(Sender: TObject;
 60   const Sensors: TSensorArray; var ChoseSensorIndex: Integer);
 61 var
 62   I: Integer;
 63   Found: Integer;
 64 begin
 65   Found := -1;
 66   for I := 0 to High(Sensors) do
 67   begin
 68     if SpeedButton1.IsPressed and (TCustomOrientationSensor.TProperty.TiltX in TCustomOrientationSensor(Sensors[I]).AvailableProperties) then
 69     begin
 70       Found := I;
 71       Break;
 72     end
 73     else if SpeedButton2.IsPressed and (TCustomOrientationSensor.TProperty.HeadingX in TCustomOrientationSensor(Sensors[I]).AvailableProperties) then
 74     begin
 75       Found := I;
 76       Break;
 77     end;
 78   end;
 79   if Found < 0 then
 80   begin
 81     Found := 0;
 82     SpeedButton1.IsPressed := True;
 83     SpeedButton2.IsPressed := False;
 84     ShowMessage('Compass(电子罗盘) not(不) available(可用)');
 85   end;
 86   ChoseSensorIndex := Found;
 87 end;
 88 
 89 //Tilt刷新
 90 procedure TForm1.SpeedButton1Click(Sender: TObject);
 91 begin
 92   OrientationSensor1.Active := False;
 93   SpeedButton2.IsPressed := False;
 94   SpeedButton1.IsPressed := True;
 95   OrientationSensor1.Active := Switch1.IsChecked;
 96 end;
 97 
 98 //Heading刷新
 99 procedure TForm1.SpeedButton2Click(Sender: TObject);
100 begin
101   OrientationSensor1.Active := False;
102   SpeedButton1.IsPressed := False;
103   SpeedButton2.IsPressed := True;
104   OrientationSensor1.Active := Switch1.IsChecked;
105 end;
106 
107 //显示开关
108 procedure TForm1.Switch1Click(Sender: TObject);
109 begin
110   OrientationSensor1.Active := Switch1.IsChecked;
111   Timer1.Enabled:= Switch1.IsChecked;
112 end;
113 
114 //取值方法
115 procedure TForm1.Timer1Timer(Sender: TObject);
116 begin
117   Label2.Text := Format('Tilt X: %f', [OrientationSensor1.Sensor.TiltX]);
118   Label3.Text := Format('Tilt Y: %f', [OrientationSensor1.Sensor.TiltY]);
119   Label4.Text := Format('Tilt Z: %f', [OrientationSensor1.Sensor.TiltZ]);
120   Label5.Text := Format('Heading X: %f', [OrientationSensor1.Sensor.HeadingX]);
121   Label6.Text := Format('Heading Y: %f', [OrientationSensor1.Sensor.HeadingY]);
122   Label7.Text := Format('Heading Z: %f', [OrientationSensor1.Sensor.HeadingZ]);
123 end;
124 
125 end.

 

 

自带单元(System.Android.Sensors.pas ):

   1 {*******************************************************}
   2 {                                                       }
   3 {           CodeGear Delphi Runtime Library             }
   4 { Copyright(c) 2013-2015 Embarcadero Technologies, Inc. }
   5 {                                                       }
   6 {*******************************************************}
   7 
   8 unit System.Android.Sensors;
   9 
  10 interface
  11 
  12 uses
  13   System.Sensors;
  14 
  15 type
  16   TPlatformSensorManager = class(TSensorManager)
  17   protected
  18     class function GetSensorManager: TSensorManager; override;
  19   end;
  20 
  21   TPlatformGeocoder = class(TGeocoder)
  22   protected
  23     class function GetGeocoderImplementer: TGeocoderClass; override;
  24   end;
  25 
  26   TPlatformGpsStatus = class(TGpsStatus)
  27   protected
  28     class function GetGpsStatusImplementer: TGpsStatusClass; override;
  29   end;
  30 
  31 implementation
  32 
  33 uses
  34   System.SysUtils,
  35   Androidapi.Sensor, Androidapi.AppGlue, Androidapi.Looper, System.Math, Androidapi.Jni,
  36   Androidapi.JNIBridge, Androidapi.JNI.Location, Androidapi.JNI.JavaTypes,
  37   Androidapi.JNI.Os, Androidapi.JNI.App, Androidapi.NativeActivity,
  38   Androidapi.JNI.GraphicsContentViewText, Androidapi.Helpers;
  39 
  40 { Permissions manager }
  41 type
  42   TPermission = class
  43   private
  44     class var FPermissions: TJavaObjectArray<JString>;
  45   private
  46     class constructor Create;
  47     class destructor Destroy;
  48   public
  49     class function IsPermitted(const APermission: JString):Boolean;
  50     class function GetList: TJavaObjectArray<JString>;
  51   end;
  52 
  53 { TPermission }
  54 
  55 class function TPermission.IsPermitted(const APermission: JString): Boolean;
  56 var
  57   I: integer;
  58 begin
  59   Result := False;
  60   for I := 0 to FPermissions.Length - 1 do
  61     if FPermissions[i].equalsIgnoreCase(APermission) then
  62     begin
  63       Result := True;
  64       Break;
  65     end;
  66 end;
  67 
  68 class constructor TPermission.Create;
  69 var
  70   PackageInfo: JPackageInfo;
  71   PackageManager: JPackageManager;
  72   Activity: JActivity;
  73 begin
  74   Activity := TJNativeActivity.Wrap(PANativeActivity(System.DelphiActivity)^.clazz);
  75   PackageManager := Activity.getPackageManager;
  76   PackageInfo := PackageManager.getPackageInfo(Activity.getPackageName, TJPackageManager.JavaClass.GET_PERMISSIONS);
  77   FPermissions := PackageInfo.requestedPermissions;
  78 end;
  79 
  80 class destructor TPermission.Destroy;
  81 begin
  82 
  83 end;
  84 
  85 class function TPermission.GetList: TJavaObjectArray<JString>;
  86 begin
  87   Result := FPermissions;
  88 end;
  89 
  90 type
  91   TAndroidGeocoder = class(TGeocoder)
  92   private
  93     type
  94       TGeocoderRunnable = class(TJavaLocal, JRunnable)
  95       private
  96         FCoord: TLocationCoord2D;
  97         FLGeocoder: JGeocoder;
  98       public
  99         constructor Create(ACoord: TLocationCoord2D; AGeocoder: JGeocoder);
 100         procedure run; cdecl;
 101       end;
 102   private class var
 103     FGeocoder: JGeocoder;
 104     FActivity: JActivity;
 105   private
 106     class constructor Create;
 107     class destructor Destroy;
 108   protected
 109     class function GetGeocoderImplementer: TGeocoderClass; override;
 110     class procedure GeocodeRequest(const AAddress: TCivicAddress); override;
 111     class procedure GeocodeReverseRequest(const Coords: TLocationCoord2D); override;
 112   public
 113     class function Supported: Boolean; override;
 114     class function Authorized: TAuthorizationType; override;
 115     class procedure Cancel; override;
 116   end;
 117 
 118 type
 119   TUIAndroidLocationSensor = class(TCustomLocationSensor)
 120   private
 121     FPermitted: Boolean;
 122     FActivity: JNativeActivity;
 123     FLastValue: JLocation;
 124     FLocationManager: JLocationManager;
 125     FAccuracy: TLocationAccuracy;
 126     FDistance: TLocationDistance;
 127     type
 128       TLocationListener = class(TJavaLocal, JLocationListener)
 129       private
 130         FLocationSensor: TUIAndroidLocationSensor;
 131       public
 132         constructor Create(ALocationSensor: TUIAndroidLocationSensor);
 133         procedure onLocationChanged(P1: JLocation); cdecl;
 134         procedure onStatusChanged(P1: JString; P2: Integer; P3: JBundle); cdecl;
 135         procedure onProviderEnabled(P1: JString); cdecl;
 136         procedure onProviderDisabled(P1: JString); cdecl;
 137       end;
 138 
 139       TLocationRunnable = class(TJavaLocal, JRunnable)
 140       private
 141         FLocationManager: JLocationManager;
 142         FListener: TLocationListener;
 143         FProvider: JString;
 144       public
 145         constructor Create(ALocationManager: JLocationManager; AListener: TLocationListener; AProvider: JString);
 146         procedure run; cdecl;
 147       end;
 148   private
 149     FGPSListener: TLocationListener;
 150     FGPSRunner: TLocationRunnable;
 151     FNetworkListener: TLocationListener;
 152     FNetworkRunner: TLocationRunnable;
 153     FPassiveListener: TLocationListener;
 154     FPassiveRunner: TLocationRunnable;
 155   protected
 156     function DoStart: Boolean; override;
 157     procedure DoStop; override;
 158     function GetLocationSensorType: TLocationSensorType; override;
 159     function GetAvailableProperties: TCustomLocationSensor.TProperties; override;
 160     function GetDoubleProperty(Prop: TCustomLocationSensor.TProperty): Double; override;
 161     function GetStringProperty(Prop: TCustomLocationSensor.TProperty): string; override;
 162     function GetSensorCategory: TSensorCategory; override;
 163     function GetState: TSensorState; override;
 164     function GetTimeStamp: TDateTime; override;
 165     procedure DoOptimize; override;
 166     function GetAuthorized: TAuthorizationType; override;
 167     function GetAccuracy: TLocationAccuracy; override;
 168     function GetDistance: TLocationDistance; override;
 169     function GetPowerConsumption: TPowerConsumption; override;
 170     procedure SetAccuracy(const Value: TLocationAccuracy); override;
 171     procedure SetDistance(const Value: TLocationDistance); override;
 172     procedure DoLocationChangeType; override;
 173   public
 174     constructor Create(AManager: TSensorManager); override;
 175     function Supported: Boolean;
 176   end;
 177 
 178   TNativeSensor = class
 179   strict private
 180     FSensorType: Integer;
 181     FSensorManager: PASensorManager;
 182     FNativeSensor: PASensor;
 183     FNativeEventQueue: PASensorEventQueue;
 184     FLastSensorEvent: ASensorEvent;
 185     FUpdateInterval: Double;
 186     function GetInterval: Double;
 187     procedure SetInterval(const Value: Double);
 188     class function NativeCallBack(FileDescriptor, Events: Integer; Data: Pointer): Integer; cdecl; static;
 189   public
 190     constructor Create(SensorType: Integer);
 191     function Supported: Boolean;
 192     function LastValue: ASensorEvent;
 193     property UpdateInterval: Double read GetInterval write SetInterval;
 194     function DoStart: Boolean;
 195     procedure DoStop;
 196     function TimeStamp: Double;
 197   end;
 198 {
 199   TAndroidNativeSensor = class(TCustomSensor)
 200   strict private
 201     FNativeSensor: TNativeSensor;
 202   protected
 203     function GetSensorCategory: TSensorCategory; override;
 204     function GetState: TSensorState; override;
 205     function GetTimeStamp: TDateTime; override;
 206     function GetDoubleProperty(Prop: TProperty): Double; override;
 207   public
 208     constructor Create(AManager: TSensorManager); override;
 209     function Supported: Boolean;
 210   end;
 211 }
 212 
 213   TAndroidNativeGravitySensor = class(TCustomMotionSensor)
 214   strict private
 215     FNativeSensor: TNativeSensor;
 216   protected
 217     function GetMotionSensorType: TMotionSensorType; override;
 218     function GetAvailableProperties: TCustomMotionSensor.TProperties; override;
 219     function DoStart: Boolean; override;
 220     procedure DoStop; override;
 221     function GetSensorCategory: TSensorCategory; override;
 222     function GetState: TSensorState; override;
 223     function GetTimeStamp: TDateTime; override;
 224     function GetDoubleProperty(Prop: TCustomMotionSensor.TProperty): Double; override;
 225     function GetUpdateInterval: Double;  override;
 226     procedure SetUpdateInterval(AInterval: Double); override;
 227   public
 228     constructor Create(AManager: TSensorManager); override;
 229     function Supported: Boolean;
 230   end;
 231 
 232   TAndroidNativeLinearAccelerometrSensor = class(TCustomMotionSensor)
 233   strict private
 234     FNativeSensor: TNativeSensor;
 235   protected
 236     function GetMotionSensorType: TMotionSensorType; override;
 237     function GetAvailableProperties: TCustomMotionSensor.TProperties; override;
 238     function DoStart: Boolean; override;
 239     procedure DoStop; override;
 240     function GetSensorCategory: TSensorCategory; override;
 241     function GetState: TSensorState; override;
 242     function GetTimeStamp: TDateTime; override;
 243     function GetDoubleProperty(Prop: TCustomMotionSensor.TProperty): Double; override;
 244     function GetUpdateInterval: Double;  override;
 245     procedure SetUpdateInterval(AInterval: Double); override;
 246   public
 247     constructor Create(AManager: TSensorManager); override;
 248     function Supported: Boolean;
 249   end;
 250 
 251   TAndroidNativeHumiditySensor = class(TCustomEnvironmentalSensor)
 252   strict private
 253     FNativeSensor: TNativeSensor;
 254   protected
 255     function GetSensorCategory: TSensorCategory; override;
 256     function GetState: TSensorState; override;
 257     function GetTimeStamp: TDateTime; override;
 258     function GetDoubleProperty(Prop: TCustomEnvironmentalSensor.TProperty): Double; override;
 259     function GetEnvironmentalSensorType: TEnvironmentalSensorType; override;
 260     function GetAvailableProperties: TCustomEnvironmentalSensor.TProperties; override;
 261   public
 262     constructor Create(AManager: TSensorManager); override;
 263     function Supported: Boolean;
 264   end;
 265 
 266   TAndroidNativeTemperatureSensor = class(TCustomEnvironmentalSensor)
 267   strict private
 268     FNativeSensor: TNativeSensor;
 269   protected
 270     function GetSensorCategory: TSensorCategory; override;
 271     function GetState: TSensorState; override;
 272     function GetTimeStamp: TDateTime; override;
 273     function GetDoubleProperty(Prop: TCustomEnvironmentalSensor.TProperty): Double; override;
 274     function GetEnvironmentalSensorType: TEnvironmentalSensorType; override;
 275     function GetAvailableProperties: TCustomEnvironmentalSensor.TProperties; override;
 276   public
 277     constructor Create(AManager: TSensorManager); override;
 278     function Supported: Boolean;
 279   end;
 280 
 281   TAndroidNativeProximitySensor = class(TCustomBiometricSensor)
 282   strict private
 283     FNativeSensor: TNativeSensor;
 284   protected
 285     function GetBiometricSensorType: TBiometricSensorType; override;
 286     function GetSensorCategory: TSensorCategory; override;
 287     function GetState: TSensorState; override;
 288     function GetTimeStamp: TDateTime; override;
 289     function GetAvailableProperties: TCustomBiometricSensor.TProperties; override;
 290     function GetDoubleProperty(Prop: TCustomBiometricSensor.TProperty): Double; override;
 291   public
 292     constructor Create(AManager: TSensorManager); override;
 293     function Supported: Boolean;
 294   end;
 295 
 296   TAndroidNativeMagneticSensor = class(TCustomOrientationSensor)
 297   strict private
 298     FNativeSensor: TNativeSensor;
 299   protected
 300     function GetUpdateInterval: Double;  override;
 301     procedure SetUpdateInterval(AInterval: Double); override;
 302     function GetOrientationSensorType: TOrientationSensorType; override;
 303     //Heading的值不刷新begin
 304     function DoStart: Boolean; override;
 305     procedure DoStop; override;
 306     //Heading的值不刷新end
 307     function GetSensorCategory: TSensorCategory; override;
 308     function GetState: TSensorState; override;
 309     function GetTimeStamp: TDateTime; override;
 310     function GetAvailableProperties: TCustomOrientationSensor.TProperties; override;
 311     function GetDoubleProperty(Prop: TCustomOrientationSensor.TProperty): Double; override;
 312   public
 313     constructor Create(AManager: TSensorManager); override;
 314     function Supported: Boolean;
 315   end;
 316 
 317   TAndroidNativePressureSensor = class(TCustomEnvironmentalSensor)
 318   strict private
 319     FNativeSensor: TNativeSensor;
 320   protected
 321     function GetSensorCategory: TSensorCategory; override;
 322     function GetState: TSensorState; override;
 323     function GetTimeStamp: TDateTime; override;
 324     function GetEnvironmentalSensorType: TEnvironmentalSensorType; override;
 325     function GetAvailableProperties: TCustomEnvironmentalSensor.TProperties; override;
 326     function GetDoubleProperty(Prop: TCustomEnvironmentalSensor.TProperty): Double; override;
 327   public
 328     constructor Create(AManager: TSensorManager); override;
 329     function Supported: Boolean;
 330   end;
 331 
 332   TAndroidNativeLightSensor = class(TCustomLightSensor)
 333   strict private
 334     FNativeSensor: TNativeSensor;
 335   protected
 336     function GetLightSensorType: TLightSensorType; override;
 337     function GetAvailableProperties: TCustomLightSensor.TProperties; override;
 338     function GetDoubleProperty(Prop: TCustomLightSensor.TProperty): Double; override;
 339     function GetSensorCategory: TSensorCategory; override;
 340     function GetState: TSensorState; override;
 341     function GetTimeStamp: TDateTime; override;
 342   public
 343     constructor Create(AManager: TSensorManager); override;
 344     function Supported: Boolean;
 345   end;
 346 
 347   TAndroidNativeAccelerometrSensor = class(TCustomMotionSensor)
 348   strict private
 349     FNativeSensor: TNativeSensor;
 350   protected
 351     function GetMotionSensorType: TMotionSensorType; override;
 352     function GetAvailableProperties: TCustomMotionSensor.TProperties; override;
 353     function DoStart: Boolean; override;
 354     procedure DoStop; override;
 355     function GetSensorCategory: TSensorCategory; override;
 356     function GetState: TSensorState; override;
 357     function GetTimeStamp: TDateTime; override;
 358     function GetDoubleProperty(Prop: TCustomMotionSensor.TProperty): Double; override;
 359     function GetUpdateInterval: Double;  override;
 360     procedure SetUpdateInterval(AInterval: Double); override;
 361   public
 362     constructor Create(AManager: TSensorManager); override;
 363     function Supported: Boolean;
 364   end;
 365 
 366   TAndroidNativeRotationSensor = class(TCustomOrientationSensor)
 367   private
 368     FNativeSensor: TNativeSensor;
 369   protected
 370     constructor Create(AManager: TSensorManager); override;
 371   public
 372     function Supported: Boolean;
 373     function GetOrientationSensorType: TOrientationSensorType; override;
 374     function GetAvailableProperties: TCustomOrientationSensor.TProperties;  override;
 375     function GetDoubleProperty(Prop: TCustomOrientationSensor.TProperty): Double;  override;
 376     function GetSensorCategory: TSensorCategory; override;
 377     function GetUpdateInterval: Double;  override;
 378     procedure SetUpdateInterval(AInterval: Double); override;
 379     function DoStart: Boolean; override;
 380     procedure DoStop; override;
 381     function GetState: TSensorState; override;
 382     function GetTimeStamp: TDateTime; override;
 383   end;
 384 
 385   TAndroidNativeGyroscopeSensor = class(TCustomMotionSensor)
 386   private
 387     FNativeSensor: TNativeSensor;
 388   protected
 389     constructor Create(AManager: TSensorManager); override;
 390   public
 391     function Supported: Boolean;
 392     function GetMotionSensorType: TMotionSensorType; override;
 393     function GetAvailableProperties: TCustomMotionSensor.TProperties;  override;
 394     function GetDoubleProperty(Prop: TCustomMotionSensor.TProperty): Double;  override;
 395     function GetSensorCategory: TSensorCategory; override;
 396     function GetUpdateInterval: Double;  override;
 397     procedure SetUpdateInterval(AInterval: Double); override;
 398     function DoStart: Boolean; override;
 399     procedure DoStop; override;
 400     function GetState: TSensorState; override;
 401     function GetTimeStamp: TDateTime; override;
 402   end;
 403 
 404 type
 405   TAndroidSensorManager = class(TPlatformSensorManager)
 406   private
 407     FActive: Boolean;
 408     FSensorManager: PASensorManager;
 409   protected
 410     function GetCanActivate: Boolean; override;
 411     function GetActive: Boolean; override;
 412   public
 413     constructor Create;
 414     destructor Destroy; override;
 415     procedure Activate; override;
 416     procedure Deactivate; override;
 417   end;
 418 
 419 { TAndroidSensorManager }
 420 
 421 procedure TAndroidSensorManager.Activate;
 422 var
 423   Accelerator: TAndroidNativeAccelerometrSensor;
 424   Orientation: TAndroidNativeGyroscopeSensor;
 425   Light: TAndroidNativeLightSensor;
 426   Pressure: TAndroidNativePressureSensor;
 427   MagneticField: TAndroidNativeMagneticSensor;
 428   Proximity: TAndroidNativeProximitySensor;
 429   Rotation: TAndroidNativeRotationSensor;
 430   Temperature: TAndroidNativeTemperatureSensor;
 431   Humidity: TAndroidNativeHumiditySensor;
 432   Gravity: TAndroidNativeGravitySensor;
 433   LinearAcceleration: TAndroidNativeLinearAccelerometrSensor;
 434   Location: TUIAndroidLocationSensor;
 435 begin
 436   if not Active then
 437   begin
 438     FActive := True;
 439 
 440     Accelerator := TAndroidNativeAccelerometrSensor.Create(Self);
 441     if not Accelerator.Supported then
 442       RemoveSensor(Accelerator);
 443 
 444     Orientation := TAndroidNativeGyroscopeSensor.Create(Self);
 445     if not Orientation.Supported then
 446       RemoveSensor(Orientation);
 447 
 448     Light := TAndroidNativeLightSensor.Create(Self);
 449     if not Light.Supported then
 450       RemoveSensor(Light);
 451 
 452     Pressure := TAndroidNativePressureSensor.Create(Self);
 453     if not Pressure.Supported then
 454       RemoveSensor(Pressure);
 455 
 456     MagneticField := TAndroidNativeMagneticSensor.Create(Self);
 457     if not MagneticField.Supported then
 458       RemoveSensor(MagneticField);
 459 
 460     Proximity := TAndroidNativeProximitySensor.Create(Self);
 461     if not Proximity.Supported then
 462       RemoveSensor(Proximity);
 463 
 464     Rotation := TAndroidNativeRotationSensor.Create(Self);
 465     if not Rotation.Supported then
 466       RemoveSensor(Rotation);
 467 
 468     Temperature := TAndroidNativeTemperatureSensor.Create(Self);
 469     if not Temperature.Supported then
 470       RemoveSensor(Temperature);
 471 
 472     Humidity := TAndroidNativeHumiditySensor.Create(Self);
 473     if not Humidity.Supported then
 474       RemoveSensor(Humidity);
 475 
 476     Gravity := TAndroidNativeGravitySensor.Create(Self);
 477     if not Gravity.Supported then
 478       RemoveSensor(Gravity);
 479 
 480     LinearAcceleration := TAndroidNativeLinearAccelerometrSensor.Create(Self);
 481     if not LinearAcceleration.Supported then
 482       RemoveSensor(LinearAcceleration);
 483 
 484     Location := TUIAndroidLocationSensor.Create(Self);
 485     if not Location.Supported then
 486       RemoveSensor(Location);
 487   end;
 488 end;
 489 
 490 constructor TAndroidSensorManager.Create;
 491 begin
 492   inherited;
 493   FSensorManager := ASensorManager_getInstance;
 494   FActive := False;
 495 end;
 496 
 497 procedure TAndroidSensorManager.Deactivate;
 498 var
 499   I: Integer;
 500 begin
 501   FActive := False;
 502   for I := Count - 1 downto 0 do
 503     RemoveSensor(Sensors[I]);
 504 end;
 505 
 506 destructor TAndroidSensorManager.Destroy;
 507 begin
 508   inherited;
 509 end;
 510 
 511 function TAndroidSensorManager.GetActive: Boolean;
 512 begin
 513   Result := FActive;
 514 end;
 515 
 516 function TAndroidSensorManager.GetCanActivate: Boolean;
 517 begin
 518   Result := Assigned(FSensorManager);
 519 end;
 520 
 521 { TAndroidCustomSensor }
 522 
 523 constructor TAndroidNativeAccelerometrSensor.Create(AManager: TSensorManager);
 524 begin
 525   inherited;
 526   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_ACCELEROMETER);
 527 end;
 528 
 529 
 530 function TAndroidNativeAccelerometrSensor.DoStart: Boolean;
 531 begin
 532   Result := FNativeSensor.DoStart;
 533 end;
 534 
 535 procedure TAndroidNativeAccelerometrSensor.DoStop;
 536 begin
 537   inherited;
 538   FNativeSensor.DoStop;
 539 end;
 540 
 541 function TAndroidNativeAccelerometrSensor.GetAvailableProperties: TCustomMotionSensor.TProperties;
 542 begin
 543   Result := [TCustomMotionSensor.TProperty.AccelerationX, TCustomMotionSensor.TProperty.AccelerationY,
 544     TCustomMotionSensor.TProperty.AccelerationZ]
 545 end;
 546 
 547 function TAndroidNativeAccelerometrSensor.GetDoubleProperty(
 548   Prop: TCustomMotionSensor.TProperty): Double;
 549 begin
 550   case Prop of
 551     TCustomMotionSensor.TProperty.AccelerationX: Result := -1 * FNativeSensor.LastValue.acceleration.x / ASENSOR_STANDARD_GRAVITY;
 552     TCustomMotionSensor.TProperty.AccelerationY: Result := -1 * FNativeSensor.LastValue.acceleration.y / ASENSOR_STANDARD_GRAVITY;
 553     TCustomMotionSensor.TProperty.AccelerationZ: Result := -1 * FNativeSensor.LastValue.acceleration.z / ASENSOR_STANDARD_GRAVITY;
 554   else
 555     Result := NaN;
 556   end;
 557 end;
 558 
 559 function TAndroidNativeAccelerometrSensor.GetMotionSensorType: TMotionSensorType;
 560 begin
 561   Result := TMotionSensorType.Accelerometer3D;
 562 end;
 563 
 564 function TAndroidNativeAccelerometrSensor.GetSensorCategory: TSensorCategory;
 565 begin
 566   Result := TSensorCategory.Motion;
 567 end;
 568 
 569 function TAndroidNativeAccelerometrSensor.GetState: TSensorState;
 570 begin
 571   if Supported then
 572     Result := TSensorState.Ready
 573   else
 574     Result := TSensorState.NoData;
 575 end;
 576 
 577 function TAndroidNativeAccelerometrSensor.GetTimeStamp: TDateTime;
 578 begin
 579   Result := FNativeSensor.TimeStamp;
 580 end;
 581 
 582 function TAndroidNativeAccelerometrSensor.GetUpdateInterval: Double;
 583 begin
 584   Result := FNativeSensor.UpdateInterval;
 585 end;
 586 
 587 procedure TAndroidNativeAccelerometrSensor.SetUpdateInterval(AInterval: Double);
 588 begin
 589   if Supported then
 590     FNativeSensor.UpdateInterval := AInterval;
 591 end;
 592 
 593 function TAndroidNativeAccelerometrSensor.Supported: Boolean;
 594 begin
 595   Result := FNativeSensor.Supported;
 596 end;
 597 
 598 { TPlatformSensorManager }
 599 
 600 class function TPlatformSensorManager.GetSensorManager: TSensorManager;
 601 begin
 602   Result := TAndroidSensorManager.Create;
 603 end;
 604 
 605 { TPlatformGeocoder }
 606 
 607 class function TPlatformGeocoder.GetGeocoderImplementer: TGeocoderClass;
 608 begin
 609   Result := TAndroidGeocoder;
 610 end;
 611 
 612 { TPlatformGpsStatus }
 613 
 614 class function TPlatformGpsStatus.GetGpsStatusImplementer: TGpsStatusClass;
 615 begin
 616                                                
 617   Result := nil;
 618 end;
 619 
 620 
 621 constructor TAndroidNativeGyroscopeSensor.Create(AManager: TSensorManager);
 622 begin
 623   inherited;
 624   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_GYROSCOPE);
 625 end;
 626 
 627 function TAndroidNativeGyroscopeSensor.DoStart: Boolean;
 628 begin
 629   Result := FNativeSensor.DoStart;
 630 end;
 631 
 632 procedure TAndroidNativeGyroscopeSensor.DoStop;
 633 begin
 634   inherited;
 635   FNativeSensor.DoStop;
 636 end;
 637 
 638 function TAndroidNativeGyroscopeSensor.GetAvailableProperties: TCustomMotionSensor.TProperties;
 639 begin
 640   Result := [TCustomMotionSensor.TProperty.AngleAccelX, TCustomMotionSensor.TProperty.AngleAccelY, TCustomMotionSensor.TProperty.AngleAccelZ];
 641 end;
 642 
 643 function TAndroidNativeGyroscopeSensor.GetDoubleProperty(
 644   Prop: TCustomMotionSensor.TProperty): Double;
 645 begin
 646   case Prop of
 647     TCustomMotionSensor.TProperty.AngleAccelX: Result := FNativeSensor.LastValue.vector.x;
 648     TCustomMotionSensor.TProperty.AngleAccelY: Result := FNativeSensor.LastValue.vector.y;
 649     TCustomMotionSensor.TProperty.AngleAccelZ: Result := FNativeSensor.LastValue.vector.z;
 650   else
 651     Result := NaN;
 652   end;
 653 end;
 654 
 655 function TAndroidNativeGyroscopeSensor.GetMotionSensorType: TMotionSensorType;
 656 begin
 657   Result := TMotionSensorType.Gyrometer3D;
 658 end;
 659 
 660 function TAndroidNativeGyroscopeSensor.GetSensorCategory: TSensorCategory;
 661 begin
 662   Result := TSensorCategory.Motion;
 663 end;
 664 
 665 function TAndroidNativeGyroscopeSensor.GetState: TSensorState;
 666 begin
 667   if FNativeSensor.Supported then
 668     Result := TSensorState.Ready
 669   else
 670     Result := TSensorState.NoData;
 671 end;
 672 
 673 function TAndroidNativeGyroscopeSensor.GetTimeStamp: TDateTime;
 674 begin
 675   Result := FNativeSensor.TimeStamp;
 676 end;
 677 
 678 function TAndroidNativeGyroscopeSensor.GetUpdateInterval: Double;
 679 begin
 680   Result := FNativeSensor.UpdateInterval;
 681 end;
 682 
 683 procedure TAndroidNativeGyroscopeSensor.SetUpdateInterval(AInterval: Double);
 684 begin
 685   inherited;
 686   FNativeSensor.UpdateInterval := AInterval;
 687 end;
 688 
 689 function TAndroidNativeGyroscopeSensor.Supported: Boolean;
 690 begin
 691   Result := FNativeSensor.Supported;
 692 end;
 693 
 694 { TNativeSensor }
 695 
 696 constructor TNativeSensor.Create(SensorType: Integer);
 697 begin
 698   FSensorType := SensorType;
 699   FSensorManager := ASensorManager_getInstance;
 700   FNativeSensor := ASensorManager_getDefaultSensor(FSensorManager, SensorType);
 701   FNativeEventQueue := ASensorManager_createEventQueue(FSensorManager, ALooper_forThread, LOOPER_ID_USER,
 702     nil, nil);
 703   SetInterval(1000);
 704 end;
 705 
 706 function TNativeSensor.DoStart: Boolean;
 707 begin
 708   Result := True;
 709   if Supported then
 710     ASensorEventQueue_enableSensor(FNativeEventQueue,FNativeSensor);
 711 end;
 712 
 713 procedure TNativeSensor.DoStop;
 714 begin
 715   ASensorEventQueue_disableSensor(FNativeEventQueue,FNativeSensor);
 716 end;
 717 
 718 function TNativeSensor.GetInterval: Double;
 719 begin
 720   Result := FUpdateInterval;
 721 end;
 722 
 723 function TNativeSensor.LastValue: ASensorEvent;
 724 var
 725   SensorEvent: ASensorEvent;
 726 begin
 727   while ASensorEventQueue_getEvents(FNativeEventQueue, @SensorEvent,1) > 0 do
 728       FLastSensorEvent := SensorEvent;
 729   Result := FLastSensorEvent;
 730 end;
 731 
 732 class function TNativeSensor.NativeCallBack(FileDescriptor, Events: Integer; Data: Pointer): Integer;
 733 const
 734   UnregisteredFromTheLooper = 0;
 735   ContinueReceivingCallbacks = 1;
 736 begin
 737   Result := ContinueReceivingCallbacks;
 738 end;
 739 
 740 procedure TNativeSensor.SetInterval(const Value: Double);
 741 begin
 742   if Supported then
 743   begin
 744     FUpdateInterval := Value;
 745     ASensorEventQueue_setEventRate(FNativeEventQueue,FNativeSensor,Round(FUpdateInterval));
 746   end;
 747 end;
 748 
 749 function TNativeSensor.Supported: Boolean;
 750 begin
 751   Result := Assigned(FNativeSensor) and Assigned(FNativeEventQueue);
 752 end;
 753 
 754 function TNativeSensor.TimeStamp: Double;
 755 begin
 756   Result := NaN;
 757   if Supported then
 758     Result := FLastSensorEvent.timestamp;
 759 end;
 760 
 761 { TAndroidNativeLightSensor }
 762 
 763 constructor TAndroidNativeLightSensor.Create(AManager: TSensorManager);
 764 begin
 765   inherited;
 766   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_LIGHT);
 767 end;
 768 
 769 function TAndroidNativeLightSensor.GetAvailableProperties: TCustomLightSensor.TProperties;
 770 begin
 771   Result := [TCustomLightSensor.TProperty.Lux];
 772 end;
 773 
 774 function TAndroidNativeLightSensor.GetDoubleProperty(Prop: TCustomLightSensor.TProperty): Double;
 775 begin
 776   case Prop of
 777     TCustomLightSensor.TProperty.Lux: Result := FNativeSensor.LastValue.light;
 778   else
 779     Result := NaN;
 780   end;
 781 end;
 782 
 783 function TAndroidNativeLightSensor.GetLightSensorType: TLightSensorType;
 784 begin
 785   Result := TLightSensorType.AmbientLight;
 786 end;
 787 
 788 function TAndroidNativeLightSensor.GetSensorCategory: TSensorCategory;
 789 begin
 790   Result := TSensorCategory.Light;
 791 end;
 792 
 793 function TAndroidNativeLightSensor.GetState: TSensorState;
 794 begin
 795   if FNativeSensor.Supported then
 796     Result := TSensorState.Ready
 797   else
 798     Result := TSensorState.NoData;
 799 end;
 800 
 801 function TAndroidNativeLightSensor.GetTimeStamp: TDateTime;
 802 begin
 803   Result := FNativeSensor.TimeStamp;
 804 end;
 805 
 806 function TAndroidNativeLightSensor.Supported: Boolean;
 807 begin
 808   Result := FNativeSensor.Supported;
 809 end;
 810 
 811 { TAndroidNativePressureSensor }
 812 
 813 constructor TAndroidNativePressureSensor.Create(AManager: TSensorManager);
 814 begin
 815   inherited;
 816   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_PRESSURE);
 817 end;
 818 
 819 function TAndroidNativePressureSensor.GetAvailableProperties: TCustomEnvironmentalSensor.TProperties;
 820 begin
 821   Result := [TCustomEnvironmentalSensor.TProperty.Pressure];
 822 end;
 823 
 824 function TAndroidNativePressureSensor.GetDoubleProperty(
 825   Prop: TCustomEnvironmentalSensor.TProperty): Double;
 826 begin
 827   case Prop of
 828     //  Atmospheric pressure in hPa (millibar)
 829     TCustomEnvironmentalSensor.TProperty.Pressure: Result := FNativeSensor.LastValue.pressure;
 830   else
 831     Result := NaN;
 832   end;
 833 end;
 834 
 835 function TAndroidNativePressureSensor.GetEnvironmentalSensorType: TEnvironmentalSensorType;
 836 begin
 837   Result := TEnvironmentalSensorType.AtmosphericPressure;
 838 end;
 839 
 840 function TAndroidNativePressureSensor.GetSensorCategory: TSensorCategory;
 841 begin
 842   Result := TSensorCategory.Environmental;
 843 end;
 844 
 845 function TAndroidNativePressureSensor.GetState: TSensorState;
 846 begin
 847   if Supported then
 848     Result := TSensorState.Ready
 849   else
 850     Result := TSensorState.NoData;
 851 end;
 852 
 853 function TAndroidNativePressureSensor.GetTimeStamp: TDateTime;
 854 begin
 855   Result := FNativeSensor.TimeStamp;
 856 end;
 857 
 858 function TAndroidNativePressureSensor.Supported: Boolean;
 859 begin
 860   Result := FNativeSensor.Supported;
 861 end;
 862 
 863 { TAndroidNativeMagneticSensor }
 864 
 865 constructor TAndroidNativeMagneticSensor.Create(AManager: TSensorManager);
 866 begin
 867   inherited;
 868   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_MAGNETIC_FIELD);
 869 end;
 870 
 871 //Heading的值不刷新begin
 872 function TAndroidNativeMagneticSensor.DoStart: Boolean;
 873 begin
 874   Result := FNativeSensor.DoStart;
 875 end;
 876 
 877 procedure TAndroidNativeMagneticSensor.DoStop;
 878 begin
 879   inherited;
 880   FNativeSensor.DoStop;
 881 end;
 882 //Heading的值不刷新end
 883 
 884 function TAndroidNativeMagneticSensor.GetAvailableProperties: TCustomOrientationSensor.TProperties;
 885 begin
 886   Result := [TCustomOrientationSensor.TProperty.HeadingX, TCustomOrientationSensor.TProperty.HeadingY,
 887     TCustomOrientationSensor.TProperty.HeadingZ];
 888 end;
 889 
 890 function TAndroidNativeMagneticSensor.GetDoubleProperty(
 891   Prop: TCustomOrientationSensor.TProperty): Double;
 892 begin
 893   case Prop of
 894     // All values are in micro-Tesla (uT) and measure the ambient magnetic field in the X, Y and Z axis.
 895     TCustomOrientationSensor.TProperty.HeadingX: Result := FNativeSensor.LastValue.magnetic.x;
 896     TCustomOrientationSensor.TProperty.HeadingY: Result := FNativeSensor.LastValue.magnetic.y;
 897     TCustomOrientationSensor.TProperty.HeadingZ: Result := FNativeSensor.LastValue.magnetic.z;
 898   else
 899     Result := NaN;
 900   end;
 901 end;
 902 
 903 function TAndroidNativeMagneticSensor.GetOrientationSensorType: TOrientationSensorType;
 904 begin
 905   Result := TOrientationSensorType.Compass3D;
 906 end;
 907 
 908 function TAndroidNativeMagneticSensor.GetSensorCategory: TSensorCategory;
 909 begin
 910   Result := TSensorCategory.Orientation;
 911 end;
 912 
 913 function TAndroidNativeMagneticSensor.GetState: TSensorState;
 914 begin
 915   if Supported then
 916     Result := TSensorState.Ready
 917   else
 918     Result := TSensorState.NoData;
 919 end;
 920 
 921 function TAndroidNativeMagneticSensor.GetTimeStamp: TDateTime;
 922 begin
 923   Result := FNativeSensor.TimeStamp;
 924 end;
 925 
 926 function TAndroidNativeMagneticSensor.GetUpdateInterval: Double;
 927 begin
 928   Result := FNativeSensor.UpdateInterval;
 929 end;
 930 
 931 procedure TAndroidNativeMagneticSensor.SetUpdateInterval(AInterval: Double);
 932 begin
 933   inherited;
 934   FNativeSensor.UpdateInterval := AInterval;
 935 end;
 936 
 937 function TAndroidNativeMagneticSensor.Supported: Boolean;
 938 begin
 939   Result := FNativeSensor.Supported;
 940 end;
 941 
 942 { TAndroidNativeProximitySensor }
 943 
 944 constructor TAndroidNativeProximitySensor.Create(AManager: TSensorManager);
 945 begin
 946   inherited;
 947   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_PROXIMITY);
 948 end;
 949 
 950 function TAndroidNativeProximitySensor.GetAvailableProperties: TCustomBiometricSensor.TProperties;
 951 begin
 952   Result := [TCustomBiometricSensor.TProperty.HumanProximity];
 953 end;
 954 
 955 function TAndroidNativeProximitySensor.GetBiometricSensorType: TBiometricSensorType;
 956 begin
 957   Result := TBiometricSensorType.HumanProximity;
 958 end;
 959 
 960 function TAndroidNativeProximitySensor.GetDoubleProperty(
 961   Prop: TCustomBiometricSensor.TProperty): Double;
 962 begin
 963   case Prop of
 964     // Proximity sensor distance measured in centimeters
 965     TCustomBiometricSensor.TProperty.HumanProximity:
 966     begin
 967       Result := FNativeSensor.LastValue.proximity;
 968     end;
 969   else
 970     Result := NaN;
 971   end;
 972 end;
 973 
 974 function TAndroidNativeProximitySensor.GetSensorCategory: TSensorCategory;
 975 begin
 976   Result := TSensorCategory.Biometric;
 977 end;
 978 
 979 function TAndroidNativeProximitySensor.GetState: TSensorState;
 980 begin
 981   if Supported then
 982     Result := TSensorState.Ready
 983   else
 984     Result := TSensorState.NoData;
 985 end;
 986 
 987 function TAndroidNativeProximitySensor.GetTimeStamp: TDateTime;
 988 begin
 989   Result := FNativeSensor.TimeStamp;
 990 end;
 991 
 992 function TAndroidNativeProximitySensor.Supported: Boolean;
 993 begin
 994   Result := FNativeSensor.Supported;
 995 end;
 996 
 997 { TAndroidNativeRotationSensor }
 998 
 999 constructor TAndroidNativeRotationSensor.Create(AManager: TSensorManager);
1000 begin
1001   inherited;
1002   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_ROTATION_VECTOR);
1003 end;
1004 
1005 function TAndroidNativeRotationSensor.DoStart: Boolean;
1006 begin
1007   Result := FNativeSensor.DoStart;
1008 end;
1009 
1010 procedure TAndroidNativeRotationSensor.DoStop;
1011 begin
1012   inherited;
1013   FNativeSensor.DoStop;
1014 end;
1015 
1016 function TAndroidNativeRotationSensor.GetAvailableProperties: TCustomOrientationSensor.TProperties;
1017 begin
1018   Result := [TCustomOrientationSensor.TProperty.TiltX, TCustomOrientationSensor.TProperty.TiltY, TCustomOrientationSensor.TProperty.TiltZ];
1019 end;
1020 
1021 function TAndroidNativeRotationSensor.GetDoubleProperty(Prop: TCustomOrientationSensor.TProperty): Double;
1022 var
1023   Tilts: ASensorVector;
1024 
1025   function VectorToAngles(const RotationVector: ASensorVector): ASensorVector;
1026   var
1027     RM: array[0..8] of Double;
1028     Len: Double;
1029     sqX, sqY, sqZ, qXY, qZL, qXZ, qYL, qYZ, qXL: Double;
1030   begin
1031     sqX := RotationVector.x * RotationVector.x;
1032     sqY := RotationVector.y * RotationVector.y;
1033     sqZ := RotationVector.z * RotationVector.z;
1034     Len := 1 - sqX - sqY - sqZ;
1035     if Len > 0 then
1036       Len := Sqrt(Len)
1037     else
1038       Len := 0;
1039     sqX := 2 * sqX;
1040     sqY := 2 * sqY;
1041     sqZ := 2 * sqZ;
1042     qXY := 2 * RotationVector.x * RotationVector.y;
1043     qZL := 2 * RotationVector.z * Len;
1044     qXZ := 2 * RotationVector.x * RotationVector.z;
1045     qYL := 2 * RotationVector.y * Len;
1046     qYZ := 2 * RotationVector.y * RotationVector.z;
1047     qXL := 2 * RotationVector.x * Len;
1048 
1049     RM[0] := 1 - sqY - sqZ;
1050     RM[1] := qXY - qZL;
1051     RM[2] := qXZ + qYL;
1052 
1053     RM[3] := qXY + qZL;
1054     RM[4] := 1 - sqX - sqZ;
1055     RM[5] := qYZ - qXL;
1056 
1057     RM[6] := qXZ - qYL;
1058     RM[7] := qYZ + qXL;
1059     RM[8] := 1 - sqX - sqY;
1060 
1061     Result.azimuth := RadToDeg(ArcTan2( RM[1], RM[4]));
1062     Result.pitch := RadToDeg(ArcCos( - RM[7]) - Pi / 2);
1063     Result.roll := RadToDeg(ArcTan2( - RM[6], RM[8]));
1064   end;
1065 
1066 begin
1067   Tilts := VectorToAngles(FNativeSensor.LastValue.vector);
1068   case Prop of
1069     TCustomOrientationSensor.TProperty.TiltX: Result := Tilts.roll;
1070     TCustomOrientationSensor.TProperty.TiltY: Result := Tilts.pitch;
1071     TCustomOrientationSensor.TProperty.TiltZ: Result := Tilts.azimuth;
1072   else
1073     Result := NaN;
1074   end;
1075 end;
1076 
1077 function TAndroidNativeRotationSensor.GetOrientationSensorType: TOrientationSensorType;
1078 begin
1079   Result := TOrientationSensorType.Inclinometer3D;
1080 end;
1081 
1082 function TAndroidNativeRotationSensor.GetSensorCategory: TSensorCategory;
1083 begin
1084   Result := TSensorCategory.Orientation;
1085 end;
1086 
1087 function TAndroidNativeRotationSensor.GetState: TSensorState;
1088 begin
1089   if FNativeSensor.Supported then
1090     Result := TSensorState.Ready
1091   else
1092     Result := TSensorState.NoData;
1093 end;
1094 
1095 function TAndroidNativeRotationSensor.GetTimeStamp: TDateTime;
1096 begin
1097   Result := FNativeSensor.TimeStamp;
1098 end;
1099 
1100 function TAndroidNativeRotationSensor.GetUpdateInterval: Double;
1101 begin
1102   Result := FNativeSensor.UpdateInterval;
1103 end;
1104 
1105 procedure TAndroidNativeRotationSensor.SetUpdateInterval(AInterval: Double);
1106 begin
1107   inherited;
1108   FNativeSensor.UpdateInterval := AInterval;
1109 end;
1110 
1111 function TAndroidNativeRotationSensor.Supported: Boolean;
1112 begin
1113   Result := FNativeSensor.Supported;
1114 end;
1115 
1116 { TAndroidNativeTemperatureSensor }
1117 
1118 constructor TAndroidNativeTemperatureSensor.Create(AManager: TSensorManager);
1119 begin
1120   inherited;
1121   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_AMBIENT_TEMPERATURE);
1122 end;
1123 
1124 function TAndroidNativeTemperatureSensor.GetAvailableProperties: TCustomEnvironmentalSensor.TProperties;
1125 begin
1126   Result := [TCustomEnvironmentalSensor.TProperty.Temperature];
1127 end;
1128 
1129 function TAndroidNativeTemperatureSensor.GetDoubleProperty(
1130   Prop: TCustomEnvironmentalSensor.TProperty): Double;
1131 begin
1132   case Prop of
1133     // ambient (room) temperature in degree Celsius
1134     TCustomEnvironmentalSensor.TProperty.Temperature: Result := FNativeSensor.LastValue.temperature;
1135   else
1136     Result := NaN;
1137   end;
1138 end;
1139 
1140 function TAndroidNativeTemperatureSensor.GetEnvironmentalSensorType: TEnvironmentalSensorType;
1141 begin
1142   Result := TEnvironmentalSensorType.Temperature;
1143 end;
1144 
1145 function TAndroidNativeTemperatureSensor.GetSensorCategory: TSensorCategory;
1146 begin
1147   Result := TSensorCategory.Environmental;
1148 end;
1149 
1150 function TAndroidNativeTemperatureSensor.GetState: TSensorState;
1151 begin
1152   if Supported then
1153     Result := TSensorState.Ready
1154   else
1155     Result := TSensorState.NoData;
1156 end;
1157 
1158 function TAndroidNativeTemperatureSensor.GetTimeStamp: TDateTime;
1159 begin
1160   Result := FNativeSensor.TimeStamp;
1161 end;
1162 
1163 function TAndroidNativeTemperatureSensor.Supported: Boolean;
1164 begin
1165   Result := FNativeSensor.Supported;
1166 end;
1167 
1168 { TAndroidNativeSensor }
1169 
1170 constructor TAndroidNativeHumiditySensor.Create(AManager: TSensorManager);
1171 begin
1172   inherited;
1173   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_RELATIVE_HUMIDITY);
1174 end;
1175 
1176 function TAndroidNativeHumiditySensor.GetAvailableProperties: TCustomEnvironmentalSensor.TProperties;
1177 begin
1178   Result := [TCustomEnvironmentalSensor.TProperty.Humidity];
1179 end;
1180 
1181 function TAndroidNativeHumiditySensor.GetDoubleProperty(
1182   Prop: TCustomEnvironmentalSensor.TProperty): Double;
1183 begin
1184   case Prop of
1185     // Relative ambient air humidity in percent
1186     TCustomEnvironmentalSensor.TProperty.Humidity: Result := FNativeSensor.LastValue.vector.v[0];
1187   else
1188     Result := NaN;
1189   end;
1190 end;
1191 
1192 function TAndroidNativeHumiditySensor.GetEnvironmentalSensorType: TEnvironmentalSensorType;
1193 begin
1194   Result := TEnvironmentalSensorType.Humidity;
1195 end;
1196 
1197 function TAndroidNativeHumiditySensor.GetSensorCategory: TSensorCategory;
1198 begin
1199   Result := TSensorCategory.Environmental;
1200 end;
1201 
1202 function TAndroidNativeHumiditySensor.GetState: TSensorState;
1203 begin
1204   if Supported then
1205     Result := TSensorState.Ready
1206   else
1207     Result := TSensorState.NoData;
1208 end;
1209 
1210 function TAndroidNativeHumiditySensor.GetTimeStamp: TDateTime;
1211 begin
1212   Result := FNativeSensor.TimeStamp;
1213 end;
1214 
1215 function TAndroidNativeHumiditySensor.Supported: Boolean;
1216 begin
1217   Result := FNativeSensor.Supported;
1218 end;
1219 
1220 { TAndroidNativeGravitySensor }
1221 
1222 constructor TAndroidNativeGravitySensor.Create(AManager: TSensorManager);
1223 begin
1224   inherited;
1225   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_GRAVITY);
1226 end;
1227 
1228 function TAndroidNativeGravitySensor.DoStart: Boolean;
1229 begin
1230   Result := FNativeSensor.DoStart;
1231 end;
1232 
1233 procedure TAndroidNativeGravitySensor.DoStop;
1234 begin
1235   inherited;
1236   FNativeSensor.DoStop;
1237 end;
1238 
1239 function TAndroidNativeGravitySensor.GetAvailableProperties: TCustomMotionSensor.TProperties;
1240 begin
1241   Result := [TCustomMotionSensor.TProperty.AccelerationX, TCustomMotionSensor.TProperty.AccelerationY,
1242     TCustomMotionSensor.TProperty.AccelerationZ]
1243 end;
1244 
1245 function TAndroidNativeGravitySensor.GetDoubleProperty(
1246   Prop: TCustomMotionSensor.TProperty): Double;
1247 begin
1248   case Prop of
1249     TCustomMotionSensor.TProperty.AccelerationX: Result := -1 * FNativeSensor.LastValue.acceleration.x / ASENSOR_STANDARD_GRAVITY;
1250     TCustomMotionSensor.TProperty.AccelerationY: Result := -1 * FNativeSensor.LastValue.acceleration.y / ASENSOR_STANDARD_GRAVITY;
1251     TCustomMotionSensor.TProperty.AccelerationZ: Result := -1 * FNativeSensor.LastValue.acceleration.z / ASENSOR_STANDARD_GRAVITY;
1252   else
1253     Result := NaN;
1254   end;
1255 end;
1256 
1257 function TAndroidNativeGravitySensor.GetMotionSensorType: TMotionSensorType;
1258 begin
1259   Result := TMotionSensorType.GravityAccelerometer3D;
1260 end;
1261 
1262 function TAndroidNativeGravitySensor.GetSensorCategory: TSensorCategory;
1263 begin
1264   Result := TSensorCategory.Motion;
1265 end;
1266 
1267 function TAndroidNativeGravitySensor.GetState: TSensorState;
1268 begin
1269   if Supported then
1270     Result := TSensorState.Ready
1271   else
1272     Result := TSensorState.NoData;
1273 end;
1274 
1275 function TAndroidNativeGravitySensor.GetTimeStamp: TDateTime;
1276 begin
1277   Result := FNativeSensor.TimeStamp;
1278 end;
1279 
1280 function TAndroidNativeGravitySensor.GetUpdateInterval: Double;
1281 begin
1282   Result := FNativeSensor.UpdateInterval;
1283 end;
1284 
1285 procedure TAndroidNativeGravitySensor.SetUpdateInterval(AInterval: Double);
1286 begin
1287   inherited;
1288   FNativeSensor.UpdateInterval := AInterval;
1289 end;
1290 
1291 function TAndroidNativeGravitySensor.Supported: Boolean;
1292 begin
1293   Result := FNativeSensor.Supported;
1294 end;
1295 
1296 { TAndroidNativeLinearAccelerometrSensor }
1297 
1298 constructor TAndroidNativeLinearAccelerometrSensor.Create(
1299   AManager: TSensorManager);
1300 begin
1301   inherited;
1302   FNativeSensor := TNativeSensor.Create(ASENSOR_TYPE_LINEAR_ACCELERATION);
1303 end;
1304 
1305 function TAndroidNativeLinearAccelerometrSensor.DoStart: Boolean;
1306 begin
1307   Result := FNativeSensor.DoStart;
1308 end;
1309 
1310 procedure TAndroidNativeLinearAccelerometrSensor.DoStop;
1311 begin
1312   inherited;
1313   DoStop;
1314 end;
1315 
1316 function TAndroidNativeLinearAccelerometrSensor.GetAvailableProperties: TCustomMotionSensor.TProperties;
1317 begin
1318   Result := [TCustomMotionSensor.TProperty.AccelerationX, TCustomMotionSensor.TProperty.AccelerationY,
1319     TCustomMotionSensor.TProperty.AccelerationZ]
1320 end;
1321 
1322 function TAndroidNativeLinearAccelerometrSensor.GetDoubleProperty(
1323   Prop: TCustomMotionSensor.TProperty): Double;
1324 begin
1325   case Prop of
1326     TCustomMotionSensor.TProperty.AccelerationX: Result := -1 * FNativeSensor.LastValue.acceleration.x / ASENSOR_STANDARD_GRAVITY;
1327     TCustomMotionSensor.TProperty.AccelerationY: Result := -1 * FNativeSensor.LastValue.acceleration.y / ASENSOR_STANDARD_GRAVITY;
1328     TCustomMotionSensor.TProperty.AccelerationZ: Result := -1 * FNativeSensor.LastValue.acceleration.z / ASENSOR_STANDARD_GRAVITY;
1329   else
1330     Result := NaN;
1331   end;
1332 end;
1333 
1334 function TAndroidNativeLinearAccelerometrSensor.GetMotionSensorType: TMotionSensorType;
1335 begin
1336   Result := TMotionSensorType.LinearAccelerometer3D;
1337 end;
1338 
1339 function TAndroidNativeLinearAccelerometrSensor.GetSensorCategory: TSensorCategory;
1340 begin
1341   Result := TSensorCategory.Motion;
1342 end;
1343 
1344 function TAndroidNativeLinearAccelerometrSensor.GetState: TSensorState;
1345 begin
1346   if Supported then
1347     Result := TSensorState.Ready
1348   else
1349     Result := TSensorState.NoData;
1350 end;
1351 
1352 function TAndroidNativeLinearAccelerometrSensor.GetTimeStamp: TDateTime;
1353 begin
1354   Result := FNativeSensor.TimeStamp;
1355 end;
1356 
1357 function TAndroidNativeLinearAccelerometrSensor.GetUpdateInterval: Double;
1358 begin
1359   Result := FNativeSensor.UpdateInterval;
1360 end;
1361 
1362 procedure TAndroidNativeLinearAccelerometrSensor.SetUpdateInterval(
1363   AInterval: Double);
1364 begin
1365   inherited;
1366   FNativeSensor.UpdateInterval := AInterval;
1367 end;
1368 
1369 function TAndroidNativeLinearAccelerometrSensor.Supported: Boolean;
1370 begin
1371   Result := FNativeSensor.Supported;
1372 end;
1373 
1374 { TUIAndroidLocationSensor.TLocationListener }
1375 
1376 constructor TUIAndroidLocationSensor.TLocationListener.Create(ALocationSensor: TUIAndroidLocationSensor);
1377 begin
1378   inherited Create;
1379   FLocationSensor := ALocationSensor;
1380 end;
1381 
1382 procedure TUIAndroidLocationSensor.TLocationListener.onLocationChanged(P1: JLocation);
1383 var
1384   OldLocation, CurrentLocation: TLocationCoord2D;
1385   Heading: THeading;
1386 
1387 begin
1388   if Assigned(FLocationSensor.FLastValue) then
1389     OldLocation.Create(FLocationSensor.FLastValue.getLatitude,
1390       FLocationSensor.FLastValue.getLongitude)
1391   else
1392     OldLocation.Create(NaN,NaN);
1393   CurrentLocation.Create(P1.getLatitude, P1.getLongitude);
1394   FLocationSensor.FLastValue := P1;
1395   FLocationSensor.DoLocationChanged(OldLocation, CurrentLocation);
1396   if p1.hasBearing then
1397   begin
1398     Heading.Azimuth := P1.getBearing;
1399     FLocationSensor.DoHeadingChanged(Heading);
1400   end;
1401 end;
1402 
1403 procedure TUIAndroidLocationSensor.TLocationListener.onProviderDisabled(
1404   P1: JString);
1405 begin
1406 ;
1407 end;
1408 
1409 procedure TUIAndroidLocationSensor.TLocationListener.onProviderEnabled(
1410   P1: JString);
1411 begin
1412 ;
1413 end;
1414 
1415 procedure TUIAndroidLocationSensor.TLocationListener.onStatusChanged(
1416   P1: JString; P2: Integer; P3: JBundle);
1417 begin
1418 ;
1419 end;
1420 
1421 { TUIAndroidLocationSensor.TLocationRunnable }
1422 
1423 constructor TUIAndroidLocationSensor.TLocationRunnable.Create(ALocationManager: JLocationManager; AListener:
1424   TLocationListener; AProvider: JString);
1425 begin
1426   Inherited Create;
1427   FLocationManager := ALocationManager;
1428   FListener := AListener;
1429   FProvider := AProvider;
1430 end;
1431 
1432 procedure TUIAndroidLocationSensor.TLocationRunnable.run;
1433 const
1434   cMinTime = 100;
1435   cMinDistance = 10;
1436 begin
1437   FLocationManager.requestLocationUpdates( FProvider, cMinTime, cMinDistance, FListener);
1438 end;
1439 
1440 { TUIAndroidLocationSensor }
1441 
1442 constructor TUIAndroidLocationSensor.Create(AManager: TSensorManager);
1443 var
1444   LocationService: JObject;
1445 begin
1446   inherited;
1447   FActivity := TJNativeActivity.Wrap(PANativeActivity(System.DelphiActivity)^.clazz);
1448   LocationService := FActivity.getSystemService(TJContext.JavaClass.LOCATION_SERVICE);
1449   if Assigned(LocationService) then
1450     FLocationManager := TJLocationManager.Wrap((LocationService as ILocalObject).GetObjectID);
1451 end;
1452 
1453 procedure TUIAndroidLocationSensor.DoLocationChangeType;
1454 begin
1455   inherited;
1456 end;
1457 
1458 procedure TUIAndroidLocationSensor.DoOptimize;
1459 begin
1460 
1461 end;
1462 
1463 function TUIAndroidLocationSensor.DoStart: Boolean;
1464 
1465   function RunIfPossible(var ARunnable: TLocationRunnable; var AListener: TLocationListener; AProviderName: JString):
1466     Boolean;
1467   var
1468     Provider: JLocationProvider;
1469   begin
1470     Result := False;
1471     if FLocationManager.isProviderEnabled(AProviderName) then
1472     begin
1473       if AListener = nil then
1474         AListener := TLocationListener.Create(Self);
1475       Provider := FLocationManager.getProvider(AProviderName);
1476       if Provider <> nil then
1477       begin
1478         ARunnable := TLocationRunnable.Create(FLocationManager, AListener, AProviderName);
1479         FActivity.runOnUiThread(ARunnable);
1480         Result := True;
1481       end;
1482     end;
1483   end;
1484 
1485   function RunTheBestProvider(var ARunnable: TLocationRunnable; var AListener: TLocationListener):Boolean;
1486   var
1487     Criteria: JCriteria;
1488     ProviderName: JString;
1489   begin
1490     Result := False;
1491     Criteria := TJCriteria.JavaClass.init;
1492     case Round(FAccuracy) of
1493       0..100:
1494         Criteria.setHorizontalAccuracy(TJCriteria.JavaClass.ACCURACY_HIGH);
1495       101..500:
1496         Criteria.setHorizontalAccuracy(TJCriteria.JavaClass.ACCURACY_MEDIUM);
1497     else
1498       Criteria.setHorizontalAccuracy(TJCriteria.JavaClass.ACCURACY_LOW);
1499     end;
1500 
1501     ProviderName := FLocationManager.getBestProvider(Criteria, True);
1502 
1503     if ProviderName <> nil then
1504       Result := RunIfPossible(ARunnable, AListener, ProviderName);
1505   end;
1506 
1507 var
1508   GPSStarted, NetworkStarted, PassiveStarted: Boolean;
1509 
1510 begin
1511   Result := False;
1512   FPermitted := TPermission.IsPermitted(StringToJString('android.permission.ACCESS_FINE_LOCATION'));
1513   if FPermitted then
1514   begin
1515     if FAccuracy > 0 then
1516       Result := RunTheBestProvider(FPassiveRunner, FPassiveListener)
1517     else
1518     begin
1519       GPSStarted := RunIfPossible(FGPSRunner, FGPSListener, TJLocationManager.JavaClass.GPS_PROVIDER);
1520       NetworkStarted := RunIfPossible(FNetworkRunner, FNetworkListener, TJLocationManager.JavaClass.NETWORK_PROVIDER);
1521       PassiveStarted := RunIfPossible(FPassiveRunner, FPassiveListener, TJLocationManager.JavaClass.PASSIVE_PROVIDER);
1522       Result := GPSStarted or NetworkStarted or PassiveStarted;
1523     end;
1524   end;
1525 end;
1526 
1527 procedure TUIAndroidLocationSensor.DoStop;
1528 begin
1529   inherited;
1530   if FPassiveListener <> nil then
1531     FLocationManager.removeUpdates(FPassiveListener);
1532   if FNetworkListener <> nil then
1533     FLocationManager.removeUpdates(FNetworkListener);
1534   if FGPSListener <> nil then
1535     FLocationManager.removeUpdates(FGPSListener);
1536 end;
1537 
1538 function TUIAndroidLocationSensor.GetAccuracy: TLocationAccuracy;
1539 begin
1540   Result := FAccuracy;
1541 end;
1542 
1543 function TUIAndroidLocationSensor.GetAuthorized: TAuthorizationType;
1544 begin
1545   Result := TAuthorizationType.atNotSpecified;
1546 end;
1547 
1548 function TUIAndroidLocationSensor.GetAvailableProperties: TCustomLocationSensor.TProperties;
1549 begin
1550   Result := [TCustomLocationSensor.TProperty.Latitude,
1551     TCustomLocationSensor.TProperty.Longitude, TCustomLocationSensor.TProperty.Altitude,
1552     TCustomLocationSensor.TProperty.Speed, TCustomLocationSensor.TProperty.TrueHeading];
1553 
1554 end;
1555 
1556 function TUIAndroidLocationSensor.GetDistance: TLocationDistance;
1557 begin
1558   Result := FDistance;
1559 end;
1560 
1561 function TUIAndroidLocationSensor.GetDoubleProperty(Prop: TCustomLocationSensor.TProperty): Double;
1562 begin
1563   Result := NaN;
1564   if Assigned(FLastValue) then
1565     case Prop of
1566       TCustomLocationSensor.TProperty.Latitude: Result := FLastValue.getLatitude;
1567       TCustomLocationSensor.TProperty.Longitude: Result := FLastValue.getLongitude ;
1568       TCustomLocationSensor.TProperty.Altitude:
1569         if FLastValue.hasAltitude then
1570           Result := FLastValue.getAltitude;
1571       TCustomLocationSensor.TProperty.Speed:
1572         if FLastValue.hasSpeed then
1573           Result := FLastValue.getSpeed;
1574       TCustomLocationSensor.TProperty.TrueHeading:
1575         if FLastValue.hasBearing then
1576           Result := FLastValue.getBearing;
1577     else
1578       Result := NaN;
1579     end;
1580 end;
1581 
1582 function TUIAndroidLocationSensor.GetLocationSensorType: TLocationSensorType;
1583 begin
1584   Result := TLocationSensorType.GPS;
1585 end;
1586 
1587 function TUIAndroidLocationSensor.GetPowerConsumption: TPowerConsumption;
1588 begin
1589   Result := TPowerConsumption.pcNotSpecified;
1590 end;
1591 
1592 function TUIAndroidLocationSensor.GetSensorCategory: TSensorCategory;
1593 begin
1594   Result := TSensorCategory.Location;
1595 end;
1596 
1597 function TUIAndroidLocationSensor.GetState: TSensorState;
1598 begin
1599   if Supported then
1600     Result := TSensorState.Ready
1601   else
1602     Result := TSensorState.NoData;
1603 end;
1604 
1605 function TUIAndroidLocationSensor.GetStringProperty(Prop: TCustomLocationSensor.TProperty): string;
1606 begin
1607   Result := '';
1608 end;
1609 
1610 function TUIAndroidLocationSensor.GetTimeStamp: TDateTime;
1611 begin
1612   if Assigned(FLastValue) then
1613     Result := FLastValue.getTime
1614   else
1615     Result := 0;
1616 end;
1617 
1618 procedure TUIAndroidLocationSensor.SetAccuracy(const Value: TLocationAccuracy);
1619 begin
1620   inherited;
1621   FAccuracy := Max(0, Value);
1622 end;
1623 
1624 procedure TUIAndroidLocationSensor.SetDistance(const Value: TLocationDistance);
1625 begin
1626   inherited;
1627   FDistance := Value;
1628 end;
1629 
1630 function TUIAndroidLocationSensor.Supported: Boolean;
1631 begin
1632   Result := Assigned(FLocationManager);
1633 end;
1634 
1635 { TAndroidGeocoder }
1636 
1637 class function TAndroidGeocoder.Authorized: TAuthorizationType;
1638 begin
1639   Result := TAuthorizationType.atNotSpecified;
1640 end;
1641 
1642 class procedure TAndroidGeocoder.Cancel;
1643 begin
1644 ;
1645 end;
1646 
1647 class constructor TAndroidGeocoder.Create;
1648 begin
1649   FActivity := TJNativeActivity.Wrap(PANativeActivity(System.DelphiActivity)^.clazz);
1650   FGeocoder := TJGeocoder.JavaClass.init(FActivity);
1651 end;
1652 
1653 class destructor TAndroidGeocoder.Destroy;
1654 begin
1655 
1656 end;
1657 
1658 class procedure TAndroidGeocoder.GeocodeRequest(const AAddress: TCivicAddress);
1659 var
1660   I: Integer;
1661   List: JList;
1662   LAddress: JAddress;
1663   JO: JObject;
1664 begin
1665   List := FGeocoder.getFromLocationName(StringToJString(AAddress.ToString),10);
1666   SetLength(FGeoFwdCoords, List.size);
1667   for I := 0 to List.size - 1 do
1668   begin
1669     JO := List.get(I);
1670     LAddress := TJAddress.Wrap((JO as ILocalObject).GetObjectID);
1671     FGeoFwdCoords[I] := TLocationCoord2D.Create(LAddress.getLatitude,LAddress.getLongitude);
1672   end;
1673   DoGeocode(FGeoFwdCoords);
1674 end;
1675 
1676 class procedure TAndroidGeocoder.GeocodeReverseRequest(const Coords: TLocationCoord2D);
1677 var
1678   List: JList;
1679   LAddress: JAddress;
1680   Addr: TCivicAddress;
1681   FLActivity: JActivity;
1682   JO: JObject;
1683   I: Integer;
1684 begin
1685   FLActivity := TJNativeActivity.Wrap(PANativeActivity(System.DelphiActivity)^.clazz);
1686   List := FGeocoder.getFromLocation(Coords.Latitude,Coords.Longitude,1);
1687   if List.size = 0 then
1688     Addr := nil
1689   else
1690   begin
1691     for I := 0 to List.size - 1 do
1692     begin
1693       JO := List.get(I);
1694       LAddress := TJAddress.Wrap((JO as ILocalObject).GetObjectID);
1695       Addr := FGeoRevAddress;
1696       Addr.AdminArea       := JStringToString(LAddress.getAdminArea);
1697       Addr.CountryName     := JStringToString(LAddress.getCountryName);
1698       Addr.CountryCode     := JStringToString(LAddress.getCountryCode);
1699       Addr.Locality        := JStringToString(LAddress.getLocality);
1700       Addr.FeatureName     := JStringToString(LAddress.getFeatureName);
1701       Addr.PostalCode      := JStringToString(LAddress.getPostalCode);
1702       Addr.SubAdminArea    := JStringToString(LAddress.getAdminArea);
1703       Addr.SubLocality     := JStringToString(LAddress.getSubLocality);
1704       Addr.SubThoroughfare := JStringToString(LAddress.getSubThoroughfare);
1705       Addr.Thoroughfare    := JStringToString(LAddress.getThoroughfare);
1706     end;
1707   end;
1708   DoGeocodeReverse(Addr);
1709 end;
1710 
1711 class function TAndroidGeocoder.GetGeocoderImplementer: TGeocoderClass;
1712 begin
1713   Result := Self;
1714 end;
1715 
1716 class function TAndroidGeocoder.Supported: Boolean;
1717 begin
1718   Result := False;
1719   if Assigned(FGeocoder) then
1720     Result := TjGeocoder.JavaClass.isPresent;
1721 end;
1722 
1723 { TAndroidGeocoder.TGeocoderRunnable }
1724 
1725 constructor TAndroidGeocoder.TGeocoderRunnable.Create(ACoord: TLocationCoord2D; AGeocoder: JGeocoder);
1726 begin
1727   inherited Create;
1728   FCoord := ACoord;
1729   FLGeocoder := AGeocoder;
1730 end;
1731 
1732 procedure TAndroidGeocoder.TGeocoderRunnable.run;
1733 var
1734   List: JList;
1735   Address: JAddress;
1736   Addr: TCivicAddress;
1737   Activity: JActivity;
1738   JO: JObject;
1739   I: Integer;
1740 begin
1741   Activity := TJNativeActivity.Wrap(PANativeActivity(System.DelphiActivity)^.clazz);
1742   FLGeocoder := TJGeocoder.JavaClass.init(Activity);
1743   List := FLGeocoder.getFromLocation(FCoord.Latitude,FCoord.Longitude,10);
1744   if List.size = 0 then
1745     Addr := nil
1746   else
1747   begin
1748     for I := 0 to List.size - 1 do
1749     begin
1750       JO := List.get(I);
1751       Address := TJAddress.Wrap((JO as ILocalObject).GetObjectID);
1752       Addr := FGeoRevAddress;
1753       Addr.AdminArea       := JStringToString(Address.getAdminArea);
1754       Addr.CountryName     := JStringToString(Address.getCountryName);
1755       Addr.CountryCode     := JStringToString(Address.getCountryCode);
1756       Addr.Locality        := JStringToString(Address.getLocality);
1757       Addr.FeatureName     := JStringToString(Address.getFeatureName);
1758       Addr.PostalCode      := JStringToString(Address.getPostalCode);
1759       Addr.SubAdminArea    := JStringToString(Address.getAdminArea);
1760       Addr.SubLocality     := JStringToString(Address.getSubLocality);
1761       Addr.SubThoroughfare := JStringToString(Address.getSubThoroughfare);
1762       Addr.Thoroughfare    := JStringToString(Address.getThoroughfare);
1763     end;
1764   end;
1765   DoGeocodeReverse(Addr);
1766 end;
1767 
1768 initialization
1769 
1770 end.