在备忘录中列出原始传感器数据
List raw sensor data in Memo
我想在 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 个因素时才会发生:
- 类型信息
- 访问器
- 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 编译器错误。我认为你在隔离它方面做得很好,为此我赞扬你。您需要向 Quality Portal 提交错误报告。
为了解决这个错误,我认为你可以将循环放在单独的函数中。我的假设是,关键是存在两个具有不同类型循环变量的 for in 循环,这是关键。避免这种情况,您应该能够避免问题。
我想在 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 个因素时才会发生:
- 类型信息
- 访问器
- 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 编译器错误。我认为你在隔离它方面做得很好,为此我赞扬你。您需要向 Quality Portal 提交错误报告。
为了解决这个错误,我认为你可以将循环放在单独的函数中。我的假设是,关键是存在两个具有不同类型循环变量的 for in 循环,这是关键。避免这种情况,您应该能够避免问题。