1

我可以用传感器的加速度计算速度吗?传感器类型是 SENSOR_TYPE_ACCELEROMETER?或者我可以从传感器获得加速度的方向,哪种类型是 SENSOR_TYPE_ACCELEROMETER?我看过一些关于检查加速度矢量值以检测安卓手机是否正在填充的博客。但是,reson 可能是 android 手机在晃动并且没有填充。我的代码是:

/**
 * how often analysising the accelerometer?(Millisecond)
 */
private static final int ANALYSIS_ACCELERATION_INTERVAL = 500;
/**
 * how often checking the accelerometer?(Millisecond)
 */
private static final int CHECK_TIME_INTERVAL = 5000;
/**
 * when the sMinorMaxAccelerationInOneSecoud[0] is less than 
 * ACCELERATION_CRITICAL_VALUE[0],and the
 * sMinorMaxAccelerationInOneSecoud[1] is more than 
 * ACCELERATION_CRITICAL_VALUE[1],i think the phone dropped to the 
 * ground.
 */
private static float ACCELERATION_CRITICAL_VALUE[] = {2, 40};

/**
 * during{@link #ANALYSIS_ACCELERATION_INTERVAL},the min accelerometer  
 *  of the phone is sMinorMaxAccelerationInOneSecoud[0],the max 
 * accelerometer of the phone is saved at 
 * sMinorMaxAccelerationInOneSecoud[1].
 */
private static float sMinorMaxAccelerationInOneSecoud[] = {0, 0};

/**
 * the last time when checking the accelerometer
 */
private static long sLastCheckTime = 0;

/**
 * the last time when analysising the accelerometer
 */
private static long sLastAnalysisTime = 0;

/**
 * during {@link #CHECK_TIME_INTERVAL},is phone dropped to ground?
 */
private static boolean sIsFallDown = false;


private SensorManager mSensorManager;

public void receiveCondition() {
    // a dialog
    Intent intent = new Intent();
    intent.setClass(GlobalHolder.getApplicationContext(), PhoneDroppedDialog.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    GlobalHolder.getApplicationContext().startActivity(intent);
}

public void start() {
    mSensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
    mSensorManager.registerListener(this,
            mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
            SensorManager.SENSOR_DELAY_UI);
}

public void stop() {
    mSensorManager.unregisterListener(this);
    mSensorManager = null;
    sMinorMaxAccelerationInOneSecoud = new float[]{0, 0};
    sLastCheckTime = 0;
    sLastAnalysisTime = 0;
}

@Override
public void onSensorChanged(SensorEvent event) {
    int sensorType = event.sensor.getType();
    if (sensorType != Sensor.TYPE_LINEAR_ACCELERATION) {
        return;
    }
    // judge if the sMinorMaxAccelerationInOneSecoud[0] is less than 
    // ACCELERATION_CRITICAL_VALUE[0],and the
    // sMinorMaxAccelerationInOneSecoud[1] is more than 
    // ACCELERATION_CRITICAL_VALUE[1]
    analysisAcceleration(event.values);

    long currentTime = System.currentTimeMillis();
    long beta = currentTime - sLastCheckTime;
    if (Math.abs(beta) < CHECK_TIME_INTERVAL) {
        return;
    }
    // it have been more than one secound since the last check,so we need re-check if the phone have dropped to the ground.
    checkIsFallDown();

    // reset sLastCheckTime with the current time
    sLastCheckTime = currentTime;

}

private void analysisAcceleration(float[] values) {
    if (sIsFallDown) {
        // if the phone have already dropped to the ground,we return directly.
        return;
    }

    // whether the min sum vector of the accelerations on the x_axis,y_axis,zaxis is less than ACCELERATION_CRITICAL_VALUE[0]
    // and the max sum vector of the accelerations on the x_axis,y_axis,zaxis is more than ACCELERATION_CRITICAL_VALUE[1]
    if (sLastAnalysisTime == 0) {
        sLastAnalysisTime = System.currentTimeMillis();
    }

    // the sum vector of the accelerations on the x_axis,y_axis,zaxis
    float currentAcceleration = 0f;
    for (int i = 0; i < values.length; i++) {
        currentAcceleration += (values[i] * values[i]);
    }
    currentAcceleration = (float) Math.sqrt(currentAcceleration);

    if (sMinorMaxAccelerationInOneSecoud[0] == 0 || sMinorMaxAccelerationInOneSecoud[0] > currentAcceleration) {
        sMinorMaxAccelerationInOneSecoud[0] = currentAcceleration;
    }

    if (sMinorMaxAccelerationInOneSecoud[1] == 0 || sMinorMaxAccelerationInOneSecoud[1] < currentAcceleration) {
        sMinorMaxAccelerationInOneSecoud[1] = currentAcceleration;
    }

    long currentTime = System.currentTimeMillis();
    long delta = currentTime - sLastAnalysisTime;
    if (delta < ANALYSIS_ACCELERATION_INTERVAL) {
        return;
    }
    MLog.d(TAG, "during ANALYSIS_ACCELERATION_INTERVAL, the min value is " + sMinorMaxAccelerationInOneSecoud[0] + ", the max value is " + sMinorMaxAccelerationInOneSecoud[1]);
    boolean isLessPre = sMinorMaxAccelerationInOneSecoud[0] < ACCELERATION_CRITICAL_VALUE[0];
    boolean isMoreNext = sMinorMaxAccelerationInOneSecoud[1] > ACCELERATION_CRITICAL_VALUE[1];
    sIsFallDown = isLessPre && isMoreNext;
    sLastAnalysisTime = currentTime;
    sMinorMaxAccelerationInOneSecoud = new float[]{0, 0};
}

private void checkIsFallDown() {
    if (sIsFallDown) {
        // the phone have dropped
        receiveCondition();
        MLog.d(TAG, "call the receiveCondition method.");
        sMinorMaxAccelerationInOneSecoud = new float[]{0, 0};
        sIsFallDown = false;
    }
}

有人有更好的主意吗?谢谢!

4

0 回答 0