Hi, Thanks for the explanation. It was very useful. I am trying to get 2 variables to store the lat/lon. Can we do that continuously? As in have 3 variables. One each for current azimuth, Lat and lon. What changes would we need to make in the code you provided here? implementing LocationListener along with the this listener should do I guess? But I tried and am unable to get both location and orientation at the 'same time'. thanks Ricky
On Jun 17, 9:56 am, lawrizy <lawr...@gmail.com> wrote: > Hi, > > I wanna thank you very much for your explanation. The official > documentation was very difficult to understand. And the example in the > api sample (the compass) does use a depreciated methods (with > sensorlistener). > > I don't understand what does remapCoordinateSystem and his parameters, > could you help? > > Thank you. > > On 16 juin, 06:28, "repDetect()" <n6mba50...@gmail.com> wrote: > > > Hi, > > While trying to retrieve orientation data I found some pretty straight > > forward code making use of SensorEventListener for > > Sensor.TYPE_ORIENTATION and it works fine, but the > > Sensor.TYPE_ORIENTATION constant has been deprecated recently - I > > believe it was on 8 (API level) - which I understand to mean that > > while I can still use it, I shouldn't. > > The documentation [1] only says "use SensorManager.getOrientation() > > instead." [2] but as a newbie, I had difficulties following that > > "detailed" instruction. > > > So the question is: > > How to properly get device orientation data? > > > In an attempt to make this discussion constructive, here is what I > > managed to figure out, hopefully it will attract corrections relevant > > to my limitations and not just general pointers to material I already > > read (and misunderstood) and perhaps also benefit other newbies > > struggling with this task. > > So please fix any misconceptions or errors you find below. > > > The most important thing to realize is that > > SensorManager.getOrientation() doesn't get the orientation from the > > sensors (as with SensorEvent for Sensor.TYPE_ORIENTATION), it merely > > "Computes the device's orientation based on the rotation matrix" which > > you must provide as the first parameter. > > In a similar fashion SensorManager.getRotationMatrix() doesn't read > > sensors data to produce the rotation matrix, it depends on you to > > provide the data through the third and forth arguments (gravity, > > geomagnetic), also note that the values of these arguments must be > > within expected limits or the method will fail. This holds in > > particular for the case where these are initialized to zeros, as this > > will imply free fall for gravity and something even more disturbing > > for geomagnetic. > > Don't take my word on it look it up for yourself in the source [3], > > for the Java end at list. > > > Once that was digested it appears the only way to get sensor data is > > through registering a sensor event listener (I thought it would be > > really nice if I could query the sensors's readings at will and that > > what I naively assumed was done by the get methods in SensorManager, > > could anyone comment why this is not made available?), then that data > > may be used to calculate the orientation as outlined below: > > > 1) Retrieve sensor data from accelerometer and magnetic field sensor > > as required by getRotationMatrix(): > > This actually involves a number of steps in the Activity class: > > 1.1) Obtain a sensor manager. > > NOTE: Context.getSystemService needs a Context, typically called > > within an Activity's context. > > mSensMan = (SensorManager) getSystemService(SENSOR_SERVICE); > > > 1.2) Register a sensor event listener for each of the above sensor > > types. > > mSensMan.registerListener(this, > > mSensMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), > > SensorManager.SENSOR_DELAY_UI); > > mSensMan.registerListener(this, > > mSensMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), > > SensorManager.SENSOR_DELAY_UI); > > > 1.3) In the listener's onSensorChanged method copy the data from the > > SensorEvent.values. > > NOTE: The data must be copied off the event.values as the system is > > reusing that array in all SensorEvents, simply assigning won't work. > > public void onSensorChanged(SensorEvent event) { > > switch (event.sensor.getType()) { > > case Sensor.TYPE_ACCELEROMETER: > > System.arraycopy(event.values, 0, mGravs, 0, 3); > > break; > > case Sensor.TYPE_MAGNETIC_FIELD: > > System.arraycopy(event.values, 0, mGeoMags, 0, 3); > > break; > > default: > > return; > > } > > > } > > > 2) Pass the copied sensor data as arrays to > > SensorManager.getRotationMatrix() to receive the rotation matrix. > > SensorManager.getRotationMatrix(mRotationM, null, mGravs, mGeoMags) > > > Optionally transform the returned rotation matrix through > > SensorManager.remapCoordinateSystem() or multiplying by a > > transformation matrix. > > > 3) Pass the rotation matrix to SensorManager.getOrientation() to > > receive the orientation as yaw, pitch and roll expressed in radians. > > SensorManager.getOrientation(mRotationM, mOrientation); > > > Voila. > > > Below the relevant code is wrapped with a complete Activity to allow > > for testing and to get the whole picture, once again - corrections and > > remarks are requested - the TODO: tags would also indicate areas where > > knowledge is lacking. > > > Please handle with care, this newbie is still a little wet and > > slippery! > > > [1]http://developer.android.com/reference/android/hardware/Sensor.html#T... > > [2]http://developer.android.com/reference/android/hardware/SensorManager...[],%20float[]%29 > > [3]http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;... > > > <<------------------------------------------------------------------------------------------------------------------------ > > > package my.odd.demo.orientation; > > > 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.view.ViewGroup.LayoutParams; > > import android.widget.TextView; > > > public class OrientationDemo extends Activity implements > > SensorEventListener { > > TextView mOrientationData; > > private SensorManager mSensMan; > > private float mAzimuth; > > private float[] mGravs = new float[3]; > > private float[] mGeoMags = new float[3]; > > private float[] mOrientation = new float[3]; > > private float[] mRotationM = new float[9]; // Use [16] > > to co-operate with android.opengl.Matrix > > private float[] mRemapedRotationM = new float[9]; > > private boolean mFailed; > > > /** Called when the activity is first created. */ > > @Override > > public void onCreate(Bundle savedInstanceState) { > > super.onCreate(savedInstanceState); > > > // I'd like to actually see something so let's have a view: > > mOrientationData = new TextView(this); > > setContentView(mOrientationData, new > > LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); > > > // Initiate the Sensor Manager and register this as Listener for > > the required sensor types: > > // TODO: Find how to get a SensorManager outside an Activity, to > > implement as a utility class. > > mSensMan = (SensorManager) getSystemService(SENSOR_SERVICE); > > mSensMan.registerListener(this, > > > > mSensMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), // > > Anonymous Sensors- no further use for them. > > SensorManager.SENSOR_DELAY_UI); > > mSensMan.registerListener(this, > > mSensMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), > > SensorManager.SENSOR_DELAY_UI); > > } > > > @Override > > public void onAccuracyChanged(Sensor sensor, int accuracy) { > > // Do nothing > > } > > > @Override > > public void onSensorChanged(SensorEvent event) { > > switch (event.sensor.getType()) { > > case Sensor.TYPE_ACCELEROMETER: > > /* > > * NOTE: The data must be copied off the > > event.values > > * as the system is reusing that array in all > > SensorEvents. > > * Simply assigning: > > * mGravs = event.values won't work. > > * > > * I use a member array in an attempt to reduce > > garbage production. > > */ > > System.arraycopy(event.values, 0, mGravs, 0, 3); > > break; > > case Sensor.TYPE_MAGNETIC_FIELD: > > // Here let's try another way: > > for (int i=0;i<3;i++) mGeoMags[i] = event.values[i]; > > break; > > default: > > return; > > } > > > if (SensorManager.getRotationMatrix(mRotationM, null, > > mGravs, > > mGeoMags)){ > > // Rotate to the camera's line of view (Y axis along > > the camera's > > axis) > > // TODO: Find how to use android.opengl.Matrix to > > rotate to an > > arbitrary coordinate system. > > SensorManager.remapCoordinateSystem(mRotationM, > > SensorManager.AXIS_X, > > SensorManager.AXIS_Z, > > ... > > read more » -- You received this message because you are subscribed to the Google Groups "Android Beginners" group. NEW! Try asking and tagging your question on Stack Overflow at http://stackoverflow.com/questions/tagged/android To unsubscribe from this group, send email to android-beginners+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-beginners?hl=en