2015-04-21 26 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确实感觉错了。人们觉得应该有更好的方法....... –