Now that SENSOR_ORIENTATION is deprecated, what's the best practice for obtaining compass heading? The old way was so simple.
2 Answers
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>

- 113
- 1
- 3
-
4Is this not still using the deprecated Orientation sensor which the OP referred to? – Tim Feb 25 '13 at 16:14
SensorManager.getOrientation(float[] R, float[] values) is the standard API call to use since API level 3.

- 14,812
- 25
- 102
- 140
-
Yeah, I found that in the documentation. Two more questions: what do you initialize R and values to? Also, is there a way to get notifications, or is that whole working model deprecated? – Edward Falk Aug 19 '10 at 03:44
-
2OK, found a good example in the source base. I won't copy it here, but if you browse the git repository for Android, look at the end of development/samples/Compass/src/com/example/android/compass/CompassActivity.java – Edward Falk Aug 19 '10 at 15:54
-
1Notifications/events is a poor way to do sensors, which is why it's deprectated afaik. Every minor aspect change would trigger a multitude of events, essentially choking the UI thread with data. – CodeFusionMobile Aug 20 '10 at 14:08
-
@CodeFusionMobile What you say makes sense, but this is not yet very well implemented in the framework: to get the appropriate matrices to call `getOrientation(...)`, you need to register to both `Sensor.TYPE_ACCELEROMETER` and `Sensor.TYPE_MAGNETIC_FIELD` events... or at least that's what is shown in the sample code provided above. That makes two sensors to register to instead of one! – JM Lord Mar 23 '18 at 14:09