Get Latitude and Longitude using GPS in Android

Objective:
To retrieve Latitude and Longitude of current position using GPS

Function:
When the button is pressed, small pop up will be displayed to inform the status of GPS. If GPS is not enable, GPS dialog will be pop up and let user to choose setting. Once the GPS is enable, 'GPS is already enable' will be pop up after the 'Get GPS Status' Button is pressed. Then latitude and longitude will be displayed as pop up. 

IDE:
Android Studio 1.0.2

Source Code:
The project can be downloaded from here.

Note:
This is the continuous tutorial from here.

Result:

                       

Explanation:

1. As usual, we need to add permission to AndroidManifest.xml




2. Then we need to commit the Fragment in MainActivity.java.

/*way of adding fragment with java*/
        //FragmentOne is the class which inflate the fragment_one.xml and return the view
        FragmentOne myFragment = new FragmentOne();
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        //'container' is android id in activity_main.xml
        //add android:id="@+id/container" in activity_main.xml
        transaction.add(R.id.container, myFragment, "main_layout_container");
        transaction.commit();

3. In FragmentOne.java, we first setup button to display
//create Button 'button' and link with button id from fragment_one.xml
        Button button = (Button) view.findViewById(R.id.button);

4. In FragmentOne.java, we implement OnClickListener to detect the pressing of the button.Also take note that Object of gpsHelperClass is created with Context which will be used in LocationManager.

button.setOnClickListener(new View.OnClickListener() {
            //create object and pass context to it.

            public void onClick(View v) {

                //get boolean result and display small pop up
                if (gpsHelperClass.isGpsReadyToUse()) {
                    Toast.makeText(context, "GPS is already enable",
                            Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(context, "GPS is not enable",
                            Toast.LENGTH_SHORT).show();
                }
            }
        });

5. In FragmentOne.java, context is sent to GpsHelperClass so that it can be able to use with context such as dialog.
@Override
    public void onPause() {
        //Pass context to GpsHelperClass before resuming the app.
        //otherwise, there will be error related to 'Unable to resume Activity'
        gpsHelperClass.setContext(getActivity());
        /*To removes all location updates to save battery*/
        gpsHelperClass.removeGpsUpdate();
        super.onPause();
    }


6. In GpsHelperClass.java, the context passed from FragmentOne.java is first used in constructor.
//at constructor, context is passed from FragmentOne.java and context will be used by GpsHelperClass throughout.
    public GpsHelperClass(Context context) {
        this.context = context;
    }

7. In GpsHelperClass.java, the context also is passed with setContext() function.
/*Pass context from FragmentOne; cannot find any neat way to pass*/
    public void setContext(Context context) {
        this.context = context;
    }

8. In GpsHelperClass.java, we first setup LocationManger and return the GPS status back. If no GPS is not enable, then we will ask user to enable GPS from the system setting using getUserInputToEnableGPS(). If GPS is enable, location is requested with requestLocationUpdates. If location is not null or if location is successfully updated with getLastKnownLocation, latitude and longitude will be updated and showed as pop up. 

public boolean isGpsReadyToUse() {
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

      /* If there is no gps provider, ask user to activate
        We cannot enable GPS via program.
        Still need user input to enable for good reason.*/
        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            getUserInputToEnableGPS();
        } else {

            //500 ==  minTime minimum time interval between location updates, in milliseconds
            //1 ==  minDistance minimum distance between location updates, in meters
            locationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER,
                    500,
                    1, this);
            if (locationManager != null) {
                location = locationManager
                        .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if (location != null) {

                    String latitude = String.valueOf(location.getLatitude());
                    String longitude = String.valueOf(location.getLongitude());
                    //small pop up for Lat and Long
                    Toast.makeText(context, "Lat: " + latitude + "\nLong: " + longitude,
                            Toast.LENGTH_SHORT).show();
                }
            }
        }
        //return the status of GPS; whether it is ON or OFF.
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }
9. In GpsHelperClass.java, we setup alertDialog and start intent to get system location setting if user choose 'alertDialog.setPositiveButton'. Otherwise, we will just cancel the dialog window.

private void getUserInputToEnableGPS() {
        //Ref from http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
        alertDialog.setTitle("GPS is settings");

        // Setting Dialog Message
        alertDialog.setMessage("GPS is not enabled. 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) {

                //Settings.ACTION_LOCATION_SOURCE_SETTINGS == Activity Action: Show settings to allow configuration of current location sources.
                // The Settings provider contains global system-level device preferences.
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);

                //Every Activity is invoked by an Intent. therefore, we are going to start activity which allow to set location
                context.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();
    }


Complete Code:


Content of MainActivity.java
package com.example.osdevlab.simpletutorial;

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;


public class MainActivity extends ActionBarActivity {

    public static Context context;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); //set to activity_main.xml

        /*way of adding fragment with java*/
        //FragmentOne is the class which inflate the fragment_one.xml and return the view
        FragmentOne myFragment = new FragmentOne();
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        //'container' is android id in activity_main.xml
        //add android:id="@+id/container" in activity_main.xml
        transaction.add(R.id.container, myFragment, "main_layout_container");
        transaction.commit();
    }


}

Content of FragmentOne.java
package com.example.osdevlab.simpletutorial;

import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

/**
 * Created by osdevlab on 12/29/14.
 */
public class FragmentOne extends Fragment {

    Context context;
    GpsHelperClass gpsHelperClass = new GpsHelperClass(getActivity());

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        // Inflate the layout with fragment_one.xml
        View view = inflater.inflate(R.layout.fragment_one, container, false);

        //create Button 'button' and link with button id from fragment_one.xml
        Button button = (Button) view.findViewById(R.id.button);

        //returns the Activity the Fragment is currently associated with
        //In Fragment, this step requires to pass context to other class.
        context = getActivity();

        /*define OnClickListener for button here*/
        button.setOnClickListener(new View.OnClickListener() {
            //create object and pass context to it.


            public void onClick(View v) {

                //get boolean result and display small pop up
                if (gpsHelperClass.isGpsReadyToUse()) {
                    Toast.makeText(context, "GPS is already enable",
                            Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(context, "GPS is not enable",
                            Toast.LENGTH_SHORT).show();
                }
            }
        });
        return view;
    }

    @Override
    public void onPause() {
        //Pass context to GpsHelperClass before resuming the app.
        //otherwise, there will be error related to 'Unable to resume Activity'
        gpsHelperClass.setContext(getActivity());
        /*To removes all location updates to save battery*/
        gpsHelperClass.removeGpsUpdate();
        super.onPause();
    }

    @Override
    public void onResume() {
        //Pass context to GpsHelperClass before resuming the app.
        //otherwise, there will be error related to 'Unable to resume Activity'
        gpsHelperClass.setContext(getActivity());

        //get ready to retrieve GPS data when app is resumed
        gpsHelperClass.isGpsReadyToUse();
        super.onResume();
    }

    @Override
    public void onStop() {
        gpsHelperClass.setContext(getActivity());
        super.onStop();
    }

    @Override
    public void onDestroy() {
        gpsHelperClass.setContext(getActivity());
        super.onDestroy();
    }
}


Content of GpsHelperClass.java
package com.example.osdevlab.simpletutorial;

import android.app.AlertDialog;
import android.content.Context;
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.provider.Settings;
import android.widget.Toast;

/**
 * Created by osdevlab on 1/1/15.
 */

//we need to first implements LocationListener
//Four functions will be provided by IDE when implements LocationListener and we have to override those functions.
//For now, we don't need to override those functions yet.

public class GpsHelperClass implements LocationListener {

    protected LocationManager locationManager;
    Context context;
    Location location;

    /*At constructor, context is passed from FragmentOne.java and
    context will be used by GpsHelperClass throughout.*/
    public GpsHelperClass(Context context) {
        this.context = context;
    }
    /*Pass context from FragmentOne; cannot find any neat way to pass*/
    public void setContext(Context context) {
        this.context = context;
    }

    /*To removes all location updates.Save battery*/
    public void removeGpsUpdate() {
        locationManager.removeUpdates(GpsHelperClass.this);
    }

    /*If GPS is not turn on yet, then ask user to turn on for us. If GPS is turn on, */

    //context is passed from FragmentOne.java and context will be used by this function
    public boolean isGpsReadyToUse() {
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

      /* If there is no gps provider, ask user to activate
        We cannot enable GPS via program.
        Still need user input to enable for good reason.*/
        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            getUserInputToEnableGPS();
        } else {

            //500 ==  minTime minimum time interval between location updates, in milliseconds
            //1 ==  minDistance minimum distance between location updates, in meters
            locationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER,
                    500,
                    1, this);
            if (locationManager != null) {
                location = locationManager
                        .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if (location != null) {

                    String latitude = String.valueOf(location.getLatitude());
                    String longitude = String.valueOf(location.getLongitude());
                    //small pop up for Lat and Long
                    Toast.makeText(context, "Lat: " + latitude + "\nLong: " + longitude,
                            Toast.LENGTH_SHORT).show();
                }
            }
        }
        //return the status of GPS; whether it is ON or OFF.
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }

    /*To get user to enable GPS through dialog*/

    private void getUserInputToEnableGPS() {
        //Ref from http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
        alertDialog.setTitle("GPS is settings");

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

        // When user presses 'Settings' button
        alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {

                //Settings.ACTION_LOCATION_SOURCE_SETTINGS == Activity Action: Show settings to allow configuration of current location sources.
                // The Settings provider contains global system-level device preferences.
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);

                //Every Activity is invoked by an Intent. Therefore, we are going to start activity which allow to set location
                context.startActivity(intent);
            }
        });

        // when user presses '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) {

    }

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

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

No comments:

Post a Comment