8

如何在 Firemonkey 中访问 iphone 指南针?

4

1 回答 1

8

这是一个操作视频: http: //blogs.embarcadero.com/ao/2011/10/13/39171
完整源代码:http
://cc.embarcadero.com/item/28536 还有一篇(短)文章:http: //edn.embarcadero.com/article/41715

这是指南针组件的源代码。
还没有尝试过,但它应该可以工作。

unit Compass;

{Based on Anders Ohlsson Firemonkey Compass example}

{$IFDEF FPC}
{$mode objfpc}{$H+}
{$modeswitch objectivec1}
{$ENDIF}

interface

uses
  SysUtils, Classes, FMX_Types
{$IFDEF FPC}
  , iPhoneAll
{$ENDIF}
  ;

type
  TUpdateEvent = TNotifyEvent;

  TiOSGPSCompass = class(TFmxObject)
  private
    FLatitude: Double;
    FLongitude: Double;
    FAltitude: Double;
    FHeading: Double;
    FOnUpdate: TUpdateEvent;
    UpdateNeeded: Boolean;
  protected
    procedure SetLatitude(value: Double);
    procedure SetLongitude(value: Double);
    procedure SetAltitude(value: Double);
    procedure SetHeading(value: Double);
    procedure Update;
  public
    constructor Create(AOwner: Classes.TComponent); override;
    destructor Destroy; override;
  published
    property Latitude: Double read FLatitude;
    property Longitude: Double read FLongitude;
    property Altitude: Double read FAltitude;
    property Heading: Double read FHeading;
    property OnUpdate: TUpdateEvent read FOnUpdate write FOnUpdate;
  end;

var
  MyGPSCompass: TiOSGPSCompass = nil;

procedure Register;

implementation

{$IFDEF FPC}
uses
  CoreLocation;
{$ENDIF}

{$IFDEF FPC}
type
  MyCLController = objcclass(NSObject)
    locationManager : CLLocationManager;
    procedure locationManager_didUpdateToLocation_fromLocation(manager: CLLocationManager; newLocation, oldLocation: CLLocation); message 'locationManager:didUpdateToLocation:fromLocation:';
    procedure locationManager_didUpdateHeading(manager: CLLocationManager; newHeading: CLHeading); message 'locationManager:didUpdateHeading:';
  end;

var
  Controller : MyCLController;
{$ENDIF}


{$IFDEF FPC}
procedure MyCLController.locationManager_didUpdateToLocation_fromLocation(manager: CLLocationManager; newLocation, oldLocation: CLLocation);
begin
  if Assigned(MyGPSCompass) then begin
    MyGPSCompass.SetLatitude(newLocation.coordinate.latitude);
    MyGPSCompass.SetLongitude(newLocation.coordinate.longitude);
    MyGPSCompass.SetAltitude(newLocation.altitude);
    MyGPSCompass.Update;
  end;
end;
{$ENDIF}

{$IFDEF FPC}
procedure MyCLController.locationManager_didUpdateHeading(manager: CLLocationManager; newHeading: CLHeading);
begin
  if Assigned(MyGPSCompass) then begin
    MyGPSCompass.FCompassHeading:= newHeading.magneticheading;
    MyGPSCompass.Update;
  end;
end;
{$ENDIF}

constructor TiOSGPSCompass.Create(AOwner: TComponent);
begin
  inherited;
  {$IFDEF FPC}
    Controller := MyCLController.alloc.init;
  Controller.locationManager := CLLocationManager.alloc.init;
    Controller.locationManager.setDelegate(Controller);
  Controller.locationManager.setDesiredAccuracy(kCLLocationAccuracyBestForNavigation);
    Controller.locationManager.startUpdatingLocation;
  Controller.locationManager.startUpdatingHeading;
  {$ENDIF}
  MyGPSCompass:= Self;
end;

destructor TiOSGPSCompass.Destroy;
begin
  {$IFDEF FPC}
  Controller.locationManager.release;
  Controller.release;
  {$ENDIF}
  inherited;
end;

procedure TiOSGPSCompass.SetLatitude(value: Double);
begin
  if (FLatitude <> value) then begin
    FLatitude:= value;
    UpdateNeeded:= True;
  end;
end;

procedure TiOSGPSCompass.SetLongitude(value: Double);
begin
  if (FLongitude <> value) then begin
    FLongitude:= value;
    UpdateNeeded:= True;
  end;
end;

procedure TiOSGPSCompass.SetAltitude(value: Double);
begin
  if (FAltitude <> value) then begin
    FAltitude:= value;
    UpdateNeeded:= True;
  end;
end;

procedure TiOSGPSCompass.SetHeading(value: Double);
begin
  if (FHeading <> value) then begin
    FHeading:= value;
    UpdateNeeded:= True;
  end;
end;

procedure TiOSGPSCompass.Update;
begin
  if (UpdateNeeded and Assigned(OnUpdate)) then OnUpdate(Self);
  UpdateNeeded:= False;
end;

procedure Register;
begin
  RegisterComponents('iOS', [TiOSGPSCompass]);
end;

end.
于 2011-11-07T21:56:26.540 回答