[英]Android - How to detect change in compass degree (Java)
我有以下代码可以在Nexus 5上完美运行。
public void onSensorChanged(SensorEvent event) {
float degree = Math.round(event.values[0]);
displayMsg.setText(String.valueOf(degree));
}
degree
包含指南针的方向。 我要做的是检测方向的变化。 因此,假设某人向北走,然后向右转10度。 人一旦改变方向,我就希望能够注意到。 此外,还有不确定性。 因此,例如,当人向北走时,方向不是恒定的0度。 它将在358至2-3度之间波动。
我想到了使用Timer.schedule
每500毫秒存储一次度,然后执行
if(Math.abs(degree - storedDegree) > 10)
Toast.makeText(this,"Direction Changed",Toast.LENGTH_SHORT).show();
但是,由于我认为创建的线程数量,此方法用完了内存。 有没有更聪明/更好的方法来检测方向变化?
更新
这是我正在执行的完整代码。
我正在计算步骤,我想保持执行步骤的方向。 一旦方向改变了10度,步数计数器应存储它拥有的值(例如在数组列表中),然后转到0并重新开始计数。
boolean start = true;
@Override
public void onSensorChanged(SensorEvent event) {
//------------------------------Compass--------------------------------------
final float degree = Math.round(event.values[0]);
displayMsg.setText(String.valueOf(degree));
//---------------------------------------------------------------------------
Sensor sensor = event.sensor;
float[] values = event.values;
int value = -1;
int steps;
if (values.length > 0) {
value = (int) values[0];
}
if(mode.equals("Start"))
{
if (sensor.getType() == Sensor.TYPE_STEP_COUNTER)
{
if(start)
{
count = value;
start = false;
}
steps = value-count;
stepCounter.setText("Step Counter Detected : " + steps);
}
}
}
我将使用低通滤波器来消除波动。
这是代码:
protected float[] lowPass(float[] input, float[] output) {
if (output == null) return input;
for (int i = 0; i < input.length; i++) {
output[i] = output[i] + ALPHA * (input[i] - output[i]);
}
return output;
}
其中ALPHA是静态最终浮点ALPHA = 0.25f;
我还将发布用于获取“方向”的代码。 也许它可以帮助您:
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = lowPass(event.values.clone(), mGravity);
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = lowPass(event.values.clone(), mGeomagnetic);
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
azimut = orientation[0]; // orientation contains: azimut, pitch and roll
}
}
}
之后,使用如下方位角:
if (azimut != null) {
canvas.rotate(-azimut * 360 / (2 * 3.14159f), centerx, centery);
if ((azimut > -0.2) && (azimut < 0.2)) current_direction = "North";
if ((azimut > 1.3) && (azimut < 1.7)) current_direction = "East";
if (((azimut < -2.8) && (azimut > -3.2)) || ((azimut < 3.2) && (azimut > 2.8))) current_direction = "South";
if ((azimut > -1.7) && (azimut < -1.3)) current_direction = "West";
}
我认为您的问题更多与传感器有关,而不是您的逻辑。 您可以尝试一下,但是传感器并不是我真正的失败。 我知道定位服务可以为您提供设备定位(通过gps),这也可能是一种选择。
您可以检查当前学位的变化幅度是否超过阈值,然后用新学位更新储值吗?
一个可能的示例是这样的:想法是,由于onSensorChanged在值更新时都会被调用,因此您可以检查当前度和存储值之间的差是否大于某个阈值。 如果采取措施并存储新的度数,则不做任何更改。
private float storedDegree;
public void onSensorChanged(SensorEvent event) {
if (sensor.getType() == Sensor.TYPE_ORIENTATION) {
float degree = Math.round(event.values[0]);
if(Math.abs(degree - storedDegree) > 10) {
Toast.makeText(this,"Direction Changed",Toast.LENGTH_SHORT).show();
displayMsg.setText(String.valueOf(degree));
storedDegree = degree;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.