Android实例-OrientationSensor方向传感器(XE8+小米2)
相关资料:
《修复 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.
作者:疯狂Delphi
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
欢迎关注我,一起进步!扫描下方二维码即可加我