使用加速度计时的逻辑问题
Logics issue while using accelerometer
我正在尝试制作一个类似 "Heads up" 的应用程序,只是为了锻炼身体!
但现在我在我的应用程序中使用加速度计时遇到了一些逻辑问题。
我希望应用程序在向下倾斜时吐司 "correct"(加速度计在此位置给出 -7)并在向上倾斜时吐司 "wrong"(在此位置加速度计给出 7 或更多)。
但问题是应用程序在每个位置重复吐司很多次。所以我使用了一个布尔值 (isToasted) 让应用程序在每个位置都吐司一次。但现在它根本不敬酒了!
我的问题在哪里,我该怎么办?
这是我的代码的一部分:
Boolean isToasted = false;
@Override
public void onSensorChanged(SensorEvent event) {
int sensorValue = (int) event.values[2];
while (isToasted) {
switch (sensorValue) {
case 7: {
Toast.makeText(find_word2.this, "wrong", Toast.LENGTH_SHORT).show();
isToasted = true;
break;
}
case -7: {
Toast.makeText(find_word2.this, "correct", Toast.LENGTH_SHORT).show();
isToasted = true;
break;
}
}
}
if (sensorValue == 0) isToasted = false; //sensorValue = 0 means device is not tilted and it's in direct position.
}
The difference between do-while and while is that do-while evaluates
its expression at the bottom of the loop instead of the top.
Therefore, the statements within the do block are always executed at
least once.
它会在每个位置多次显示 Toast
的原因是因为 SensorEvent
可以出现在单个位置 multiple times:
Note that "on changed" is somewhat of a misnomer, as this will also be
called if we have a new reading from a sensor with the exact same
sensor values (but a newer timestamp).
因此,每当 SensorEvent
具有您在 switch 语句中指定的 z 值之一时,就会显示 Toast
。通过添加 boolean
值来跟踪消息是否已经显示,您走在了正确的轨道上,但是您拥有的 while
循环将永远不会执行,因为 isToasted
设置为 false
.
实际上,您甚至不需要循环。您所要做的就是检查 z 值是否在两个值的范围之间。如果是这样,您将 boolean
设置为 true。如果不是,则检查 boolean
是否为真以及 z 值是否高于或低于范围。然后你可以相应地设置Toast
,并将boolean
设置为false,这样消息就不会显示第二次了。
private boolean isReset = true;
private float mMaxValue = 7;
private float mDeadZone = 5;
@Override
public void onSensorChanged(SensorEvent event) {
float value = event.values[2];
if(value >= mDeadZone || value <= -mDeadZone) {
if(isReset && value <= -mMaxValue) {
Toast.makeText(find_word2.this, "correct", Toast.LENGTH_SHORT).show();
isReset = false;
} else if(isReset && value >= mMaxValue) {
Toast.makeText(find_word2.this, "wrong", Toast.LENGTH_SHORT).show();
isReset = false;
}
} else {
isReset = true;
}
}
您还可以通过使外部 if
语句中的范围低于最大值来创建 "dead zone"。这将确保在 Toast
可以再次显示之前,用户必须将设备重置为接近零。
我正在尝试制作一个类似 "Heads up" 的应用程序,只是为了锻炼身体!
但现在我在我的应用程序中使用加速度计时遇到了一些逻辑问题。
我希望应用程序在向下倾斜时吐司 "correct"(加速度计在此位置给出 -7)并在向上倾斜时吐司 "wrong"(在此位置加速度计给出 7 或更多)。
但问题是应用程序在每个位置重复吐司很多次。所以我使用了一个布尔值 (isToasted) 让应用程序在每个位置都吐司一次。但现在它根本不敬酒了!
我的问题在哪里,我该怎么办?
这是我的代码的一部分:
Boolean isToasted = false;
@Override
public void onSensorChanged(SensorEvent event) {
int sensorValue = (int) event.values[2];
while (isToasted) {
switch (sensorValue) {
case 7: {
Toast.makeText(find_word2.this, "wrong", Toast.LENGTH_SHORT).show();
isToasted = true;
break;
}
case -7: {
Toast.makeText(find_word2.this, "correct", Toast.LENGTH_SHORT).show();
isToasted = true;
break;
}
}
}
if (sensorValue == 0) isToasted = false; //sensorValue = 0 means device is not tilted and it's in direct position.
}
The difference between do-while and while is that do-while evaluates its expression at the bottom of the loop instead of the top. Therefore, the statements within the do block are always executed at least once.
它会在每个位置多次显示 Toast
的原因是因为 SensorEvent
可以出现在单个位置 multiple times:
Note that "on changed" is somewhat of a misnomer, as this will also be called if we have a new reading from a sensor with the exact same sensor values (but a newer timestamp).
因此,每当 SensorEvent
具有您在 switch 语句中指定的 z 值之一时,就会显示 Toast
。通过添加 boolean
值来跟踪消息是否已经显示,您走在了正确的轨道上,但是您拥有的 while
循环将永远不会执行,因为 isToasted
设置为 false
.
实际上,您甚至不需要循环。您所要做的就是检查 z 值是否在两个值的范围之间。如果是这样,您将 boolean
设置为 true。如果不是,则检查 boolean
是否为真以及 z 值是否高于或低于范围。然后你可以相应地设置Toast
,并将boolean
设置为false,这样消息就不会显示第二次了。
private boolean isReset = true;
private float mMaxValue = 7;
private float mDeadZone = 5;
@Override
public void onSensorChanged(SensorEvent event) {
float value = event.values[2];
if(value >= mDeadZone || value <= -mDeadZone) {
if(isReset && value <= -mMaxValue) {
Toast.makeText(find_word2.this, "correct", Toast.LENGTH_SHORT).show();
isReset = false;
} else if(isReset && value >= mMaxValue) {
Toast.makeText(find_word2.this, "wrong", Toast.LENGTH_SHORT).show();
isReset = false;
}
} else {
isReset = true;
}
}
您还可以通过使外部 if
语句中的范围低于最大值来创建 "dead zone"。这将确保在 Toast
可以再次显示之前,用户必须将设备重置为接近零。