使用加速度计确定安卓的移动

  • 本文关键字:移动 加速度计 android
  • 更新时间 :
  • 英文 :


我正在制作一个带有加速度计传感器的安卓应用程序。我的目标是当我将智能手机向右移动,然后发送到服务器"RIGHT",当我将智能手机向左移动时,然后发送到服务器"LEFT"。要实现此功能,我知道我必须检测智能手机的移动。在实现这个函数之前,我只想在textview上打印"RIGHT"或"LEFT",所以我搜索了一些代码,我写了这样的代码,

package com.example.administrator.motiondetector;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MotionDetector extends AppCompatActivity implements SensorEventListener {
private TextView xText;
private TextView yText;
private SensorManager mSensorManager;
private Sensor mSensorAccelerometer;
private float xPastData;
private float yPastData;
private float zPastData;
private float Speed;
private float AccHistory[] = new float[3];
private float AccelData[] = new float[3];
String[] direction = {"NONE", "NONE"}
private long lastTime;
private static final int SHAKE_THRESHOLD = 800;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_motion_detector);
xText = (TextView) findViewById(R.id.xText);
yText = (TextView) findViewById(R.id.yText);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorAccelerometer = mSensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
mSensorManager.registerListener(this, mSensorAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);
}
public void onSensorChanged (SensorEvent event) {
if (event.sensor.getType() == mSensorAccelerometer.TYPE_ACCELEROMETER) {
long currentTime = System.currentTimeMillis();
long TimeInterval = currentTime - lastTime;
if (TimeInterval > 100) {
lastTime = currentTime;
AccelData[0] = event.values[0];
AccelData[1] = event.values[1];
AccelData[2] = event.values[2];
Speed = Math.abs(AccelData[0] + AccelData[1] + AccelData[2] - xPastData - yPastData - zPastData) / TimeInterval * 10000;
if (Speed > SHAKE_THRESHOLD) {
Log.i("roosh", "Speed : " + Speed + ". Higher than Threshold");
float xChange = AccHistory[0] - AccelData[0];
float yChange = AccHistory[1] - AccelData[1];
AccHistory[0] = event.values[0];
AccHistory[1] = event.values[1];
if (xChange > 3) {
Log.i("roosh", "AccHistory[0] : " + AccHistory[0]);
Log.i("roosh", "AccelData[0] : " + AccelData[0]);
Log.i("roosh", "xChange : " + xChange + ". Direction is LEFT");
direction[0] = "LEFT";
} else if (xChange < -3) {
Log.i("roosh", "AccHistory[0] : " + AccHistory[0]);
Log.i("roosh", "AccelData[0] : " + AccelData[0]);
Log.i("roosh", "xChange : " + xChange + ". Direction is RIGHT");
direction[0] = "RIGHT";
}
if (yChange > 3) {
Log.i("roosh", "AccHistory[1] : " + AccHistory[1]);
Log.i("roosh", "AccelData[1] : " + AccelData[1]);
Log.i("roosh", "xChange : " + xChange + ". Direction is DOWN");
direction[1] = "DOWN";
} else if (yChange < -3) {
Log.i("roosh", "AccHistory[1] : " + AccHistory[1]);
Log.i("roosh", "AccelData[1] : " + AccelData[1]);
Log.i("roosh", "xChange : " + xChange + ". Direction is UP");
direction[1] = "UP";
}
xText.setText("X : " + direction[0]);
yText.setText("Y : " + direction[1]);
}
Log.i("roosh", "Speed : " + Speed + ". Lower than Threshold");
xPastData = event.values[0];
yPastData = event.values[1];
zPastData = event.values[2];
}
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Not in use
}
}

问题是这个。此代码有时运行良好。但有时存在很多问题。这意味着文本视图显示我"右",尽管我将智能手机从右向左移动(文本视图必须显示我"左"),并且文本视图显示我"左",尽管我将智能手机从左到右移动(文本视图缪斯显示"右")。

我在堆栈溢出中找到了一些解决方案,但我失败了。 有些人说我不仅要使用加速度计传感器,还要使用更多的传感器,例如陀螺仪或磁力计。但是我不明白如何修复这些传感器(加速度计,陀螺仪,磁力计)来检测智能手机的运动。

我以为"https://www.codeproject.com/Articles/729759/Android-Sensor-Fusion-Tutorial"处的代码可以帮助我,但我无法理解这些代码......

所以,问题是这个。 我的代码有什么问题?我的代码有什么解决方案吗?或者有任何示例代码吗?或者有人可以告诉我如何理解"https://www.codeproject.com/Articles/729759/Android-Sensor-Fusion-Tutorial"处的代码吗?

有些人会说"请在stackoverflow上搜索更多",但我已经这样做了。 我真的很想制作这个程序。

感谢您的阅读

没有好的方法可以使用加速度计检测手机的绝对运动,它只能检测相对运动/晃动。

您可以开始慢慢地向右移动手机,然后突然停止它,您将看到加速度计读数激增。

但是,如果您开始快速向左移动手机,然后慢慢停止它,您将看到加速度计读数在相同方向上的相同峰值。

您可以将加速度计想象成一个小球在手机中自由漂浮。当您将手机向右移动时,球会击中左侧,并且手机会检测到移动。当您将手机向左移动然后停止时,球击中相同的左侧,并检测到相同的移动,手机无法知道您之前已经开始移动它。

由于加速度计不是一个非常精确的传感器,它根本无法检测到缓慢的运动,除非您使用的是Project Tango设备。

加速度计可以为您提供的唯一可靠读数是地球中心的方向,这要归功于重力。

陀螺仪通常是更精确的传感器,但它只检测相对旋转,而不是线性运动。它也无法知道您是否更早开始旋转手机,但您可以将其与加速度计结合使用,加速度计为您提供到地心的绝对方向,以及指南针,为您提供磁北极的方向,尽管根据我的经验,指南针即使在高端手机上也会疯狂漂移。

要对加速度计做同样的事情,你必须将其与GPS结合起来,而GPS太不精确了。

你读过 Android 开发者文档吗?

您可能会感兴趣的几点:

从运动传感器:

加速度计使用标准传感器坐标系。实际上,这意味着当设备以自然方向平放在桌子上时,以下条件适用:

  1. 如果将设备推到左侧(使其向右移动),则 x 加速度值为正。

  2. 如果将设备推到底部(使其远离您),则 y 加速度值为正。

  3. 如果以 A m/s2
  4. 的加速度将设备推向天空,则 z 加速度值等于 A + 9.81,对应于设备的加速度 (+A m/s2) 减去重力 (-9.81 m/s2)。

  5. 固定设备的加速度值为 +9.81,对应于设备的加速度(0 m/s2 减去重力,即 -9.81 m/s2)。

在哪种情况下,您的应用程序有效?

您也可以查看有关传感器坐标系的信息。

最新更新