我使用Sensor.TYPE_ORIENTATION
来确定设备的当前角度,但 API版本8 上已弃用TYPE_ORIENTATION
。在SensorManager手册中,它引用getOrientation()
函数以使用TYPE_ORIENTATION
。
这是我的旧代码:
public void onSensorChanged(SensorEvent event) {
Log.d("debug","Sensor Changed");
if (event.sensor.getType()==Sensor.TYPE_ORIENTATION) {
Log.d("debug",Float.toString(event.values[0]));
float mAzimuth = event.values[0];
float mPitch = event.values[1];
float mRoll = event.values[2];
Log.d("debug","mAzimuth :"+Float.toString(mAzimuth));
Log.d("debug","mPitch :"+Float.toString(mPitch));
Log.d("debug","mRoll :"+Float.toString(mRoll));
}
}
我对使用getOrientation()
功能感到很困惑,有谁能告诉我一个如何获得角度的例子?
答案 0 :(得分:25)
现在使用两个传感器(ACCELEROMETER和MAGNETIC_FIELD)来获取该信息。见blog post for more detail.
public class CompassActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
Sensor accelerometer;
Sensor magnetometer;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(mCustomDrawableView); // Register the sensor listeners
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
float[] mGravity;
float[] mGeomagnetic;
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
azimut = orientation[0]; // orientation contains: azimut, pitch and roll
}
}
}
}
权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
答案 1 :(得分:3)
关于你的第二个问题。注册传感器侦听器时,请将代码更改为:
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_NORMAL);
}
答案 2 :(得分:0)
Google在名为TiltSpot的google-developer-training系列中提供了一个不错的定向演示应用。因为它具有Apache许可证,所以我很自由地将其转换为一个名为johnnylambada-orientation的小型库,该库使定向变得很简单,将其添加到您的活动中即可。
getLifecycle().addObserver(new OrientationReporter(this, (a, p, r) -> {
Log.i("orientation","a="+a+" p="+p+" r="+r);
}));
答案 3 :(得分:0)
我的回答是针对那些获得跳跃头球值的人的。如需进一步说明,请在评论中告诉我。
Sensor accelerometer;
Sensor magnetometer;
private float[] mGravity = new float[3];
private float[] mGeomagnetic = new float[3];
private float[] Rv = new float[9];
private float[] I = new float[9];
类 MapsActivity
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, SensorEventListener{
onSensorChanged(SensorEvent 事件)
@Override
public void onSensorChanged(SensorEvent event) {
synchronized (this) {
float INITIAL_ALPHA = 0.97f;
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mGravity[0] = INITIAL_ALPHA * mGravity[0] + (1 - INITIAL_ALPHA)
* event.values[0];
mGravity[1] = INITIAL_ALPHA * mGravity[1] + (1 - INITIAL_ALPHA)
* event.values[1];
mGravity[2] = INITIAL_ALPHA * mGravity[2] + (1 - INITIAL_ALPHA)
* event.values[2];
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
mGeomagnetic[0] = INITIAL_ALPHA * mGeomagnetic[0] + (1 - INITIAL_ALPHA)
* event.values[0];
mGeomagnetic[1] = INITIAL_ALPHA * mGeomagnetic[1] + (1 - INITIAL_ALPHA)
* event.values[1];
mGeomagnetic[2] = INITIAL_ALPHA * mGeomagnetic[2] + (1 - INITIAL_ALPHA)
* event.values[2];
if (Math.abs(mGeomagnetic[2]) > Math.abs(mGeomagnetic[1])) {
magStrength = Math.round(Math.abs(mGeomagnetic[2]));
} else {
magStrength = Math.round(Math.abs(mGeomagnetic[1]));
}
}
boolean success = SensorManager.getRotationMatrix(Rv, I, mGravity, mGeomagnetic);
if (success) {
float[] orientation = new float[3];
SensorManager.getOrientation(Rv, orientation);
azimuth = (float) Math.toDegrees(orientation[0]);
azimuth = (azimuth + 360) % 360;
// Log.d(TAG, "azimuth (deg): " + azimuth);
float degree = Math.round(azimuth);
// create a rotation animation (reverse turn degree degrees)
RotateAnimation ra = new RotateAnimation(
currentDegree,
-degree,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF,
0.5f);
ra.setDuration(500);
ra.setFillAfter(true);
ra.setRepeatCount(0);
binding.compassImage.startAnimation(ra);
showDirection(degree);
currentDegree = -degree;
}
}
}
onAccuracyChanged
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
onResume()
@Override
protected void onResume() {
super.onResume();
if (mSensorManager == null) {
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometer =
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer =
mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
mSensorManager.registerListener(this, accelerometer,
SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, magnetometer,
SensorManager.SENSOR_DELAY_UI);
}
onPause()
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(MapsActivity.this);
}