运动检测准确使用加速度计的Andr​​oid加速度计、准确、oid、Andr

2023-09-04 13:19:54 作者:拾安

我在执行演示计时器,与振动(在特定的条件下),当我preSS启动我的定时器开始运行..当我停止使用停止按钮,它只是停止。

现在我已经集成了功能,当人转移设备的(在定时器运行),应该复位定时器。这是工作pretty的好,但加速的功能无法正常工作绝对准确。它需要一个快速挺举重置计时器。

建议我要同一个很好的解决方案。

下面是我的code

 公共类SensorAccelerometer实现SensorEventListener {

    私人上下文的背景下;
    私人的SensorManager的SensorManager;
    私人Sensor重力感应;
    私人TextView的timelabel;
    私人处理器mHandler;
    Runnable运行;

    私人浮动mLastX,mLastY,mLastZ;
    私人最终浮动噪声=(浮点)3.0;

    公共SensorAccelerometer(上下文的背景下){

    }


    公共SensorAccelerometer(上下文的背景下,TextView的timelabel,处理程序mHandler2,可运行mUpdateTimeTask){
        // TODO自动生成构造函数存根

        this.context =背景;
        this.timelabel = timelabel;
        this.mHandler = mHandler2;
        this.run = mUpdateTimeTask;

        initialiseSensor();
    }


    公共无效initialiseSensor(){
        的SensorManager =(的SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        加速度= sensorManager.getDefaultSensor(Sensor.TYPE_ALL);
        sensorManager.registerListener(这一点,加速度计,SensorManager.SENSOR_DELAY_NORMAL);
    }

    公共无效unregisterSensor(){
        sensorManager.unregisterListener(本);
        Toast.makeText(背景下,传感器停止..,Toast.LENGTH_SHORT).show();
    }


    公共无效onAccuracyChanged(传感器传感器,诠释精度){

    }

    公共无效onSensorChanged(SensorEvent事件){
    浮X = event.values​​ [0];
    浮Y = event.values​​ [1];
    浮Z = event.values​​ [2];

    mAccelLast = mAccelCurrent;

    mAccelCurrent = FloatMath.sqrt(X * X + Y * Y + Z * Z);
    浮动三角洲= mAccelCurrent  -  mAccelLast;
    mAccel = mAccel * 0.9F +增量;

    如果(mAccel&0.5){
        TimerActivity.mStartTime = SystemClock.uptimeMillis();
        mHandler.removeCallbacks(运行);
        mHandler.postDelayed(运行,100);
    }
 

}

定时活动

 公共类TimerActivity延伸活动{

    公共静态长mStartTime = 0L;
    私人TextView的mTimerLabel;

    私人处理程序mHandler =新的处理程序();

    字符串timerStop1;

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);

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

        按钮timerStartButton =(按钮)findViewById(R.id.btnTimer);
        timerStartButton.setOnClickListener(新View.OnClickListener(){
            公共无效的onClick(视图查看){

                如果(mStartTime == 0L){
                    mStartTime = SystemClock.uptimeMillis();
                    mHandler.removeCallbacks(mUpdateTimeTask);
                    mHandler.postDelayed(mUpdateTimeTask,100);

                    //激活传感器和acclerometer
                    SensorAccelerometer ACC =新SensorAccelerometer(view.getContext(),mTimerLabel,mHandler,mUpdateTimeTask);
                }
            }
        });

        按钮timerStopButton =(按钮)findViewById(R.id.btnTimerStop);
        timerStopButton.setOnClickListener(新View.OnClickListener(){
            公共无效的onClick(视图查看){

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

                SensorAccelerometer SCC =新SensorAccelerometer(view.getContext(),mTimerLabel,mHandler,mUpdateTimeTask);
                scc.unregisterSensor();
            }
        });

    }


    私人可运行mUpdateTimeTask =新的Runnable(){

        公共无效的run(){

            最终长开始= mStartTime;
            长米利斯= SystemClock.uptimeMillis() - 启动;

            INT秒=(INT)(米利斯/ 1000);
            INT分钟=秒/ 60;
            秒=秒%60;

            mTimerLabel.setText(+分钟+:
                                  +的String.Format(%02D,秒));

            timerStop1 =分钟+:
                      +的String.Format(%02D,秒);

            mHandler.postDelayed(此,200);

        }
    };

    保护无效的onPause(){
        super.onPause();
        SensorAccelerometer SCC =新SensorAccelerometer(这一点,mTimerLabel,mHandler,mUpdateTimeTask);
        scc.unregisterSensor();
    };

}
 

解决方案

我想在你的应用程序发展的下一阶段是看所生产的为preadsheet加速度的值。我使用Excel这一点,但可以生成图表任何工具就可以了。因此,改变 onSensorChanged()来像

 公共无效onSensorChanged(SensorEvent事件){
    浮X = event.values​​ [0];
    浮Y = event.values​​ [1];
    浮Z = event.values​​ [2];

    浮mAccelCurrent = FloatMath.sqrt(X * X + Y * Y + Z * Z);
    浮mAccel = mAccel * 0.9F + mAccelCurrent * 0.1F;
    Log.d(onSensorChanged,System.currentTimeMillis的()+,+ mAccelCurrent +,+ mAccel);

}
 

然后就可以捕捉到currentTime的,mAccelCurrent和mAccel到Android的日志机制。另外,创建你自己的文本文件,写入值出现,并且能够产生图形工具打开该文件。从图表,然后你可以决定使用触发器什么样的价值观。

I am implementing a demo TIMER, with Vibration ( at a particular condition ), When I press start my timer starts running.. and when I stop it using stop button, it simply stops.

Now I have to integrate a functionality, when the person shifts the device (while the Timer is running), it should reset the timer. It is working pretty good, but the accelerometer functionality is not working absolutely accurate. It needs a fast jerk to reset the timer.

Suggest me a good solution for the same.

Here is my code

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);
    }

}

Timer Activity

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(),mTimerLabel,mHandler,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,mTimerLabel,mHandler,mUpdateTimeTask);
        scc.unregisterSensor();
    };

} 

解决方案

I think the next stage in the development of your app is to look at values of acceleration that are produced in a spreadsheet. I use Excel for this, but any tool that can produce graphs will do. So alter onSensorChanged() to something like

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);

}

and then you can capture the currentTime, mAccelCurrent and mAccel into the Android logging mechanism. Alternatively, create your own text file, write the values there, and open the file in a tool that can produce graphs. From the graphs, you can then decide what values to use for your trigger.