![]() |
XE5 Orientation Sensor unter Android
Hi,
ich spiele gerade mit der XE5 Delphi Demo herum. Ich würde gern den Orientation-Sensor unter Android benutzen, um die Gyroscope und Compass Daten abzurufen. Dabei nutze ich das Delphi-Beispiel unter: ![]() Führe ich die Anwendung auf meinem Smartphone aus (LG Optimus G E975, Android 4.1.2) aus, bekomme ich nur einmal Neigungswerte (Tilt), die sich nicht weiter ändern, wenn ich das Smartphone drehe und wende. Daraufhin habe ich die Beispiel-Anwendung nachgebaut und erweitert um den Status zu überprüfen. Alle nötigen Orientationsensoren (1x Compass3D und 1x Inclinometer3D) sind gestartet und auf "ready". Nun erhalte ich allerdings für die Neigungswerte immer 0 (obwohl TiltX, TiltY, TiltZ in AvailableProperties vorhanden ist). Die Heading-Werte des Kompass erhalte ich ganz normal. Hab schon etliches durchprobiert: Auslesen des Sensors in einem eigenen Thread, mit einem Timer oder eventgesteuert (OnDataChanged). Mit verschiedenen Intervallen des Auslesen von 10ms - 1sek. Hab auch alle Rechte für Android angefordert. Ich habe mir Beispiel-Apps aus dem PlayStore auf dem LG installiert, wo das Gyroscope vernünftig funktioniert. Würde also meinen, dass es nicht am Smartphone selbst liegt. Hat jemand eine Idee was die Ursache für dieses Verhalten sein könnte? Ist das ein Bug? Wird mein Smartphone von der Delphi-Bibliothek nicht sauber unterstützt? |
AW: XE5 Orientation Sensor unter Android
Das Beispiel hat ja schon einige Schwachpunkte im Bezug auf Rückmeldungen im Fehlerfall.
Ich kommentiere mal den Sourcecode:
Delphi-Quellcode:
procedure TGyroscopeForm.Form3DCreate(Sender: TObject);
begin { attempt to get and activate the sensor manager } FSensorManager := TSensorManager.Current; FSensorManager.Activate; { attempt to get an orientation sensor } FSensors := TSensorManager.Current.GetSensorsByCategory(TSensorCategory.Orientation); if Length(FSensors) = 0 then begin Label1.Text := 'Gyro not found'; // gut, aber die Meldung sollte sein: "no sensors available" Exit; { no sensors available } end; if not (FSensors[0] is TCustomOrientationSensor) then begin // schlecht - hier fehlt die Rückmeldung an den User Label1.Text := 'no orientation sensor is available'; // neu hinzu Exit; { no orientation sensor is available } end; { start the sensor if it is not started } if not TCustomOrientationSensor(FSensors[0]).Started then begin TCustomOrientationSensor(FSensors[0]).Start; // sollte der Sensor aus irgendeinem Grund schon gestartet sein // dann wird der Timer nicht gestartet // die folgende Zeile sollte daher ausserhalb der if-Anweisung verschoben werden Timer1.Enabled := True; end end; |
AW: XE5 Orientation Sensor unter Android
Zitat:
Mein Timer wird aber kontinuierlich ausgeführt, da ich mir einen Zähler ausgebe, der artig nach oben zählt. |
AW: XE5 Orientation Sensor unter Android
Liste der Anhänge anzeigen (Anzahl: 1)
Ich verstehe auch nicht, warum mir die offizielle Demo mir immerhin einmal Neigungswerte für den ersten Sensor (Compass3D) liefert, in meiner Testanwendung hingegen TiltX, TiltY und TiltZ für diesen nicht einmal definiert sind. Die Neigungswerte sind nur für den zweiten Sensor (Inclinometer3D) definiert, aber auf Null.
Ich habe mein Testprojekt mal angehangen. Die Compiler-Direktive "USEGYROSCOPETHREAD" muss deaktiviert werden, wenn man den Abfrage per Timer aktivieren möchte. Wäre super, wenn ihr mir sagen könntet, was ich falsch mache!?
Delphi-Quellcode:
unit uMain;
interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms3D, FMX.Forms, FMX.Dialogs, FMX.Sensors, FMX.Controls3D, FMX.Objects3D, System.Sensors, FMX.StdCtrls, FMX.Layers3D, FMX.MaterialSources, FMX.Layouts, FMX.Memo, FMX.ListBox {$IFDEF MSWINDOWS}, ComObj, ActiveX, System.Win.Sensors, Winapi.Sensors, Winapi.Sensorsapi {$ENDIF}; {$IFnDEF MSWINDOWS} {$DEFINE USEGYROSCOPETHREAD} {$ENDIF} const SENSOR_INTERVAL = 100; type TGyroscopeThread = class{$IFDEF USEGYROSCOPETHREAD}(TThread){$ENDIF} protected {$IFnDEF USEGYROSCOPETHREAD} fHandle : TTimer; {$ENDIF} fSensors : TSensorArray; fSensorManager : TSensorManager; fAvailable : Boolean; fIterations : Int64; fState : TSensorState; fRotation : Array[0..2] of Double; fDistance : Array[0..2] of Double; fHeading : Array[0..2] of Double; fMagHeading : Double; fTrueHeading : Double; fCompMagHeading : Double; fCompTrueHeading : Double; fMessage : String; {$IFDEF MSWINDOWS} fIntf : ISensor; {$ENDIF} procedure handleOrientationSensor(const ASensor : TCustomOrientationSensor); procedure SyncOutputMessage(); procedure SyncCamera(); procedure SynchronizeOutputMessage(const AMessage : String); procedure Execute(); {$IFDEF USEGYROSCOPETHREAD}override;{$ENDIF} {$IFnDEF USEGYROSCOPETHREAD} procedure doOnExecute(Sender : TObject); {$ENDIF} public property available : Boolean read fAvailable write fAvailable; constructor Create(); reintroduce; virtual; destructor Destroy; override; {$IFnDEF USEGYROSCOPETHREAD} procedure Start(); procedure Terminate(); {$ENDIF} end; TGyroscopeForm = class(TForm3D) LightMaterialSource1: TLightMaterialSource; Light1: TLight; Layer3D1: TLayer3D; Label1: TLabel; Cube1: TCube; Camera1: TCamera; Timer1: TTimer; Layer3D2: TLayer3D; Lbl_Iterations: TLabel; Memo1: TMemo; CkBx_Active: TCheckBox; procedure Form3DCreate(Sender: TObject); procedure Form3DDestroy(Sender: TObject); procedure CkBx_ActiveChange(Sender: TObject); private fGyroscope : TGyroscopeThread; public { Public declarations } end; var GyroscopeForm: TGyroscopeForm; implementation {$R *.fmx} function getOrientationSensorType(const ASensor : TCustomOrientationSensor) : String; begin with ASensor do case SensorType of TOrientationSensorType.Compass1D : result := 'Compass1D'; TOrientationSensorType.Compass2D : result := 'Compass2D'; TOrientationSensorType.Compass3D : result := 'Compass3D'; TOrientationSensorType.Inclinometer1D : result := 'Inclinometer1D'; TOrientationSensorType.Inclinometer2D : result := 'Inclinometer2D'; TOrientationSensorType.Inclinometer3D : result := 'Inclinometer3D'; TOrientationSensorType.Distance1D : result := 'Distance1D'; TOrientationSensorType.Distance2D : result := 'Distance2D'; TOrientationSensorType.Distance3D : result := 'Distance3D'; else result := 'Unknown'; end; end; constructor TGyroscopeThread.Create(); var lSensor : TCustomSensor; lOrientationSensor : TCustomOrientationSensor; lSensorType : String; begin inherited {$IFDEF USEGYROSCOPETHREAD}Create(true){$ENDIF}; {$IFnDEF USEGYROSCOPETHREAD} fHandle := TTimer.Create(nil); with fHandle do begin OnTimer := doOnExecute; Interval := SENSOR_INTERVAL; Enabled := false; end; {$ELSE} FreeOnTerminate := true; {$ENDIF} fIterations := 0; fSensorManager := TSensorManager.Current; fSensorManager.Activate; fSensors := TSensorManager.Current.GetSensorsByCategory(TSensorCategory.Orientation); if (System.Length(fSensors) = 0) then begin SynchronizeOutputMessage('no sensors available'); exit; end; if not (fSensors[0] is TCustomOrientationSensor) then begin SynchronizeOutputMessage('default orientation sensor not available'); exit; end; for lSensor in fSensors do begin lOrientationSensor := lSensor as TCustomOrientationSensor; with lOrientationSensor do begin if not Started then begin Start(); if not Started then raise Exception.Create('failed to start orientation sensor'); lSensorType := getOrientationSensorType(lOrientationSensor); SynchronizeOutputMessage('Sensor started: ' + Name + ' (' + Model + '::' + SerialNo + ') - ' + lSensorType); end else begin lSensorType := getOrientationSensorType(lOrientationSensor); SynchronizeOutputMessage('Sensor already started: ' + Name + ' (' + Model + '::' + SerialNo + ') - ' + lSensorType); end; end; end; fAvailable := true; end; destructor TGyroscopeThread.Destroy; var lSensor : TCustomSensor; lOrientationSensor : TCustomOrientationSensor; lSensorType : String; begin for lSensor in fSensors do begin lOrientationSensor := lSensor as TCustomOrientationSensor; with lOrientationSensor do begin Stop(); lSensorType := getOrientationSensorType(lOrientationSensor); SynchronizeOutputMessage('Sensor stopped: ' + Name + ' (' + Model + '::' + SerialNo + ') - ' + lSensorType); end; end; fSensorManager.Deactivate; inherited; end; procedure TGyroscopeThread.SyncOutputMessage(); begin if (fMessage > '') then with GyroscopeForm do begin Memo1.Lines.Insert(0, fMessage); fMessage := ''; end; end; procedure TGyroscopeThread.SyncCamera(); begin with GyroscopeForm do begin Label1.Text := Format('Rotation: %3.1f %3.1f %3.1f', [fRotation[0], fRotation[1], fRotation[2]]); with GyroscopeForm.Camera.RotationAngle do begin X := fRotation[0]; Y := fRotation[1]; Z := fRotation[2]; end; Lbl_Iterations.Text := 'Iterations: ' + IntToStr(fIterations); end; end; procedure TGyroscopeThread.SynchronizeOutputMessage(const AMessage : String); begin fMessage := AMessage; {$IFDEF USEGYROSCOPETHREAD} Synchronize(SyncOutputMessage); {$ELSE} SyncOutputMessage(); {$ENDIF} end; procedure TGyroscopeThread.handleOrientationSensor(const ASensor : TCustomOrientationSensor); var lSensorType : String; function ready() : Boolean; var lMsg : String; begin case ASensor.State of TSensorState.Added : lMsg := 'sensor - added'; TSensorState.Removed : lMsg := 'sensor - removed'; TSensorState.Initializing : lMsg := 'sensor - initializing'; TSensorState.Ready : begin result := true; exit; end; TSensorState.NoData : lMsg := 'sensor - no data'; TSensorState.AccessDenied : lMsg := 'sensor - access denied'; TSensorState.Error : lMsg := 'sensor error'; end; SynchronizeOutputMessage(lSensorType + ': ' + lMsg); result := false; end; begin inc(fIterations); with ASensor do begin lSensorType := getOrientationSensorType(ASensor); if ready() then begin if (TCustomOrientationSensor.TProperty.TiltX in AvailableProperties) then begin fRotation[0] := TiltX; fRotation[1] := TiltY; fRotation[2] := TiltZ; SynchronizeOutputMessage(lSensorType + ': ' + Format('Rotation: %3.1f %3.1f %3.1f', [TiltX, TiltY, TiltZ])); end; if (TCustomOrientationSensor.TProperty.DistanceX in AvailableProperties) then begin fDistance[0] := DistanceX; fDistance[1] := DistanceY; fDistance[2] := DistanceZ; SynchronizeOutputMessage(lSensorType + ': ' + Format('Distance: %3.1f %3.1f %3.1f', [DistanceX, DistanceY, DistanceZ])); end; if (TCustomOrientationSensor.TProperty.HeadingX in AvailableProperties) then begin fHeading[0] := HeadingX; fHeading[1] := HeadingY; fHeading[2] := HeadingZ; SynchronizeOutputMessage(lSensorType + ': ' + Format('Heading: %3.1f %3.1f %3.1f', [HeadingX, HeadingY, HeadingZ])); end; if (TCustomOrientationSensor.TProperty.MagHeading in AvailableProperties) then begin fMagHeading := MagHeading; SynchronizeOutputMessage(lSensorType + ': ' + Format('MagHeading: %3.1f', [MagHeading])); end; if (TCustomOrientationSensor.TProperty.TrueHeading in AvailableProperties) then begin fTrueHeading := TrueHeading; SynchronizeOutputMessage(lSensorType + ': ' + Format('TrueHeading: %3.1f', [TrueHeading])); end; if (TCustomOrientationSensor.TProperty.CompMagHeading in AvailableProperties) then begin fCompMagHeading := CompMagHeading; SynchronizeOutputMessage(lSensorType + ': ' + Format('CompMagHeading: %3.1f', [CompMagHeading])); end; if (TCustomOrientationSensor.TProperty.CompTrueHeading in AvailableProperties) then begin fCompTrueHeading := CompTrueHeading; SynchronizeOutputMessage(lSensorType + ': ' + Format('CompTrueHeading: %3.1f', [CompTrueHeading])); end; fState := State; end; end; end; procedure TGyroscopeThread.Execute(); var lSensor : TCustomSensor; lOrientationSensor : TCustomOrientationSensor; begin {$IFDEF USEGYROSCOPETHREAD} while not terminated do begin {$ENDIF} // iterate through all orientation sensors if fAvailable then begin for lSensor in fSensors do begin lOrientationSensor := lSensor as TCustomOrientationSensor; handleOrientationSensor(lOrientationSensor); end; {$IFDEF USEGYROSCOPETHREAD} Synchronize(SyncCamera); sleep(SENSOR_INTERVAL); end; end; {$ELSE} SyncCamera(); end; {$ENDIF} end; {$IFnDEF USEGYROSCOPETHREAD} procedure TGyroscopeThread.doOnExecute(Sender : TObject); begin execute(); end; procedure TGyroscopeThread.Start(); begin fHandle.Enabled := true; end; procedure TGyroscopeThread.Terminate(); begin fHandle.Enabled := false; end; {$ENDIF} procedure TGyroscopeForm.CkBx_ActiveChange(Sender: TObject); begin fGyroscope.available := CkBx_Active.IsChecked; end; procedure TGyroscopeForm.Form3DCreate(Sender: TObject); begin fGyroscope := TGyroscopeThread.Create(); fGyroscope.Start(); end; procedure TGyroscopeForm.Form3DDestroy(Sender: TObject); begin fGyroscope.Terminate(); {$IFnDEF USEGYROSCOPETHREAD} fGyroscope.Free(); {$ENDIF} end; end. |
AW: XE5 Orientation Sensor unter Android
Was zeigt Dir den die Demo SensorInfo an ? Das Beispiel ließt alle Sensoren aus und gibt dazu die entsprechenden Werte zurück.
|
AW: XE5 Orientation Sensor unter Android
Die Demo zeigt mir an, dass ich als Orientation Sensoren: Compass3D und Inclinometer3D habe. Für den Compass3D bekomme ich auch nur die Heading-Werte. Beim Inclinometer3D bekomme ich die Tilt-Werte die auch hier alle Null sind.
Der GravityAccelerometer3D, LinearAccelerometer3D und AmbientLight bleiben ebenfalls auf Null. Ich vermute so langsam, dass das Auslesen bestimmter Sensoren speziell für mein Smartphone nicht richtig funktioniert. |
AW: XE5 Orientation Sensor unter Android
Oder hast Du irgendwelche Dienste oder Optionen abgeschaltet, die für die Sensoren zuständig sind. Weil sage ich bei iOS, dass er meinen aktuellen Ort nicht verwenden darf, spielt meine Anzeige vom Locationsensor auch verrückt und zeigt auch keine entsprechenden Werte an. Ist nur so eine Vermutung, da ich in Android nicht so fit bin.
![]() |
AW: XE5 Orientation Sensor unter Android
Ich hab versucht alle Optionen zu aktivieren und geschaut ob irgendwelche Dienste fehlen. Selbst dann werden keine Neigungswerte ausgegeben.
Ich habe die Demo-App beim einem Freund auf dem Nexus 4 (Das offizielle Embarcadero Testgerät!) ausprobiert. Bei ihm werden ebenfalls nur Nullwerte für die Neigung ausgegeben. Hat jemand mal die Gyroscope/SensorInfo Demos unter Android ausprobiert? Denn im Moment sieht es für mich nach einem Bug im Delphi aus. |
AW: XE5 Orientation Sensor unter Android
Es hat sich anscheinend wirklich als Bug entpuppt:
![]() ![]() Andere Benutzer haben ähnliche Probleme mit den anderen Sensoren. |
AW: XE5 Orientation Sensor unter Android
Gibt es schon Lösungen zu diesem Problem? Habe das gleiche Problem.. :?:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz