Android Basic Traning Course: Detecting device location by using GPS, Location Manager


1. Android Location API

    If you are developing any location based app, you can make your app more smarter by finding user’s location automatically. For this you need to integrate location modules in your application.
There is an API use for detecting device location called LocationManager. For implements LocationListener interface, you will receiving notifications from the LocationListener when the location has changed.
This tutorial describes the usage of them. It is build on:
- Android Studio 1.0.0.
- Java 1.7
- Android min-sdk is 14 (4.0.0 - Ice Cream Sandwich).

2. Determine current location

    Most Android devices allow to determine the current geolocation. This can be done via a GPS (Global Positioning System) module, via cell tower triangulation or via wifi networks.
    In Android SDK, android.location is package provides the API to do this trick.
    Firstly, we must create a subclass of Service to receiving changes of device location (named as GPSDetector). This class also implements LocationListener to update information when you move your device.
    The most important method is getLocation(), when LocationManager is allowed, app will retreive current geolocation of device via GPS_PROVIDER.
And source code of this method like this:
    /**
     * Get current location of Android device
     * @return longtitude and latitude of device
     */
    public Location getLocation() {
        try {
            locationManager = (LocationManager) activity
                    .getSystemService(LOCATION_SERVICE);

            // getting GPS status
            isGPSEnabled = locationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);

            // getting network status
            isNetworkEnabled = locationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            if (!isGPSEnabled && !isNetworkEnabled) {
                // no network provider is enabled
            } else {
                this.canGetLocation = true;
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
                // if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled) {
                    if (location == null) {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        if (locationManager != null) {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return location;
    }
    For implement LocationListener interface, in onLocationChanged() method, we will update informations by call back a method of our Activity:
    @Override
    public void onLocationChanged(Location location) {
        //update current location when device moves
        activity.updateLocation();

    }
     If we haven't enabled Location in device Setting, prompt user to allowed LocationManager by showing an AlertDialog like this:

This method named as showSettingAlert():
    /**
     * Function to show settings alert dialog
     * On pressing Settings button will launch Settings Options
     */
    public void showSettingsAlert() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(activity);

        // Setting Dialog Title
        alertDialog.setTitle("Location setting");

        // Setting Dialog Message
        alertDialog.setMessage("Location is not allowed. Do you want to go to settings menu?");

        // On pressing Settings button
        alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                activity.startActivity(intent);
            }
        });

        // on pressing cancel button
        alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });

        // Showing Alert Message
        alertDialog.show();
    }
    And full code of GPSDetector.java:
package info.devexchanges.location;

import android.app.AlertDialog;
import android.app.Service;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

public class GPSDetector extends Service implements LocationListener {

    private LocationActivity activity;
    private boolean isGPSEnabled = false;
    private boolean isNetworkEnabled = false;
    private boolean canGetLocation = false;
    private Location location;
    private double latitude;
    private double longitude;

    // The minimum distance to change Updates in meters
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 1 meters
    // The minimum time between updates in milliseconds
    private static final long MIN_TIME_BW_UPDATES = 600;
    private LocationManager locationManager;

    public GPSDetector(LocationActivity context) {
        this.activity = context;
        getLocation();
    }

    /**
     * Get current location of Android device
     * @return longtitude and latitude of device
     */
    public Location getLocation() {
        try {
            locationManager = (LocationManager) activity
                    .getSystemService(LOCATION_SERVICE);

            // getting GPS status
            isGPSEnabled = locationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);

            // getting network status
            isNetworkEnabled = locationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            if (!isGPSEnabled && !isNetworkEnabled) {
                // no network provider is enabled
            } else {
                this.canGetLocation = true;
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
                // if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled) {
                    if (location == null) {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        if (locationManager != null) {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return location;
    }

    /**
     * Stop using GPS listener
     * Calling this function will stop using GPS in your app
     */
    public void stopUsingGPS() {
        if (locationManager != null) {
            locationManager.removeUpdates(GPSDetector.this);
        }
    }

    /**
     * Function to get latitude
     */
    public double getLatitude() {
        if (location != null) {
            latitude = location.getLatitude();
        }

        // return latitude
        return latitude;
    }

    /**
     * Function to get longitude
     */
    public double getLongitude() {
        if (location != null) {
            longitude = location.getLongitude();
        }

        // return longitude
        return longitude;
    }

    /**
     * Function to check GPS/wifi enabled
     *
     * @return boolean
     */
    public boolean canGetLocation() {
        return this.canGetLocation;
    }

    /**
     * Function to show settings alert dialog
     * On pressing Settings button will lauch Settings Options
     */
    public void showSettingsAlert() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(activity);

        // Setting Dialog Title
        alertDialog.setTitle("Location setting");

        // Setting Dialog Message
        alertDialog.setMessage("Location is not allowed. Do you want to go to settings menu?");

        // On pressing Settings button
        alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                activity.startActivity(intent);
            }
        });

        // on pressing cancel button
        alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });

        // Showing Alert Message
        alertDialog.show();
    }

    @Override
    public void onLocationChanged(Location location) {
        //update current location when device moves
        activity.updateLocation();

    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

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

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
}

3. Creating an Activity to run it

     Design a simple layout include 1 Button and two TextViews (show longtitude and latitude):     There is only one important method in this (getCurrentLocation()) to get location from LocationManager and show result to TextViews:
private void getCurrentLocation() {
        // create class object
        gps = new GPSDetector(LocationActivity.this);

        // check if GPS enabled
        if (gps.canGetLocation()) {

            double latitude = gps.getLatitude();
            double longitude = gps.getLongitude();

            //update data to textviews
            longtitudeText.setText(String.valueOf(longitude));
            latutideText.setText(String.valueOf(latitude));
        } else {
            // can't get location
            // GPS or Network is not enabled
            // Ask user to enable GPS/network in settings
            gps.showSettingsAlert();
        }
    }
When app onPause(), we stop using GPS to update information, when moving device, app will automatic update current location to TextViews. And this is full code for LocationActivity.java:
package info.devexchanges.location;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class LocationActivity extends Activity {

    private View btnShowLocation;
    private TextView longtitudeText;
    private TextView latutideText;

    // GPSTracker class
    private GPSDetector gps;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_location);

        btnShowLocation = (Button) findViewById(R.id.btnShowLocation);
        longtitudeText = (TextView)findViewById(R.id.txt_long);
        latutideText = (TextView)findViewById(R.id.txt_lat);

        // show location button click event
        btnShowLocation.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                getCurrentLocation();
            }
        });
    }

    private void getCurrentLocation () {
        // create class object
        gps = new GPSDetector(LocationActivity.this);

        // check if GPS enabled
        if (gps.canGetLocation()) {

            double latitude = gps.getLatitude();
            double longitude = gps.getLongitude();

            //update data to textviews
            longtitudeText.setText(String.valueOf(longitude));
            latutideText.setText(String.valueOf(latitude));
        } else {
            // can't get location
            // GPS or Network is not enabled
            // Ask user to enable GPS/network in settings
            gps.showSettingsAlert();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        gps.stopUsingGPS(); //stop using GPS service on pause
    }

    public void updateLocation() {
       getCurrentLocation();
    }
}

4. Setting up permissions

    If you want to access the GPS sensor, you need the ACCESS_FINE_LOCATION permission. Moreover, provider INTERNET permission to get data. Open your AndroidManifest.xml and add these lines above <application> tag:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">
<uses-permission android:name="android.permission.INTERNET">

5. Running application

Turn on Location options on device Setting first:
Our output will be like this:
pic name pic name pic name

6. Conclusions


     In this post, I presented the GPS System of Android to detect user location. Today, Map applications use this location philosophy, you can see this post to learn about detecting current location with Google Map API. Finally, you can get completed code by clicking the button below.
(Sorry for ads)


Share


Previous post
« Prev Post
Next post
Next Post »