其实在上次完善了指南针程序后基本上就算是完事了,目前商标状态均为申请注册中。日前,但是呢其实对于使用Sensor.TYPE_ORIENTATION注册方向来说其实这个在官方文档里面从api15就废弃了,有媒体报道,虽然还能用就是,字节内在一款元宇宙社交产品“Pixsoul”。举报/反馈,但是新的api据说是可以获取到更精准的数据
android给我们提供的方向数据是一个float型的数组,包含三个方向的值 如图
那么这里就对接下官方的这个推荐接口来实现下指南针逻辑,那么其它都不动,还是只修改下逻辑层,则如MainActivity.java:
packagecom.exle.pointer;
importandroidx.appcompat.app.AppCompatActivity;
importandroid.content.Context;
importandroid.hardware.Sensor;
importandroid.hardware.SensorEvent;
importandroid.hardware.SensorEventListener;
importandroid.hardware.SensorManager;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.view.animation.Animation;
importandroid.view.animation.RotateAnimation;
importandroid.widget.ImageView;
importandroid.widget.TextView;
public classMainActivityextendsAppCompatActivity {
privateImageViewiv;
TextViewtv;
floatpredegree=;
privateSensorManagersm;
//需要两个Sensor
privateSensoraSensor;
privateSensormSensor;
float[]accelerometerValues=new float[3];
float[]magneticFieldValues=new float[3];
private static finalStringTAG="sensor";
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv= (TextView)this.findViewById(R.id.textView);
iv= (ImageView)this.findViewById(R.id.iv);
}
@Override
//Activity第一次创建时或重新加载实例时调用
protected voidonResume() {
sm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
//加速度传感器
aSensor=sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//地磁传感器
mSensor=sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sm.registerListener(myListener,aSensor,SensorManager.SENSOR_DELAY_GAME);
sm.registerListener(myListener,mSensor,SensorManager.SENSOR_DELAY_GAME);
//更新显示数据的方法
calculateOrientation();
super.onResume();
}
@Override
protected voidonPause() {
sm.unregisterListener(myListener);//注消传感器
super.onPause();
}
finalSensorEventListenermyListener=newSensorEventListener() {
public voidonSensorChanged(SensorEvent sensorEvent){
if(sensorEvent.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD) {magneticFieldValues=sensorEvent.values;}
if(sensorEvent.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
accelerometerValues=sensorEvent.values;
}
calculateOrientation();
}
public voidonAccuracyChanged(Sensor sensor,intaccuracy){}
};
private voidcalculateOrientation() {
float[] values=new float[3];
float[] R =new float[9];
SensorManager.getRotationMatrix(R,null,accelerometerValues,magneticFieldValues);
SensorManager.getOrientation(R,values);
//要经过一次数据格式的转换,转换为度
values[]=(float) Math.toDegrees(values[]);
Log.i(TAG,values[]+"");
if(values[] >= -5&& values[]
Log.i(TAG,"正北");
}
else if(values[] >=5&& values[]
Log.i(TAG,"东北");
}else if(values[] >=85&& values[]
Log.i(TAG,"正东");
}else if(values[] >=95&& values[]
Log.i(TAG,"东南");
}else if((values[]>=175&& values[]= -180&& values[]
Log.i(TAG,"正南");
}
else if(values[] >=-175&& values[]
Log.i(TAG,"西南");
}
else if(values[] >= -95&& values[]
Log.i(TAG,"正西");}
else if(values[] >= -85&& values[]
Log.i(TAG,"西北");
}
/*
* values[0]:
表示Z轴的角度:方向角,我们平时判断的东西南北就是看这个数据的,经过我的实验,发现了一个有意思的事情.
也就是说使用第一种方式获得方向(磁场+加速度)得到的数据范围是(-180~180),也就是说,表示正北,90表示正东,180/-180表示正南,-90表示正西。
而第二种方式(直接通过方向感应器)数据范围是(~360)360/0表示正北,90表示正东,180表示正南,270表示正西。
values[1]:表示X轴的角度:俯仰角即由静止状态开始,前后翻转
values[2]:表示Y轴的角度:翻转角即由静止状态开始,左右翻转
* */
String orientationSensorLog="Orientation Sensor: "+ values[] +", "+ values[1] +", "+ values[2];
tv.setText(orientationSensorLog);
System.out.println(orientationSensorLog);
floatxoz=values[];
RotateAnimation ra =newRotateAnimation(predegree, -xoz, Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f);
ra.setDuration(500);
ra.setFillAfter(true);
iv.startAnimation(ra);
predegree=xoz;
}
}
然后实现的效果如
随后进行和内置的一些指南针应用来对比的时候,发现咱们这个会出现方向是反的,但是其实吧,我感觉这个主要是因为一些内置的指南针应用都有一个校准的过程,指南针应该和百度地图、谷歌地图等差不多,都会有偏差。但是完全相反,这个偏差就有点,所以还怀疑应该是因为我们的应用没有以正式版而是以版安装的,查看了一些资料,好像是说版和正式版有相反的问题。
免责声明:文中图片均来源于网络,如有版权问题请联系我们进行删除!