手机传感器辅助类
程序员文章站
2022-04-19 10:22:04
...
SensorUtil.java
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Message;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
import java.util.ArrayList;
import java.util.List;
/**
* 传感器管理
*/
public class SensorUtil {
private static SensorUtil instance = null;
public static SensorUtil getInstance() {
if (instance == null) {
synchronized (SensorUtil.class) {
if (instance == null) {
instance = new SensorUtil();
}
}
}
return instance;
}
public static SensorUtil newInstance(Context activityContext) {
SensorUtil sensorUtil = new SensorUtil();
sensorUtil.init(activityContext);
return sensorUtil;
}
private SensorUtil() {
}
/**
* 窗体的context
*/
private Context context = null;
/**
* 传感器服务
*/
private SensorManager sensorManager = null;
/**
* 传感器:加速度
*/
private float[] gravity = null;
/**
* 传感器:环境磁场
*/
private float[] geomagnetic = null;
/**
* 屏幕方向
*/
private int surfaceRotation = Surface.ROTATION_0;
/**
* 手机屏幕方向
*/
private int axisX = SensorManager.AXIS_Y;
/**
* 手机屏幕方向
*/
private int axisY = SensorManager.AXIS_X;
/**
* 方位角(0~360)
* 手机围绕Z轴旋转,正北方向为0度,顺时针旋转,方位角从0到360度变化,正北0度、正东90度,正南180度,正西270度。
*/
private float orientation = -1;
/**
* 横滚角(-90~90)
* 当手机zy轴所在的平面与地面垂直时,此时横滚角是0度,手机围绕y轴旋转,若顺时针旋转,横滚角从0到90度变化。如果逆时针旋转,横滚角从0到-90度变化。
*/
private float roll = -1;
/**
* 俯仰角(-90~90)
* 当手机xy轴所在的平面与地面平行时,此时俯仰角是0度,当手机围绕x轴旋转,且顶部离你越来越远,底部离你越来越近时(此时可以理解成,手机逐渐朝着地面拍摄),俯仰角从0到-90度变化;如果顶部离你越来越近,底部离你越来越远时(此时可以理解成,手机逐渐朝着天空拍摄),俯仰角从0到90度变化
*/
private float tilt = -1;
private List<SensorListener> sensorListeners = new ArrayList<>();
/**
* 初始化
* @param activityContext Activity上下文
*/
public void init(Context activityContext) {
if (activityContext == null) {
return;
}
this.context = activityContext;
sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL);
}
/**
* 资源释放
*/
public void release() {
if (sensorManager != null) {
sensorManager.unregisterListener(sensorEventListener);
sensorManager = null;
gravity = null;
geomagnetic = null;
}
}
/**
* 添加传感器监听
* @param listener 监听事件
*/
public void addSensorListener(SensorListener listener) {
if (listener == null) {
return;
}
if (sensorListeners != null && sensorListeners.contains(listener) == false) {
sensorListeners.add(listener);
}
if (orientation >= 0) {
listener.updateOrientation(surfaceRotation, orientation, roll, tilt);
}
if (gravity != null) {
listener.updateGravity(gravity);
}
if (geomagnetic != null) {
listener.updateGeomagnetic(geomagnetic);
}
}
/**
* 移除监听事件
*/
public void removeSensorListener(SensorListener listener) {
if (listener == null) {
return;
}
if (sensorListeners != null && sensorListeners.contains(listener)) {
sensorListeners.remove(listener);
}
}
/**
* 清空监听事件
*/
public void clearSensorListener() {
sensorListeners.clear();
}
/**
* 兼容横竖屏
*/
private void updateCoordinate() {
WindowManager windowManager = ((Activity)context).getWindowManager();
Display display = windowManager.getDefaultDisplay();
surfaceRotation = display.getRotation();
switch (surfaceRotation) {
// 正向竖屏
case Surface.ROTATION_0:
axisX = SensorManager.AXIS_Y;
axisY = SensorManager.AXIS_X;
break;
// 正向横屏
case Surface.ROTATION_90:
axisX = SensorManager.AXIS_X;
axisY = SensorManager.AXIS_Y;
break;
case Surface.ROTATION_180:
break;
case Surface.ROTATION_270:
break;
default:
break;
}
}
/**
* 传感器监听
*/
private SensorEventListener sensorEventListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
// 加速度传感器
case Sensor.TYPE_ACCELEROMETER:
gravity = event.values;
handler.sendEmptyMessage(0);
sensorListeners.forEach(listener -> listener.updateGravity(gravity));
break;
// 磁场传感器
case Sensor.TYPE_MAGNETIC_FIELD:
geomagnetic = event.values;
handler.sendEmptyMessage(0);
sensorListeners.forEach(listener -> listener.updateGeomagnetic(geomagnetic));
break;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if(gravity != null && geomagnetic != null) {
float[] inR = new float[9];
if(SensorManager.getRotationMatrix(inR, null, gravity, geomagnetic)) {
updateCoordinate();
float[] outR = new float[9];
SensorManager.remapCoordinateSystem(inR, axisX, axisY, outR);
float[] values = new float[3];
SensorManager.getOrientation(outR, values);
orientation = (float) ((360f + Math.toDegrees(values[0])) % 360);
tilt = (float) Math.toDegrees(values[1]);
roll = (float) Math.toDegrees(values[2]);
float tempTilt = 0;
if (axisX == SensorManager.AXIS_X) {
// 横屏
if (orientation < 270 && orientation >=0) {
orientation += 90;
} else {
orientation -= 270;
}
tempTilt = tilt;
tilt = Math.abs(roll) - 90;
roll = -tempTilt;
} else {
// 竖屏
if (orientation < 90 && orientation >= 0) {
orientation += 270;
} else {
orientation -= 90;
}
tempTilt = tilt;
tilt = Math.abs(roll) - 90;
roll = tempTilt;
}
sensorListeners.forEach(listener -> listener.updateOrientation(surfaceRotation, orientation, roll, tilt));
}
}
}
};
/**
* 传感器监听事件
*/
public interface SensorListener {
void updateOrientation(int surfaceRotation, float orientation, float roll, float tilt);
void updateGravity(float[] gravity);
void updateGeomagnetic(float[] geomagnetic);
}
/**
* 传感器监听事件的抽象类
*/
public abstract static class AbstractSensorValue implements SensorListener{
@Override
public void updateOrientation(int surfaceRotation, float orientation, float roll, float tilt) {
}
@Override
public void updateGravity(float[] gravity) {
}
@Override
public void updateGeomagnetic(float[] geomagnetic) {
}
}
}
调用方法
private SensorUtil sensorUtil;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sensorUtil = SensorUtil.newInstance(this);
sensorUtil.addSensorListener(new SensorUtil.AbstractSensorValue() {
@Override
public void updateOrientation(int surfaceRotation, float orientation, float roll, float tilt) {
switch (surfaceRotation) {
case Surface.ROTATION_0:
dataBinding.tvScreenOrientation.setText("正向竖屏");
break;
case Surface.ROTATION_90:
dataBinding.tvScreenOrientation.setText("正向横屏");
break;
case Surface.ROTATION_180:
dataBinding.tvScreenOrientation.setText("反向竖屏");
break;
case Surface.ROTATION_270:
dataBinding.tvScreenOrientation.setText("反向横屏");
break;
}
dataBinding.tvOrientation.setText(String.valueOf(orientation));
dataBinding.tvRoll.setText(String.valueOf(roll));
dataBinding.tvTilt.setText(String.valueOf(tilt));
}
@Override
public void updateGravity(float[] gravity) {
String result = "[";
if (gravity != null && gravity.length > 0) {
for (int i = 0; i < gravity.length; i++) {
if (i < gravity.length - 1) {
result += gravity[i] + ", ";
} else {
result += String.valueOf(gravity[i]);
}
}
}
result += "]";
dataBinding.tvGravity.setText(result);
}
@Override
public void updateGeomagnetic(float[] geomagnetic) {
String result = "[";
if (geomagnetic != null && geomagnetic.length > 0) {
for (int i = 0; i < geomagnetic.length; i++) {
if (i < geomagnetic.length - 1) {
result += geomagnetic[i] + ", ";
} else {
result += String.valueOf(geomagnetic[i]);
}
}
}
result += "]";
dataBinding.tvGeomagnetic.setText(result);
}
});
}
@Override
protected void onDestroy() {
sensorUtil.clearSensorListener();
sensorUtil.release();
sensorUtil = null;
super.onDestroy();
}
测试效果
上一篇: docker学习笔记