15

Sensor.TYPE_ORIENTATION用来确定设备的当前角度,但在API 版本 8TYPE_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()函数感到困惑,谁能告诉我一个如何获得角度的例子?

4

4 回答 4

34

您现在使用两个传感器(ACCELEROMETER 和 MAGNETIC_FIELD)来获取该信息。有关更多详细信息,请参阅博客文章。

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"/>
于 2013-12-02T23:45:45.667 回答
4

关于你的第二个问题。注册传感器侦听器时,将代码更改为:

protected void onResume() {          
    super.onResume();          
    mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);          
    mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_NORMAL);          
}
于 2014-12-23T18:11:13.477 回答
1

Google 在其 google-developer-training 系列中提供了一个很棒的定向演示应用程序,称为TiltSpot。因为它有一个 Apache 许可证,所以我冒昧地将它变成了一个名为johnnylambada-orientation的小型库,它使获取方向变得很简单,将其添加到您的活动中:

        getLifecycle().addObserver(new OrientationReporter(this, (a, p, r) -> {
            Log.i("orientation","a="+a+" p="+p+" r="+r);
        }));
于 2019-12-20T00:55:06.587 回答
1

我的答案是为那些获得跳跃值的人准备的。如需进一步说明,请在评论中告诉我。

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

暂停()

@Override
protected void onPause() {
    super.onPause();
    mSensorManager.unregisterListener(MapsActivity.this);
}
于 2021-06-29T05:14:53.383 回答