Android 在备忘录中列出原始传感器数据

Android 在备忘录中列出原始传感器数据,android,delphi,firemonkey,delphi-xe8,Android,Delphi,Firemonkey,Delphi Xe8,我想在Android的备忘录中列出所有可用的原始传感器数据 下面的代码在过去几年中一直有效,但它不适用于XE8。可能存在内部编译器错误。我能做些什么使它再次工作,或者有其他解决方案吗 uses TypInfo; type TOrientationSensorAccessor = class(TCustomOrientationSensor); TLocationSensorAccessor = class(TCustomLocationSensor); procedure TFo

我想在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”时,它将编译:

//    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循环都可以工作,但组合起来就不起作用了

看起来只有将以下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.

是的,这看起来像是XE8编译器的错误。我认为你在隔离它方面做得很好,为此我赞扬你。您需要向质量门户提交错误报告


为了解决这个问题,我认为您可以将循环放在单独的函数中。我的假设是,关键是存在两个for-in循环,其中不同类型的循环变量是关键。避免这种情况,你应该能够避免这个问题

你能再详细解释一下吗?几个小时以来我一直在想办法
p_方向
是一个
TCustomOrientationSensor
和另一侧。当我删除像“TypInfo”这样不相关的东西时,它又起作用了。这句话与你在问题中的报告相矛盾。我的说法是,它不再编译了。你可以自己测试。我对一些内容进行了注释,但无法找出问题所在,因此我假设存在编译器错误。看起来您已经在我看来发现了问题
//错误(仅在XE8中):不兼容的类型“TCustomLocationSensor.tpProperty”和“TCustomOrientationSensor.tpProperty”
从不假设任何内容,尤其是在责怪别人的时候。更新让事情变得更清楚了。谢谢。非常感谢你的这个想法!现在,代码再次在新版本的Delphi中编译。:-)我还报告了错误:。顺便问一下,你认为使用访问器和类型信息是读取所有可用传感器数据的唯一可能吗?在我看来,这似乎是一种不干净的编程风格。我不熟悉FMX,尤其是移动编译器。但RTTI在这方面确实感觉非常错误。人们觉得应该有更好的办法。。。。。。。