Android phone orientation overview including compass
You might want to check out the One Screen Turn Deserves Another article. It explains why you need the rotation matrix.
In a nutshell, the phone's sensors always use the same coordinate system, even when the device is rotated.
In applications that are not locked to a single orientation, the screen coordinate system changes when you rotate the device. Thus, when the device is rotated from its default view mode, the sensor coordinate system is no longer the same as the screen coordinate system. The rotation matrix in this case is used to transform A to C (B always remains fixed).
Here's a code snippet to show you how it can be used.
SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
// Register this class as a listener for the accelerometer sensor
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
// ...and the orientation sensor
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_NORMAL);
//...
// The following code inside a class implementing a SensorEventListener
// ...
float[] inR = new float[16];
float[] I = new float[16];
float[] gravity = new float[3];
float[] geomag = new float[3];
float[] orientVals = new float[3];
double azimuth = 0;
double pitch = 0;
double roll = 0;
public void onSensorChanged(SensorEvent sensorEvent) {
// If the sensor data is unreliable return
if (sensorEvent.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
return;
// Gets the value of the sensor that has been changed
switch (sensorEvent.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
gravity = sensorEvent.values.clone();
break;
case Sensor.TYPE_MAGNETIC_FIELD:
geomag = sensorEvent.values.clone();
break;
}
// If gravity and geomag have values then find rotation matrix
if (gravity != null && geomag != null) {
// checks that the rotation matrix is found
boolean success = SensorManager.getRotationMatrix(inR, I,
gravity, geomag);
if (success) {
SensorManager.getOrientation(inR, orientVals);
azimuth = Math.toDegrees(orientVals[0]);
pitch = Math.toDegrees(orientVals[1]);
roll = Math.toDegrees(orientVals[2]);
}
}
}
osmdroid get orientation from Compass [How to]
You can use internal compass of the device and use SensorListener in android. Then use MapOrientation method to rotate the osmmap.
Some snippet:
mSensorManager.registerListener(mySensorEventListener,
SensorManager.SENSOR_ORIENTATION,
SensorManager.SENSOR_DELAY_UI);
public SensorListener mySensorEventListener = new SensorListener(){
@Override
public void onSensorChanged(int sensor, float[] values) {
synchronized (this) {
float mHeading = values[0];
mOSMView.setMapOrientation(-mHeading);
}
}
};
Android using RotateAnimation pointing towards a specific location
I did some further tests and realized that the range from the bearing and the azimuth angles are each (0...180,-180...0) going clockwise and starting from 0, whereas the RotateAnimation takes angles from 0...360 clockwise. Therefore I just converted the azimuth and bearing angles by adding 360 if they were smaller than 0 before I proceeded in the calculations.
Related Topics
App-Release-Unsigned.Apk Is Not Signed
How to Extract Code of .Apk File Which Is Not Working
Tab Not Taking Full Width on Tablet Device [Using Android.Support.Design.Widget.Tablayout]
Navigation Drawer to Switch Activities Instead of Fragments
Circular Reveal Transition for New Activity
Is Gui for Android Sdk Manager Gone
Starting Activity from Fragment Causes Nullpointerexception
Android Camera Android.Hardware.Camera Deprecated
Android Opengl Texture Compression
Nexus 7 Not Visible Over Usb via "Adb Devices" from Windows 7 X64
What Is the Correct Way to Specify Dimensions in Dip from Java Code
How to Get Toolbar from Fragment
How to Call Rest API from an Android App
Android Preferences: How to Load the Default Values When the User Hasn't Used the Preferences-Screen