计步器源代码实现的俩种方式

网上比较流行的计步好多都是用第一中方法写,是一套算法:

下边是第一种的代码,个人感觉准确度不是很好,误差经常在好几十往上,但是也还能用:下载地址:http://download.csdn.net/detail/u012808234/8539079

package com.example.pedometerdemo;

import java.util.List;
import java.util.Timer;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.util.Log;



public class pedometerService extends Service implements SensorEventListener {

    public static final String STEP_CHANGE = "step_change";
    public static final String ADD_STEPS = "add_Step";
    
    private static final int notifiId = 11;
    private Intent intent;
    private ActivityManager activityManager;
    private SensorManager sensorManager;
    private Timer timer = new Timer();
    private long lastTime;// 上次记步的时间

    private float mLimit = 6.44f;
    private int interval_time;
    private float mLastValues[] = new float[3 * 2];
    private float mScale[] = new float[2];
    private float mYOffset;

    private float mLastDirections[] = new float[3 * 2];
    private float mLastExtremes[][] = { new float[3 * 2], new float[3 * 2] };
    private float mLastDiff[] = new float[3 * 2];
    private int mLastMatch = -1;

    private int startStep;

    private Service instance;
    
    private float[] xyz=new float[3];
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        instance = this;
        initData();
        initStepDetector();
        interval_time = 200;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        System.out.println("启动");
        return START_REDELIVER_INTENT;
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        sensorManager.unregisterListener(this);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        // TODO Auto-generated method stub
        Sensor sensor = event.sensor;
        synchronized (this) {
            if (System.currentTimeMillis() - lastTime < interval_time) {
                return;
            }
            if (sensor.getType() == Sensor.TYPE_ORIENTATION) {
            } else {
                int j = (sensor.getType() == Sensor.TYPE_ACCELEROMETER) ? 1 : 0;
                
                if (j == 1) {
                    float vSum = 0;
                    
                
                    for (int i = 0; i < 3; i++) {
                        final float v = mYOffset + event.values[i] * mScale[j];
                        
                        vSum += v;
                    }
                    int k = 0;
                    float v = vSum / 3;

                    float direction = (v > mLastValues[k] ? 1 : (v < mLastValues[k] ? -1 : 0));
                    if (direction == -mLastDirections[k]) {
                        // Direction changed
                        int extType = (direction > 0 ? 0 : 1); // minumum or
                                                                // maximum?
                        mLastExtremes[extType][k] = mLastValues[k];
                        float diff = Math.abs(mLastExtremes[extType][k] - mLastExtremes[1 - extType][k]);

                        if (diff > mLimit) {
                            boolean isAlmostAsLargeAsPrevious = diff > (mLastDiff[k] * 2 / 3);
                            boolean isPreviousLargeEnough = mLastDiff[k] > (diff / 3);
                            boolean isNotContra = (mLastMatch != 1 - extType);

                            if (isAlmostAsLargeAsPrevious && isPreviousLargeEnough && isNotContra) {
                                long currentTime = System.currentTimeMillis();
                                if (currentTime - lastTime > 2000) {
                                    
                                    startStep = 0;
                                } else {
                                   Log.e("STEP", startStep+++"");
                                }
                                mLastMatch = extType;
                                lastTime = currentTime;
                            } else {
                                mLastMatch = -1;
                            }
                        }
                        mLastDiff[k] = diff;
                    }
                    mLastDirections[k] = direction;
                    mLastValues[k] = v;
                }
            }
        }
    }

    private boolean appIsTop() {
        if (activityManager == null) {
            activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        }
        List<RunningTaskInfo> rti = activityManager.getRunningTasks(1);
        String packagename = rti.get(0).topActivity.getPackageName();
        if (packagename.equals(getPackageName())) {
            return true;
        }
        return false;
    }

    public void initStepDetector() {
        int h = 480; // TODO: remove this constant
        mYOffset = h * 0.5f;
        mScale[0] = -(h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
        mScale[1] = -(h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
    }

    @Override
    public void onAccuracyChanged(Sensor arg0, int arg1) {
        // TODO Auto-generated method stub

    }
    private void initData() {
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        if (sensorManager != null) {// 注册监听器
            sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
            // 第一个参数是Listener,第二个参数是所得传感器类型,第三个参数值获取传感器信息的频率
        }

    }
    
}


还有第二种,我觉得是误差小点的,自己测试了下,不管别的情况的,就是正常走路的误差在10步左右:看看代码,他是封成了好几个方法,上最主要的逻辑代码:

 下载地址:http://download.csdn.net/detail/u012808234/8539095

/*
 * Copyright 2013 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.android.apps.simplepedometer;

/**
 * Receives sensor updates and alerts a StepListener when a step has been detected.
 */
public class SimpleStepDetector {

  private static final int ACCEL_RING_SIZE = 50;
  private static final int VEL_RING_SIZE = 10;
  private static final float STEP_THRESHOLD = 4f;
  private static final int STEP_DELAY_NS = 250000000;

  private int accelRingCounter = 0;
  private float[] accelRingX = new float[ACCEL_RING_SIZE];
  private float[] accelRingY = new float[ACCEL_RING_SIZE];
  private float[] accelRingZ = new float[ACCEL_RING_SIZE];
  private int velRingCounter = 0;
  private float[] velRing = new float[VEL_RING_SIZE];
  private long lastStepTimeNs = 0;
  private float oldVelocityEstimate = 0;

  private StepListener listener;

  public void registerListener(StepListener listener) {
    this.listener = listener;
  }

  /**
   * Accepts updates from the accelerometer.
   */
  public void updateAccel(long timeNs, float x, float y, float z) {
    float[] currentAccel = new float[3];
    currentAccel[0] = x;
    currentAccel[1] = y;
    currentAccel[2] = z;

    // First step is to update our guess of where the global z vector is.
    accelRingCounter++;
    accelRingX[accelRingCounter % ACCEL_RING_SIZE] = currentAccel[0];
    accelRingY[accelRingCounter % ACCEL_RING_SIZE] = currentAccel[1];
    accelRingZ[accelRingCounter % ACCEL_RING_SIZE] = currentAccel[2];

    float[] worldZ = new float[3];
    worldZ[0] = SensorFusionMath.sum(accelRingX) / Math.min(accelRingCounter, ACCEL_RING_SIZE);
    worldZ[1] = SensorFusionMath.sum(accelRingY) / Math.min(accelRingCounter, ACCEL_RING_SIZE);
    worldZ[2] = SensorFusionMath.sum(accelRingZ) / Math.min(accelRingCounter, ACCEL_RING_SIZE);

    float normalization_factor = SensorFusionMath.norm(worldZ);

    worldZ[0] = worldZ[0] / normalization_factor;
    worldZ[1] = worldZ[1] / normalization_factor;
    worldZ[2] = worldZ[2] / normalization_factor;

    // Next step is to figure out the component of the current acceleration
    // in the direction of world_z and subtract gravity's contribution
    float currentZ = SensorFusionMath.dot(worldZ, currentAccel) - normalization_factor;
    velRingCounter++;
    velRing[velRingCounter % VEL_RING_SIZE] = currentZ;

    float velocityEstimate = SensorFusionMath.sum(velRing);

    if (velocityEstimate > STEP_THRESHOLD && oldVelocityEstimate <= STEP_THRESHOLD
        && (timeNs - lastStepTimeNs > STEP_DELAY_NS)) {
      listener.step(timeNs);
      lastStepTimeNs = timeNs;
    }
    oldVelocityEstimate = velocityEstimate;
  }
}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单计步器的完整代码示例,可以在Android Studio中创建一个新的项目并将以下代码复制到MainActivity.java文件中: ```java import androidx.appcompat.app.AppCompatActivity; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends AppCompatActivity implements SensorEventListener { private TextView stepCountTextView; private SensorManager sensorManager; private Sensor stepSensor; private boolean isSensorPresent; private int stepCount = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); stepCountTextView = findViewById(R.id.step_count_text_view); sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); if (sensorManager != null) { stepSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER); if (stepSensor != null) { isSensorPresent = true; } } if (!isSensorPresent) { stepCountTextView.setText("Step sensor not present!"); } } @Override protected void onResume() { super.onResume(); if (isSensorPresent) { sensorManager.registerListener(this, stepSensor, SensorManager.SENSOR_DELAY_NORMAL); } } @Override protected void onPause() { super.onPause(); if (isSensorPresent) { sensorManager.unregisterListener(this); } } @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) { stepCount = (int) event.values[0]; stepCountTextView.setText("Step count: " + stepCount); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } } ``` 此代码使用Android的传感器API来实现计步器。在onCreate方法中,它检查设备是否支持计步器传感器,如果支持,则注册SENSOR_DELAY_NORMAL监听器以接收步数更新。在onResume方法中,它注册了传感器监听器,而在onPause方法中注销了它。在onSensorChanged方法中,它更新步数并在UI上显示它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值