Ok here's how I think it should be done a year later. Please correct me if you spot any issues.
Most of the following code deals with a discrepancy between coordinate systems. I'm using a rotation vector sensor. From the docs: Y is tangential to the ground at the device's current location and points towards magnetic north.
Bearing in google maps, on the other hand, seems to point to true north. this page shows how the conversion is done
1) get the current declination from your current GPS location
@Override
public void onLocationChanged(Location location) {
GeomagneticField field = new GeomagneticField(
(float)location.getLatitude(),
(float)location.getLongitude(),
(float)location.getAltitude(),
System.currentTimeMillis()
);
// getDeclination returns degrees
mDeclination = field.getDeclination();
}
2) calculate bearing from declination and magnetic north
@Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
SensorManager.getRotationMatrixFromVector(
mRotationMatrix , event.values);
float[] orientation = new float[3];
SensorManager.getOrientation(mRotationMatrix, orientation);
float bearing = Math.toDegrees(orientation[0]) + mDeclination;
updateCamera(bearing);
}
}
3) update maps
private void updateCamera(float bearing) {
CameraPosition oldPos = mMap.getCameraPosition();
CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing).build();
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos));
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…