我可以用传感器的加速度计算速度,类型是SENSOR_TYPE_ACCELEROMETER吗? 或者我可以从传感器获得类型为SENSOR_TYPE_ACCELEROMETER的加速度方向? 我见过一些博客,关于检查加速度矢量的值,以检测Android手机是否正在填充。 但是,共鸣可能是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;
}
}
有人有更好的主意吗?谢谢!