Android Location getBearing() always returns 0

12,372

getBearing() will return 0 if you are obtaining your data using LocationManager.NETWORK_PROVIDER because the signal/accuracy is too weak. Try setting the GPS provider to GPS and be sure to test it outside (GPS does not work indoors or in the middle of very tall buildings due to satellites not having direct communication)

To ensure the provider you have chosen supports getBearing() you can use the method from LocationProvider called supportsBearing () which returns true if the provider you have chosen supports the getBearing() call.

Lastly ensure that you have the ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permissions in your AndroidManifest.xml

Code as per my suggestions would be something like this:

LocationManager mlocManager =

(LocationManager)getSystemService(Context.LOCATION_SERVICE);

LocationListener mlocListener = new MyLocationListener();


mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);

Resources: http://developer.android.com/reference/android/location/LocationManager.html http://developer.android.com/reference/android/location/LocationProvider.html http://www.firstdroid.com/2010/04/29/android-development-using-gps-to-get-current-location-2/

UPDATE: The answer was that the two points that were being used to calculate in getBearing() were too close and therefore giving an inaccurate result. To correct this, manually grab two GPS points and use the bearingTo() to see a more accurate result.

Share:
12,372
user3171597
Author by

user3171597

Updated on July 26, 2022

Comments

  • user3171597
    user3171597 almost 2 years

    I've been trying to implement a feature for my Android app that gets the speed and direction of travel of the device, no matter where the device is pointed at. For example: If my Android device is pointed in the North direction and if I'm moving backwards in the South direction, it would return that I'm moving Southbound.

    I've been looking around and I have came up with a possibility of using the Location's getBearing() method (Still, I do not know if that will solve my whole problem). When I invoke getBearing(), it always returns 0.0 for some reason. I have no idea why. Here is my code:

    LocationManager lm;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gcm);
        setUpUI(findViewById(R.id.LinearLayout1));
        isRegged = false;
    
        // GCM startup
        gcm = GoogleCloudMessaging.getInstance(this);
        context = getApplicationContext();
    
        gps = new GPSTracker(context);
        // gps.startListening(context);
        // gps.setGpsCall(this);
    
        /*
         * Variables to indicate location and device ID
         */
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    
        if (gps.getIsGPSTrackingEnabled())
        {
            longitude = Double.valueOf(gps.getLongitude()).toString();
            latitude = Double.valueOf(gps.getLatitude()).toString();
        }
    
        deviceID = telephonyManager.getDeviceId();
    
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, (float) 0.0,
                this);
    }
    

    This is where I am getting the bearing.

    @Override
    public void onLocationChanged(Location currentLocation)
    {
        float speed = 0;
        float speed_mph = 0;
    
        if (previousLocation != null)
        {
            float distance = currentLocation.distanceTo(previousLocation);
    
            // time taken (in seconds)
            float timeTaken = ((currentLocation.getTime() - previousLocation
                    .getTime()) / 1000);
    
            // calculate speed
            if (timeTaken > 0)
            {
                speed = getAverageSpeed(distance, timeTaken);
                speed_mph = (float) (getAverageSpeed(distance, timeTaken) / 1.6);
            }
    
            if (speed >= 0)
            {
                info_text.setVisibility(View.VISIBLE);
                info_text_mph.setVisibility(View.VISIBLE);
    
                DecimalFormat df = new DecimalFormat("#.#");
                info_text.setText("Speed: " + df.format(speed) + " " + "km/h");
                info_text_mph.setText("  Speed: " + df.format(speed_mph) + " "
                        + "mph");
    
                if (speed >= 10 && lm.getProvider(LocationManager.GPS_PROVIDER).supportsBearing())
                {
                    float degree = currentLocation.getBearing();
    
                    direction_text.setVisibility(View.VISIBLE);
    
                    Log.i(TAG, String.valueOf(degree));
    
                    if (degree == 0 && degree < 45 || degree >= 315
                            && degree == 360)
                    {
                        direction_text.setText("You are: Northbound");
                    }
    
                    if (degree >= 45 && degree < 90)
                    {
                        direction_text.setText("You are: NorthEastbound");
                    }
    
                    if (degree >= 90 && degree < 135)
                    {
                        direction_text.setText("You are: Eastbound");
                    }
    
                    if (degree >= 135 && degree < 180)
                    {
                        direction_text.setText("You are: SouthEastbound");
                    }
    
                    if (degree >= 180 && degree < 225)
                    {
                        direction_text.setText("You are: SouthWestbound");
                    }
    
                    if (degree >= 225 && degree < 270)
                    {
                        direction_text.setText("You are: Westbound");
                    }
    
                    if (degree >= 270 && degree < 315)
                    {
                        direction_text.setText("You are: NorthWestbound");
                    }
    
                }
    
            }
        }
        previousLocation = currentLocation;
    
    }
    

    Thanks so much!

  • user3171597
    user3171597 almost 9 years
    Thank you for your feedback and I apologize that I completely forgot to mention in my post that I am using GPS provider. I will update my code.
  • Matt Newbill
    Matt Newbill almost 9 years
    And did you attempt the use of getBearing() while outside and in a location away from tall buildings or other objects which could prevent you from satellite communication?
  • user3171597
    user3171597 almost 9 years
    Yes I did. I've tried testing that feature while driving around. Although the speed is pretty accurate (5-10 km off) the getBearing() always returns 0, which always returns "You are: Northbound" no matter which direction I go.
  • Matt Newbill
    Matt Newbill almost 9 years
    And is the result of the supportsBearing() method true?
  • user3171597
    user3171597 almost 9 years
    Yes it does. I've added in lm.getProvider(LocationManager.GPS_PROVIDER).supportsBearing‌​()) into the if (speed >= 10) statement.
  • Matt Newbill
    Matt Newbill almost 9 years
    Hmm, interesting. Bearings are calculated with two GPS points, so what is probably happening is the GPS points are so close to each other that it is unable do an accurate calculation. I would try manually grabbing two GPS points (within 10 seconds) and calculating using the bearingTo Method. This way you can ensure 1) You are getting two different GPS points 2) The calculation itself is working and its the GPS data that is incorrect. Similar to what is done here android-er.blogspot.com/2013/02/…
  • user3171597
    user3171597 almost 9 years
    After using the bearingTo() method, the bearing doesn't always return 0 anymore! I have to further test if this is accurate when I am driving. However, it works. Thank you so much! Also, is there a reason why my getBearing() always returns random floating number every second? Is it possible that it is due to the minimum distance and minimum time of update for the LocationManager?
  • Matt Newbill
    Matt Newbill almost 9 years
    Awesome! The getBearing() returns the degrees, but if the points are too close to each other than the numbers are going to be inaccurate(or "random").
  • chintan s
    chintan s over 8 years
    Hello guys, Is there anyway to get accurate heading information for indoor environment? For example, iOS provides trueHeading using CoreLocation Framework. Is there anything like this in Android? My detailed question is here stackoverflow.com/questions/32693424/…
  • The_Martian
    The_Martian about 8 years
    @Matt Newbill do you know how to align a car marker along the street based on the bearing the car is moving? Here is my question. stackoverflow.com/questions/35449269/…
  • Matt Newbill
    Matt Newbill about 8 years
    @The_Martian Did you try applying the answer here to your situation? Manually grabbing two points because the two you get are too close together, which gives you an inaccurate facing direction.
  • The_Martian
    The_Martian about 8 years
    @Matt Newbill the bearing is returning a value, but I have hard time to rotate the car on the street. I set the anchor at (.5,5.) but that didn't help. My question is how do I trick it to think the front of the car should always face the direction the car is moving.
  • Matt Newbill
    Matt Newbill about 8 years
    @The_Martian Keep a variable of the old location or the location it was at 1 or 2 seconds ago and calculate the direction manually. If you do it every time it won't be accurate enough to provide the correct direction.