我需要添加一个摇功能,将刷新我的Android应用程序。
我所找到的所有文档都涉及实现SensorListener,但Eclipse告诉我它已被弃用,并建议使用SensorEventListener。
有人知道如何创建这个震动控制器吗?
我需要添加一个摇功能,将刷新我的Android应用程序。
我所找到的所有文档都涉及实现SensorListener,但Eclipse告诉我它已被弃用,并建议使用SensorEventListener。
有人知道如何创建这个震动控制器吗?
当前回答
我正在为我的大学项目开发一个运动检测和震动检测应用程序。
除了应用程序的原始目标之外,我还从应用程序中分离了库部分(负责运动和震动检测)。该代码是免费的,可在SourceForge上获得,项目名称为“BenderCatch”。我正在制作的文件将在9月中旬左右准备好。 http://sf.net/projects/bendercatch
它使用了一种更精确的方法来检测震动:当你执行震动时,既观察SensorEvents之间的力差,也观察X轴和Y轴上的振动。它甚至可以在每次震动时发出声音(或振动)。
欢迎通过电子邮件raffaele [at] terzigno [dot] com向我询问更多信息
其他回答
这里还有另一个实现,它是基于这里的一些技巧以及来自Android开发人员网站的代码。
MainActivity.java
public class MainActivity extends Activity {
private ShakeDetector mShakeDetector;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ShakeDetector initialization
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mShakeDetector = new ShakeDetector(new OnShakeListener() {
@Override
public void onShake() {
// Do stuff!
}
});
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
}
@Override
protected void onPause() {
mSensorManager.unregisterListener(mShakeDetector);
super.onPause();
}
}
ShakeDetector.java
package com.example.test;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
public class ShakeDetector implements SensorEventListener {
// Minimum acceleration needed to count as a shake movement
private static final int MIN_SHAKE_ACCELERATION = 5;
// Minimum number of movements to register a shake
private static final int MIN_MOVEMENTS = 2;
// Maximum time (in milliseconds) for the whole shake to occur
private static final int MAX_SHAKE_DURATION = 500;
// Arrays to store gravity and linear acceleration values
private float[] mGravity = { 0.0f, 0.0f, 0.0f };
private float[] mLinearAcceleration = { 0.0f, 0.0f, 0.0f };
// Indexes for x, y, and z values
private static final int X = 0;
private static final int Y = 1;
private static final int Z = 2;
// OnShakeListener that will be notified when the shake is detected
private OnShakeListener mShakeListener;
// Start time for the shake detection
long startTime = 0;
// Counter for shake movements
int moveCount = 0;
// Constructor that sets the shake listener
public ShakeDetector(OnShakeListener shakeListener) {
mShakeListener = shakeListener;
}
@Override
public void onSensorChanged(SensorEvent event) {
// This method will be called when the accelerometer detects a change.
// Call a helper method that wraps code from the Android developer site
setCurrentAcceleration(event);
// Get the max linear acceleration in any direction
float maxLinearAcceleration = getMaxCurrentLinearAcceleration();
// Check if the acceleration is greater than our minimum threshold
if (maxLinearAcceleration > MIN_SHAKE_ACCELERATION) {
long now = System.currentTimeMillis();
// Set the startTime if it was reset to zero
if (startTime == 0) {
startTime = now;
}
long elapsedTime = now - startTime;
// Check if we're still in the shake window we defined
if (elapsedTime > MAX_SHAKE_DURATION) {
// Too much time has passed. Start over!
resetShakeDetection();
}
else {
// Keep track of all the movements
moveCount++;
// Check if enough movements have been made to qualify as a shake
if (moveCount > MIN_MOVEMENTS) {
// It's a shake! Notify the listener.
mShakeListener.onShake();
// Reset for the next one!
resetShakeDetection();
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Intentionally blank
}
private void setCurrentAcceleration(SensorEvent event) {
/*
* BEGIN SECTION from Android developer site. This code accounts for
* gravity using a high-pass filter
*/
// alpha is calculated as t / (t + dT)
// with t, the low-pass filter's time-constant
// and dT, the event delivery rate
final float alpha = 0.8f;
// Gravity components of x, y, and z acceleration
mGravity[X] = alpha * mGravity[X] + (1 - alpha) * event.values[X];
mGravity[Y] = alpha * mGravity[Y] + (1 - alpha) * event.values[Y];
mGravity[Z] = alpha * mGravity[Z] + (1 - alpha) * event.values[Z];
// Linear acceleration along the x, y, and z axes (gravity effects removed)
mLinearAcceleration[X] = event.values[X] - mGravity[X];
mLinearAcceleration[Y] = event.values[Y] - mGravity[Y];
mLinearAcceleration[Z] = event.values[Z] - mGravity[Z];
/*
* END SECTION from Android developer site
*/
}
private float getMaxCurrentLinearAcceleration() {
// Start by setting the value to the x value
float maxLinearAcceleration = mLinearAcceleration[X];
// Check if the y value is greater
if (mLinearAcceleration[Y] > maxLinearAcceleration) {
maxLinearAcceleration = mLinearAcceleration[Y];
}
// Check if the z value is greater
if (mLinearAcceleration[Z] > maxLinearAcceleration) {
maxLinearAcceleration = mLinearAcceleration[Z];
}
// Return the greatest value
return maxLinearAcceleration;
}
private void resetShakeDetection() {
startTime = 0;
moveCount = 0;
}
// (I'd normally put this definition in it's own .java file)
public interface OnShakeListener {
public void onShake();
}
}
和我一起工作,很好 参考
public class ShakeEventListener implements SensorEventListener {
public final static int SHAKE_LIMIT = 15;
public final static int LITTLE_SHAKE_LIMIT = 5;
private SensorManager mSensorManager;
private float mAccel = 0.00f;
private float mAccelCurrent = SensorManager.GRAVITY_EARTH;
private float mAccelLast = SensorManager.GRAVITY_EARTH;
private ShakeListener listener;
public interface ShakeListener {
public void onShake();
public void onLittleShake();
}
public ShakeEventListener(ShakeListener l) {
Activity a = (Activity) l;
mSensorManager = (SensorManager) a.getSystemService(Context.SENSOR_SERVICE);
listener = l;
registerListener();
}
public ShakeEventListener(Activity a, ShakeListener l) {
mSensorManager = (SensorManager) a.getSystemService(Context.SENSOR_SERVICE);
listener = l;
registerListener();
}
public void registerListener() {
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
}
public void unregisterListener() {
mSensorManager.unregisterListener(this);
}
public void onSensorChanged(SensorEvent se) {
float x = se.values[0];
float y = se.values[1];
float z = se.values[2];
mAccelLast = mAccelCurrent;
mAccelCurrent = (float) FloatMath.sqrt(x*x + y*y + z*z);
float delta = mAccelCurrent - mAccelLast;
mAccel = mAccel * 0.9f + delta;
if(mAccel > SHAKE_LIMIT)
listener.onShake();
else if(mAccel > LITTLE_SHAKE_LIMIT)
listener.onLittleShake();
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
}
我正在为我的大学项目开发一个运动检测和震动检测应用程序。
除了应用程序的原始目标之外,我还从应用程序中分离了库部分(负责运动和震动检测)。该代码是免费的,可在SourceForge上获得,项目名称为“BenderCatch”。我正在制作的文件将在9月中旬左右准备好。 http://sf.net/projects/bendercatch
它使用了一种更精确的方法来检测震动:当你执行震动时,既观察SensorEvents之间的力差,也观察X轴和Y轴上的振动。它甚至可以在每次震动时发出声音(或振动)。
欢迎通过电子邮件raffaele [at] terzigno [dot] com向我询问更多信息
我写了一个检测垂直和水平震动并显示Toast的小例子。
public class Accelerometerka2Activity extends Activity implements SensorEventListener {
private float mLastX, mLastY, mLastZ;
private boolean mInitialized;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private final float NOISE = (float) 8.0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mInitialized = false;
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer , SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// can be safely ignored for this demo
}
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
if (!mInitialized) {
mLastX = x;
mLastY = y;
mLastZ = z;
mInitialized = true;
} else {
float deltaX = Math.abs(mLastX - x);
float deltaY = Math.abs(mLastY - y);
float deltaZ = Math.abs(mLastZ - z);
if (deltaX < NOISE) deltaX = (float)0.0;
if (deltaY < NOISE) deltaY = (float)0.0;
if (deltaZ < NOISE) deltaZ = (float)0.0;
mLastX = x;
mLastY = y;
mLastZ = z;
if (deltaX > deltaY) {
Toast.makeText(getBaseContext(), "Horizental", Toast.LENGTH_SHORT).show();
} else if (deltaY > deltaX) {
Toast.makeText(getBaseContext(), "Vertical", Toast.LENGTH_SHORT).show();
}
}
}
}
你可能想试试开源tinybus。有了它,震动检测就像这样简单。
public class MainActivity extends Activity {
private Bus mBus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// Create a bus and attach it to activity
mBus = TinyBus.from(this).wire(new ShakeEventWire());
}
@Subscribe
public void onShakeEvent(ShakeEvent event) {
Toast.makeText(this, "Device has been shaken",
Toast.LENGTH_SHORT).show();
}
@Override
protected void onStart() {
super.onStart();
mBus.register(this);
}
@Override
protected void onStop() {
mBus.unregister(this);
super.onStop();
}
}
它采用地震仪进行振动检测。