Now that SENSOR_ORIENTATION is deprecated, what's the best practice for obtaining compass heading? The old way was so simple.
Check you are away from any magnetic interference The compass sensors are very sensitive to interference. Make sure you are holding your device away from any electric cables/magnetic objects. Also check you don't have a magnet on your case as this can interfere with the sensors.
Does your Android phone have a magnetometer? Yup, chances are that it does as most Android devices do. Even if you have an old or a cheap phone, there's likely a magnetometer inside of it. And, there are a lot of apps out there that make use of that magnetometer to display a digital compass on your phone's screen.
The following is a basic example that obtains the compass heading and displays it in a TextView. It does so by implementing the SensorEventListener interface. You may change the rate at which events are delivered to the system by changing the constant in the following line of code (i.e. "mSensorManager.registerListener(this, mCompass, SensorManager.SENSOR_DELAY_NORMAL);") (see the OnResume() event); however, the setting is only a suggestion to the system. This example also uses the onReuse() and onPause() methods to preserve battery life by registering and unregistering the Listener when not in use. Hope this helps.
package edu.uw.android.thorm.wayfinder;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;
public class CSensorActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mCompass;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layoutsensor);
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mCompass = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
mTextView = (TextView) findViewById(R.id.tvSensor);
}
// The following method is required by the SensorEventListener interface;
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
// The following method is required by the SensorEventListener interface;
// Hook this event to process updates;
public void onSensorChanged(SensorEvent event) {
float azimuth = Math.round(event.values[0]);
// The other values provided are:
// float pitch = event.values[1];
// float roll = event.values[2];
mTextView.setText("Azimuth: " + Float.toString(azimuth));
}
@Override
protected void onPause() {
// Unregister the listener on the onPause() event to preserve battery life;
super.onPause();
mSensorManager.unregisterListener(this);
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mCompass, SensorManager.SENSOR_DELAY_NORMAL);
}
}
The following is the associated XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tvSensor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
SensorManager.getOrientation(float[] R, float[] values) is the standard API call to use since API level 3.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With