我需要添加一个摇功能,将刷新我的Android应用程序。
我所找到的所有文档都涉及实现SensorListener,但Eclipse告诉我它已被弃用,并建议使用SensorEventListener。
有人知道如何创建这个震动控制器吗?
我需要添加一个摇功能,将刷新我的Android应用程序。
我所找到的所有文档都涉及实现SensorListener,但Eclipse告诉我它已被弃用,并建议使用SensorEventListener。
有人知道如何创建这个震动控制器吗?
当前回答
你可能想试试开源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();
}
}
它采用地震仪进行振动检测。
其他回答
和我一起工作,很好 参考
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) {}
}
我真的很喜欢彼得dk的回答。我自作主张对他的代码做了一些调整。
文件:ShakeDetector.java
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.FloatMath;
public class ShakeDetector implements SensorEventListener {
// The gForce that is necessary to register as shake. Must be greater than 1G (one earth gravity unit)
private static final float SHAKE_THRESHOLD_GRAVITY = 2.7F;
private static final int SHAKE_SLOP_TIME_MS = 500;
private static final int SHAKE_COUNT_RESET_TIME_MS = 3000;
private OnShakeListener mListener;
private long mShakeTimestamp;
private int mShakeCount;
public void setOnShakeListener(OnShakeListener listener) {
this.mListener = listener;
}
public interface OnShakeListener {
public void onShake(int count);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// ignore
}
@Override
public void onSensorChanged(SensorEvent event) {
if (mListener != null) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float gX = x / SensorManager.GRAVITY_EARTH;
float gY = y / SensorManager.GRAVITY_EARTH;
float gZ = z / SensorManager.GRAVITY_EARTH;
// gForce will be close to 1 when there is no movement.
float gForce = FloatMath.sqrt(gX * gX + gY * gY + gZ * gZ);
if (gForce > SHAKE_THRESHOLD_GRAVITY) {
final long now = System.currentTimeMillis();
// ignore shake events too close to each other (500ms)
if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now ) {
return;
}
// reset the shake count after 3 seconds of no shakes
if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now ) {
mShakeCount = 0;
}
mShakeTimestamp = now;
mShakeCount++;
mListener.onShake(mShakeCount);
}
}
}
}
另外,不要忘记需要向SensorManager注册一个ShakeDetector实例。
// ShakeDetector initialization
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mShakeDetector = new ShakeDetector();
mShakeDetector.setOnShakeListener(new OnShakeListener() {
@Override
public void onShake(int count) {
handleShakeEvent(count);
}
});
mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
下面是另一个代码:
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
public class AccelerometerListener implements SensorEventListener {
private SensorManager sensorManager;
private List<Sensor> sensors;
private Sensor sensor;
private long lastUpdate = -1;
private long currentTime = -1;
private Main parent;
private Timer timer;
private int shakes;
private static final Handler mHandler = new Handler();
private float last_x, last_y, last_z;
private float current_x, current_y, current_z, currenForce;
private static final int FORCE_THRESHOLD = 500;
private final int DATA_X = SensorManager.DATA_X;
private final int DATA_Y = SensorManager.DATA_Y;
private final int DATA_Z = SensorManager.DATA_Z;
public AccelerometerListener(Main parent) {
SensorManager sensorService = (SensorManager) parent
.getSystemService(Context.SENSOR_SERVICE);
this.sensorManager = sensorService;
if (sensorService == null)
return;
this.sensors = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if (sensors.size() > 0) {
sensor = sensors.get(0);
}
this.parent = parent;
}
public void start() {
if (sensor == null)
return;
sensorManager.registerListener(this, sensor,
SensorManager.SENSOR_DELAY_GAME);
}
public void stop() {
if (sensorManager == null)
return;
sensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor s, int valu) {
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return;
currentTime = System.currentTimeMillis();
if ((currentTime - lastUpdate) > 50) {
long diffTime = (currentTime - lastUpdate);
lastUpdate = currentTime;
current_x = event.values[DATA_X];
current_y = event.values[DATA_Y];
current_z = event.values[DATA_Z];
currenForce = Math.abs(current_x + current_y + current_z - last_x
- last_y - last_z)
/ diffTime * 10000;
if (currenForce > FORCE_THRESHOLD) {
shakeDetected();
}
last_x = current_x;
last_y = current_y;
last_z = current_z;
}
}
private void shakeDetected() {
shakes++;
if (shakes == 1) {
if (timer != null) {
timer.cancel();
}
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (shakes > 3) {
mHandler.post(new Runnable() {
public void run() {
// shake
}
});
}
shakes = 0;
}
}, 500);
}
}
}
package com.example.shakingapp;
import android.app.Activity;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager sensorManager;
private boolean color = false;
private View view;
private long lastUpdate;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = findViewById(R.id.textView);
view.setBackgroundColor(Color.GREEN);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
lastUpdate = System.currentTimeMillis();
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
getAccelerometer(event);
}
}
private void getAccelerometer(SensorEvent event) {
float[] values = event.values;
// Movement
float x = values[0];
float y = values[1];
float z = values[2];
System.out.println(x);
System.out.println(y);
System.out.println(z);
System.out.println(SensorManager.GRAVITY_EARTH );
float accelationSquareRoot = (x * x + y * y + z * z)
/ (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
long actualTime = System.currentTimeMillis();
if (accelationSquareRoot >= 2) //
{
if (actualTime - lastUpdate < 200) {
return;
}
lastUpdate = actualTime;
Toast.makeText(this, "Device was shuffed "+accelationSquareRoot, Toast.LENGTH_SHORT)
.show();
if (color) {
view.setBackgroundColor(Color.GREEN);
} else {
view.setBackgroundColor(Color.RED);
}
color = !color;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
protected void onResume() {
super.onResume();
// register this class as a listener for the orientation and
// accelerometer sensors
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
// unregister listener
super.onPause();
sensorManager.unregisterListener(this);
}
}
您应该订阅SensorEventListener,并获取加速度计数据。 一旦你有了它,你应该监测在某个轴上加速度方向(符号)的突然变化。这将是一个很好的指示“摇动”移动的设备。