使用getOrientation()函数获取设备角度

时间:2013-12-02 23:25:59

标签: android orientation sensor android-sensors sensormanager

我使用Sensor.TYPE_ORIENTATION来确定设备的当前角度,但 API版本8 上已弃用TYPE_ORIENTATION。在SensorManager手册中,它引用getOrientation()函数以使用TYPE_ORIENTATION

Here is the manual


这是我的旧代码:

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()功能感到很困惑,有谁能告诉我一个如何获得角度的例子?

4 个答案:

答案 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);
}