使用Android中的加速度计准确检测移动

我正在实施一个演示TIMER,具有振动(在特定条件下),当我按开始我的定时器开始运行..当我停止它使用停止按钮,它只是停止.

现在我必须集成一个功能,当人员移动设备(在定时器运行时),它应该重置定时器.它的工作相当不错,但是加速度计的功能并不是绝对准确的.需要一个快速的跳动来重置定时器.

给我一个很好的解决方案.

这是我的代码

public class SensorAccelerometer implements SensorEventListener {

    private Context context;
    private SensorManager sensorManager;
    private Sensor accelerometer;
    private TextView timelabel;
    private Handler mHandler;
    Runnable run;

    private float mLastX,mLastY,mLastZ;
    private final float NOISE = (float) 3.0;

    public SensorAccelerometer(Context context) {

    }


    public SensorAccelerometer(Context context,TextView timelabel,Handler mHandler2,Runnable mUpdateTiMetask) {
        // Todo Auto-generated constructor stub

        this.context = context;
        this.timelabel = timelabel;
        this.mHandler = mHandler2;
        this.run = mUpdateTiMetask;

        initialiseSensor();
    }


    public void initialiseSensor(){
        sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ALL);
        sensorManager.registerListener(this,accelerometer,SensorManager.SENSOR_DELAY_norMAL);
    }

    public void unregisterSensor(){
        sensorManager.unregisterListener(this);
        Toast.makeText(context,"Sensor Stopped..",Toast.LENGTH_SHORT).show();
    }


    public void onAccuracyChanged(Sensor sensor,int accuracy) {

    }

    public void onSensorChanged(SensorEvent event) {
    float x = event.values[0];
    float y = event.values[1];
    float z = event.values[2];

    mAccelLast=mAccelCurrent;

    mAccelCurrent = FloatMath.sqrt(x*x + y*y + z*z);
    float delta = mAccelCurrent - mAccelLast;
    mAccel = mAccel * 0.9f + delta;

    if(mAccel>0.5){
        TimerActivity.mStartTime = SystemClock.uptimeMillis();
        mHandler.removeCallbacks(run);
        mHandler.postDelayed(run,100);
    }

}

计时器活动

public class TimerActivity extends Activity {

    public static long mStartTime = 0L;
    private TextView mTimerLabel;

    private Handler mHandler = new Handler();

    String timerStop1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mTimerLabel = (TextView) findViewById(R.id.textTimer);

        Button timerStartButton = (Button) findViewById(R.id.btnTimer);       
        timerStartButton.setonClickListener(new View.OnClickListener() {
            public void onClick(View view){

                if(mStartTime == 0L){
                    mStartTime = SystemClock.uptimeMillis();
                    mHandler.removeCallbacks(mUpdateTiMetask);
                    mHandler.postDelayed(mUpdateTiMetask,100);

                    //activating the sensor and the acclerometer
                    SensorAccelerometer acc = new SensorAccelerometer(view.getContext(),mTimerLabel,mHandler,mUpdateTiMetask);
                }                                   
            }
        }); 

        Button timerStopButton = (Button) findViewById(R.id.btnTimerStop);       
        timerStopButton.setonClickListener(new View.OnClickListener() {
            public void onClick(View view){

                mHandler.removeCallbacks(mUpdateTiMetask);
                mTimerLabel.setText(timerStop1);
                mStartTime = 0L;

                SensorAccelerometer scc = new SensorAccelerometer(view.getContext(),mUpdateTiMetask);
                scc.unregisterSensor();
            }
        }); 

    } 


    private Runnable mUpdateTiMetask = new Runnable(){

        public void run() {

            final long start = mStartTime;
            long millis = SystemClock.uptimeMillis()- start;

            int seconds = (int) (millis / 1000);
            int minutes = seconds / 60;
            seconds = seconds % 60;

            mTimerLabel.setText("" + minutes + ":"
                                  + String.format("%02d",seconds));                    

            timerStop1 = minutes + ":"
                      + String.format("%02d",seconds);

            mHandler.postDelayed(this,200);            

        }   
    }; 

    protected void onPause() {
        super.onPause();
        SensorAccelerometer scc = new SensorAccelerometer(this,mUpdateTiMetask);
        scc.unregisterSensor();
    };

}

解决方法

我认为开发应用程序的下一个阶段是查看电子表格中生成的加速度值.我为此使用Excel,但任何可以生成图形的工具都可以.所以将onSensorChanged()改为类似的东西
public void onSensorChanged(SensorEvent event) {
    float x = event.values[0];
    float y = event.values[1];
    float z = event.values[2];

    float mAccelCurrent = FloatMath.sqrt(x*x + y*y + z*z);
    float mAccel = mAccel * 0.9f + mAccelCurrent * 0.1f;
    Log.d("onSensorChanged",System.currentTimeMillis()+","+mAccelCurrent +","+mAccel);

}

然后您可以将currentTime,mAccelCurrent和mAccel捕获到Android日志记录机制中.或者,创建自己的文本文件,在其中写入值,然后在可以生成图形的工具中打开该文件.从图中,您可以决定用于触发器的值.

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...