Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Direction in Android (Such as North, West)

I am new in Android and I want to get direction according to my camera. How can I get direction information according to my camera? Could you give an idea for this?

like image 315
oldTimes Avatar asked Nov 29 '11 18:11

oldTimes


People also ask

What is orientation sensor in mobile?

The system computes the orientation angles by using a device's geomagnetic field sensor in combination with the device's accelerometer. Using these two hardware sensors, the system provides data for the following three orientation angles: Azimuth (degrees of rotation about the -z axis).

What is magnetic sensor in android?

A system called Pulse uses the magnetic field sensor, or magnetometer, for the compass app in iPhones and Android phones, to receive messages in the form of a varying magnetic field produced by a nearby electromagnet.

What is the difference between motion and position sensors in Android?

Motion sensors by themselves are not typically used to monitor device position, but they can be used with other sensors, such as the geomagnetic field sensor, to determine a device's position relative to the Earth's frame of reference. This section describes many of the most common Android motion sensors.


2 Answers

TYPE_ORIENTATION is deprecated

We cannot use the Orientation Sensor anymore, we can use the Magnetic Field Sensor and Accelerometer Sensors in tandem to get equivalent functionality. It's more work but it does allow to continue to use a callback to handle orientation changes.

Conversion from accelerometer and magnetic field to azimut :

float[] mGravity;
float[] mGeomagnetic;

public void onSensorChanged(SensorEvent event) {

    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
        mGravity = event.values;

    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
        mGeomagnetic = event.values;

    if (mGravity != null && mGeomagnetic != null) {
        float R[] = new float[9];
        float I[] = new float[9];

        if (SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic)) {
            
            // orientation contains azimut, pitch and roll
            float orientation[] = new float[3];
            SensorManager.getOrientation(R, orientation);

            azimut = orientation[0];
        }
    }
}

To point the north you can calculate a rotation in degrees :

float rotation = -azimut * 360 / (2 * 3.14159f);
like image 143
Yves M. Avatar answered Oct 30 '22 15:10

Yves M.


Here's what I have so far that's somewhat working for me, values returned are between 0 - 360 but I don't think north is properly calibrated? I'm using this on an LG G Pad running Android 5.0.1

public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
        mGravity = event.values;
    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
        mGeomagnetic = event.values;
    if (mGravity != null && mGeomagnetic != null) {
        float R[] = new float[9];
        float outR[] = new float[9];
        float I[] = new float[9];

        boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
        if (success) {
            float orientation[] = new float[3];

            SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Y, outR);

            SensorManager.getOrientation(outR, orientation);
            azimut = orientation[0];

            float degree = (float)(Math.toDegrees(azimut)+360)%360;

            System.out.println("degree " + degree);

I'm sure there are things I've missed but hopefully this is a decent starting point for others. I reviewed a good number of other questions, comments, etc. to get to this point.

like image 40
JC23 Avatar answered Oct 30 '22 14:10

JC23