Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Location getBearing() always returns 0

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!

like image 966
user3171597 Avatar asked Jul 13 '15 15:07

user3171597


1 Answers

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.

like image 154
Matt Newbill Avatar answered Sep 22 '22 18:09

Matt Newbill