Zachary Powell

Software Programmer

Zachary Powell

Download my CV Send me a Message

LocationListener

Display Users current location on Google Map

Zachary Powell - 14/12/2015

Before starting this guide, check out the Google Map example HERE if you have not already read it.

Now that we have a working Map, there is a range of examples we can cover. One that is very widely required, is displaying the users current location. When using a map, it is often the case that the user will want to be able to see where they currently are. Below we will explore what needs to be added to our Google Map example to display the users current location and update the marker as the user moves.

Manifest Changes

First we need to set some permissions in the Android manifest of our project. In Android studio, open the Manifest folder and open AndroidManifest.xml

We then need to add the below lines to manifest our side of the application tag.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />

If you are using my Google Map Example code your manifest should then look like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.zpwebsites.basicgooglemapexample">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

These permissions are required to get the users current location. We want the file location when available, but if there is no GPS connection, the coarse location can be used to get a rough user location based on a mobile signal.

Centre Map on Current Location

We are going to create a method called centerMapOnMyLocation(). This will be called once the map is loaded and will grab the users current location using GPS if available. The complete method:

private void centerMapOnMyLocation() {
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();

        Location location = null;

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

            location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
        }

        if (location != null)
        {
            Long = location.getLongitude();
            Lat = location.getLatitude();
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                    new LatLng(location.getLatitude(), location.getLongitude()), 13));

            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(new LatLng(location.getLatitude(), location.getLongitude()))      // Sets the center of the map to location user
                    .zoom(17)                   // Sets the zoom
                    .bearing(0)                // Sets the orientation of the camera to east
                    .tilt(40)                   // Sets the tilt of the camera to 30 degrees
                    .build();                   // Creates a CameraPosition from the builder
            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
        }else{
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(53.779558, -4.042969), 5.5f));
            CharSequence text = "Sorry, we where unable to get your location, please check your GPS";
            int duration = Toast.LENGTH_LONG;
            Toast.makeText(this.getBaseContext(), text, duration).show();
        }
    }

First we set up a couple of variables which will be used within the method.

LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
Location location = null;

The LocationManager will be used to get the current location from the system. This handles querying the GPS for the location. The Location object will then be used to store the Location that is returned by the LocationManager.

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
        }

Next, as of Android API level 23 (Android version 6.0), we now have to check that the permissions we require have been accepted by the user. If they have been accepted, we can go ahead and use the LocationManager to call the .getLastKnownLocation(). This will return the last location from the system. If GPS is available, this will return the current location.

if (location != null)
        {
            Long = location.getLongitude();
            Lat = location.getLatitude();
           
            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(new LatLng(Lat, Long))      // Sets the center of the map to location user
                    .zoom(17)                   // Sets the zoom
                    .bearing(0)                // Sets the orientation of the camera to east
                    .tilt(40)                   // Sets the tilt of the camera to 30 degrees
                    .build();                   // Creates a CameraPosition from the builder
            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
        }

If the location has been returned, we can then get the locations longitude and latitude using the getter methods.  Once we have the location in the form of co-ordinates, we build a CameraPosition object, setting the target to the users position and setting up other camera settings, zoom level, bearing and tilt.

Finally, by passing this CameraPosition object to the animateCamera() method of the Google map object, we can move the maps view to centre on the users location.

else{
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(53.779558, -4.042969), 5.5f));
            CharSequence text = "Sorry, we where unable to get your location, please check your GPS";
            int duration = Toast.LENGTH_LONG;
            Toast.makeText(this.getBaseContext(), text, duration).show();
        }

We then use an else statement to cover if the location was not returned, either because the user declined the permissions or for some reason, theLocationManager failed to return the location object. In this else statement, we just move the camera to a pre-defined location and display a Toast message to let the user know we failed to get their position.

Then we need to edit our onMapRead() function to call our centerMapOnMyLocation() method, once our map is ready to use. We also call setMyLocationEnabled(true) so that the map will display a marker at the users location.

public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMyLocationEnabled(true);
        centerMapOnMyLocation();
}

Using LocationListener to update the users location

At this point, we have an app that centres to the users location on starting up the map, but if the user then moves it will not update the map. This is where we need to set up a LocationListener to monitor for location changes and update the map accordingly.

LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        LocationListener locationListener = new LocationListener() {
            public void onLocationChanged(Location location) {
                Long = location.getLongitude();
                Lat = location.getLatitude();
            }

            public void onStatusChanged(String provider, int status, Bundle extras) {
            }

            public void onProviderEnabled(String provider) {
            }

            public void onProviderDisabled(String provider) {
            }
        };

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
        }

Within the onCreate() method we add the above code. This sets up a LocationManager and a LocationListener. The LocationManager is the same as before using the Location service, while the LocationListener sets up the code to be run when a location changes. Within the onLocationChanged() method, we get the new Longitude and Latitude and update our Long and Lat variables.

Then, we need to run the same check to make sure the user has accepted our permissions again. If they have, we can then go ahead and register the LocationListener with the LocationManager. This allows the onLocationChanged() code to be run when the users location changes.

Complete Example

Once we have added all the above code, the app can not be run and display the current users location.

If you would like to check out the complete applications code, you can find it HERE. This code will be updated in the future to hold all example code for Google Maps.

As always if you have any questions please comment below.

Leave a Reply

Your email address will not be published. Required fields are marked *

Tags: , , ,

“ Any fool can write code that a computer can understand. Good programmers write code that humans can understand. ”

-Martin Fowler