版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
这里做了一个指南针,主要用到了Android里的
加速度传感器
和地磁传感器
Github源码
1.数据初始化
private USensor(Context context) {
if (sorMgr == null) {
//传感器管理
sorMgr = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
//加速度传感器
Sensor accelerometer = sorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//地磁传感器
Sensor magnetic = sorMgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
//注册监听
sorMgr.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
sorMgr.registerListener(this, magnetic, SensorManager.SENSOR_DELAY_GAME);
}
}
2.实时系统监听回调并计算
public class USensor implements SensorEventListener
private static final int sensitivity = 6;//变化灵敏度,数值越小,变化月灵敏
....
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
accelerometerValues = event.values;
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magneticFieldValues = event.values;
}
float degree = calculateOrientation();
if (Math.abs(degree - olDegree) > sensitivity) {
if (listener != null) {
ULog.commonD(" --> " + degree);
listener.onDegree(olDegree, degree);
}
}
olDegree = degree;
}
/**
* @return 计算偏移量
*/
private float calculateOrientation() {
float[] values = new float[3];
float[] R = new float[9];
SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticFieldValues);
SensorManager.getOrientation(R, values);
values[0] = (float) Math.toDegrees(values[0]);
return -values[0];
}
3.使用示例
这里注意不要把
new动画对象
丢到传感器监听里
private USensor sensor;//传感器管理类
@Override
protected void onResume() {
sensor = USensor.instance(this);
//使用属性动画旋转指针View
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.addUpdateListener(animation -> {
float degree = (float) animation.getAnimatedValue();
VCompass.setRotation(degree);
});
//传感器处理后的旋转度数
sensor.setDegreeListener((olDegree, degree) -> {
valueAnimator.setFloatValues(olDegree, degree);
valueAnimator.setDuration(100).start();
});
super.onResume();
}
@Override
protected void onPause() {
if (sensor != null) {
sensor.clear();
}
super.onPause();
}