2015-04-21 30 views
7

我想列出Android備忘錄中所有可用的原始傳感器數據。列出備忘錄中的原始傳感器數據

以下代碼在過去幾年工作過,但它不適用於XE8。可能有一個內部編譯器錯誤。有什麼我可以做的,使其再次工作,或者有其他解決方案嗎?

uses 
    TypInfo; 

type 
    TOrientationSensorAccessor = class(TCustomOrientationSensor); 
    TLocationSensorAccessor = class(TCustomLocationSensor); 

procedure TForm2.Button1Click(Sender: TObject); 
var 
    p_location: TCustomLocationSensor.TProperty; 
    p_orientation: TCustomOrientationSensor.TProperty; 
    n, v: string; 
begin 
    Memo1.Lines.Clear; 

    if Assigned(OrientationSensor1.Sensor) then 
    begin 
    if not OrientationSensor1.Sensor.Started then OrientationSensor1.Sensor.Start; 

    // Error (only in XE8): Incompatible types 'TCustomLocationSensor.TProperty' and 'TCustomOrientationSensor.TProperty' 
    // In XE7 it works. 
    for p_orientation in OrientationSensor1.Sensor.AvailableProperties do 
    begin 
     n := 'OrientationSensor.'+GetEnumName(TypeInfo(TCustomOrientationSensor.TProperty), integer(p_orientation)) ; 
     v := FloatToStr(TOrientationSensorAccessor(OrientationSensor1.Sensor).GetDoubleProperty(p_orientation)); 
     Memo1.Lines.Values[n] := v; 
    end; 
    end; 

    if Assigned(LocationSensor1.Sensor) then 
    begin 
    if not LocationSensor1.Sensor.Started then LocationSensor1.Sensor.Start; 
    for p_location in LocationSensor1.Sensor.AvailableProperties do 
    begin 
     n := 'LocationSensor.'+GetEnumName(TypeInfo(TCustomLocationSensor.TProperty), integer(p_location)) ; 
     v := FloatToStr(TLocationSensorAccessor(LocationSensor1.Sensor).GetDoubleProperty(p_location)); 
     Memo1.Lines.Values[n] := v; 
    end; 
    end; 
end; 

更新

一些實驗:

(1)當我註釋掉第一 「爲」,它會編譯:

// for p_orientation in OrientationSensor1.Sensor.AvailableProperties do 
// begin 
     n := 'OrientationSensor.'+GetEnumName(TypeInfo(TCustomOrientationSensor.TProperty), integer(p_orientation)) ; 
     v := FloatToStr(TOrientationSensorAccessor(OrientationSensor1.Sensor).GetDoubleProperty(p_orientation)); 
     Memo1.Lines.Values[n] := v; 
// end; 
    end; 

(2 )當我註釋掉「n」和「v」的賦值時,它也會編譯:

for p_orientation in OrientationSensor1.Sensor.AvailableProperties do 
    begin 
//  n := 'OrientationSensor.'+GetEnumName(TypeInfo(TCustomOrientationSensor.TProperty), integer(p_orientation)) ; 
//  v := FloatToStr(TOrientationSensorAccessor(OrientationSensor1.Sensor).GetDoubleProperty(p_orientation)); 
//  Memo1.Lines.Values[n] := v; 
    end; 
    end; 

既然「for」,也不是「n」和「v」是壞區,那麼錯誤在哪裏呢?

(3)當我註釋掉第二個for循環時,它會再次編譯。如果我註釋掉第一個for循環,它也會編譯。每個for-loop工作,但組合他們將無法工作。

它看起來像如果5個因素組合的誤差僅發生:

  • TypInfo
  • 訪問者
  • for循環
  • TypInfo的用法(GetEnumName)
  • 兩個for循環被使用。

更新2

這裏是最小的可重複的代碼,我可以找到。如果任何行被註釋掉,它會編譯:

program ProjectCompilerBug; 

{$APPTYPE CONSOLE} 

uses 
    System.Sensors, System.Sensors.Components; 

var 
    p_location: TCustomLocationSensor.TProperty; 
    p_orientation: TCustomOrientationSensor.TProperty; 
begin 
    // Compilation Error (only in XE8): 
    // "Incompatible types 'TCustomLocationSensor.TProperty' and 'TCustomOrientationSensor.TProperty'" 
    // In XE7 it compiles 
    for p_orientation in TOrientationSensor.Create(nil).Sensor.AvailableProperties do 
    begin 
    FloatToStr(1.23); 
    end; 

    for p_location in TLocationSensor.Create(nil).Sensor.AvailableProperties do 
    begin 
    end; 
end. 
+0

你能解釋一下更詳細一點嗎?我試圖弄清楚,因爲很多小時。 'p_orientation'是一個'TCustomOrientationSensor',另一邊也是。當我移除像「TypInfo」這樣無關緊要的東西時,它會再次起作用。 –

+0

該聲明與您在問題中報告的內容矛盾。 –

+0

我的陳述是,它不再編譯。你可以自己測試一下。我評論了一些事情,但是我找不到問題出在哪裏,所以我假設了一個編譯器錯誤。 –

回答

5

是的,這看起來像是一個XE8編譯器錯誤。我認爲你已經完成了一項很好的工作,我讚揚你。您需要向Quality Portal提交錯誤報告。

要解決故障,我認爲你將能夠把循環放在單獨的函數中。我的假設是關鍵是在循環中存在兩個不同類型的循環變量,它們是關鍵。避免這種情況,你應該能夠避免這個問題。

+0

非常感謝您的這個想法!現在代碼再次編譯在新版本的Delphi中。 :-)我也報告了這個錯誤:https://quality.embarcadero.com/browse/RSP-10575。 順便說一句,你認爲使用訪問器和typeinfo是唯一可能讀出所有可用的傳感器數據?在我看來,它似乎是一種不潔的編程風格。 –

+0

我對FMX不熟悉,尤其是移動編譯器。但RTTI確實感覺錯了。人們覺得應該有更好的方法....... –