踩坑记录
这个工具类里有两个独立的监听
1.先贴代码
1.使用示例
1.实例化
UGravity gravity = new UGravity(this);
//监听手机方向
gravity.setOrientationListener(orientation -> {
//do sth
});
//监听手机摇晃
gravity.setOnShakeListener(() -> {
//do sth
});
2.用完清理
@Override
protected void onDestroy() {
gravity.clear();
super.onDestroy();
}
2.工具类源码
原理是使用Android的重力传感器返回值来判断
/**
* @Description: 重力监听
* @Author: Kosmos
* @Date: 2019.01.28 11:56
* @Email: KosmoSakura@gmail.com
* 1.摇晃手机
* 2.屏幕旋转
*/
public class UGravity implements SensorEventListener {
private static final int SPEED_SHRESHOLD = 2000;// 速度阈值
private static final int UPTATE_INTERVAL_TIME = 200;// 检测的时间间隔
private SensorManager sorMgr;// 传感器管理器
private OnShakeListener onShakeListener;//摇晃监听器
private OrientationListener orientationListener;旋转监听器
private long lastUpdateTime;//上次检测时间
// 手机上一个位置时重力感应坐标
private float lastX;
private float lastY;
private float lastZ;
// 构造器
public UGravity(Context context) {
sorMgr = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
// 注册
if (sorMgr != null) {
sorMgr.registerListener(this,
sorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
}
}
// 摇晃监听接口
public interface OnShakeListener {
void onShake();
}
// 旋转监听接口
public interface OrientationListener {
void orientation(int orientation);
}
// 设置摇晃监听
public void setOnShakeListener(OnShakeListener listener) {
onShakeListener = listener;
}
// 设置旋转监听
public void setOrientationListener(OrientationListener orientationListener) {
this.orientationListener = orientationListener;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/*
* 重力感应器感应获得变化数据
*/
@Override
public void onSensorChanged(SensorEvent event) {
//返回的不是重力传感信号
if (Sensor.TYPE_ACCELEROMETER != event.sensor.getType()) {
return;
}
// 检测时间必须大于间隔时间
long currentUpdateTime = System.currentTimeMillis();
long timeInterval = currentUpdateTime - lastUpdateTime;//时间间隔
if (timeInterval < UPTATE_INTERVAL_TIME) {
return;
}
// 保存
lastUpdateTime = currentUpdateTime;
// 获得x,y,z坐标
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
//摇晃监听
if (onShakeListener != null) {
// 获得x,y,z的变化值
float deltaX = x - lastX;
float deltaY = y - lastY;
float deltaZ = z - lastZ;
// 将现在的坐标变成last坐标
lastX = x;
lastY = y;
lastZ = z;
double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / timeInterval * 10000;
// 达到阀值
if (speed >= SPEED_SHRESHOLD) {
onShakeListener.onShake();
}
}
//旋转监听
if (orientationListener != null) {
//理论上临界值应为4.5,但是实际效果有所偏差,值为6时效果最佳
if (x < 6 && x > -6 && y > 6) {
//竖屏:x∈(-4.5,4.5),y∈(4.5,+∞)
orientationListener.orientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else if (x < 6 && x > -6 && y < -6) {
//竖屏反转:x∈(-4.5,4.5),y∈(-∞,-4.5)
orientationListener.orientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} else if (y > -6 && y < 6 && x > 6) {
//横屏:x∈(4.5,+∞),y∈(-4.5,4.5)
orientationListener.orientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
//横屏反转:x∈(-∞,-4.5),y∈(-4.5,4.5)
orientationListener.orientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
}
}
/**
* 资源清理,注销监听
*/
public void clear() {
if (sorMgr != null) {
sorMgr.unregisterListener(this);
sorMgr = null;
}
if (onShakeListener != null) {
onShakeListener = null;
}
if (orientationListener != null) {
orientationListener = null;
}
}
}