Android

Android Fetching Device Location on GoogleMap: Part 1

android gps google map googlemap location
Written by Yasir Ameen

Now a days almost all big companies integrating GoogleMap and Location services in their apps in order to aware user location. Uber and Careem uses the GoogleMap and Location services in thier apps to give you very easy ride. In this tutorail we will first implment GoogleMap and then we will start Fetching Device Location on GoogleMap.

 

Let’s Start the Journey With Google Map

Download Source Code : https://github.com/YasirAmeen/GoogleMapFetchinglocationPart1

*Integerating Google Map

Implementing GoogleMap in your app is very easy you just first create GoogleMap API key from the developer site, you use this key in your project and then you add googleMap fragment in your xml.

Enabling GoogleMap API Key

Open google developer site from here and click the GET A API button, enter any name in prompt dialog and click ENABLE API button, see screenshot.

google map android api location

Fetching GoogleMap API Key

Once your map api key is ready you are ready to use it but first copy api key in any safe location, we will need it. Now Click the FINISH button, see screenshot.

google map location fetching key

 

Confgurationd and Updating Manifiest File.

Adding Dependency For Google Map.

Now open your build.gradle file and the following dependency in your android project. If you get install and sync error, please install the it.

   compile 'com.google.android.gms:play-services:10.2.0'

Open your project manifies file as we need to add some permissions and other configuration.

Add the following permission in your project manifest file.


<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Add the following declaration in your manifies file inside the root element of manifiest file.


 <uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />

Add the following declaration in your manifies file, keep in mind you need to put in inside the application tag.


<meta-data
    android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />

 

Now add the GoogleMap API key in your project manifest file using the following metadata tag. You must specify your api key in string resource directory otherwise your application missbehave.


<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="@string/google_maps_key" />

 

Adding GoogleMap Object In Your Project

In order to add GoogleMap Object in your android app you need a fragment. Although its very easy to integrate. Open your activity_main.xml file and remove everything and paste the following xml code.


<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="com.google.android.gms.maps.MapFragment"
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

 

Now open MainActivity.java and copy all the code from here and paste it your java file.


public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MapFragment mapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        
        mMap = googleMap;
        //Here you will define the logic what to do when the Map Ready
        LatLng latLng = new LatLng(24.5572298,67.8388739);
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 10);
        mMap.animateCamera(cameraUpdate);
   } 
} 

Run the app and you will see specified location on GoogleMap.

android google map

 

Fetching Device Location on GoogleMap

Now you have implmented GoogleMap functionaliy in your app and now its time to integrate real device location on GoogleMap. Keep In mind that you can fetch device location withoug implementing GoogleMap. Map is other thing and knowing device location is other, but combining both in your app is great and awesome 🙂

 

What is Last Know Location?

When you want to know the current location of your device. Your app request the Last Known location of user’s device. Knowing the Last know location of your device is actually knowing the current location of your device.

In order to getting the Last Know location of user device, we will use fused location provider. The fused location provider is the API from the Google Play services which manage the underlying location technology.

 

Let’s Start Writing Code

Important! Add following permission in your manifest file. These permission are need when fetching device location.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><

Step 1) Implementing Interface

Open your MainActivity.java and implement ConnectionCallbacks, OnConnectionFailedListener and LocationListener also implement their methods. Your MainActivity.java should look like mine.

 


 public class MainActivity extends AppCompatActivity implements OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener {


    private static final int REQUEST_CHECK_SETTINGS = 1000;
    private MapFragment mapFragment;
    private GoogleMap mMap;
    private GoogleApiClient googleApiClient;
    private Location mLastLocation;
    private LocationRequest request;

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

         mapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        mMap = googleMap;


        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then over   riding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        mMap.setMyLocationEnabled(true);

    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onLocationChanged(Location location) {

    }

 

Writing Some Useful Methods

Here we will write some useful methods which will help use to find  Last Know location of user’s device. We will write following methods for our need.

  1. setupLocationManager() – Use to create LocationManager before requesting Last Know location
  2. createLocationRequest() – Handle request paramerter for getting Last Know location
  3. setInitialLocation() – This method will show Last Known location of device on GoogleMap

 

Writing Code for setupLocationManager() Method

You have already defined GoogleApiClient field above.

 private void setupLocationManager() {
    //buildGoogleApiClient();
    if (googleApiClient == null) {

        googleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .addApi(Places.GEO_DATA_API)
                .addApi(Places.PLACE_DETECTION_API)
                .build();
        //mGoogleApiClient = new GoogleApiClient.Builder(this);
    }
    googleApiClient.connect();
}

 

Writing Code for createLocationRequest() Method

You have already defined LocationRequest field above.

 protected void createLocationRequest() {

    request = new LocationRequest();
    request.setSmallestDisplacement(10);
    request.setFastestInterval(50000);
    request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    request.setNumUpdates(3);

    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(request);
    builder.setAlwaysShow(true);

    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(googleApiClient,
                    builder.build());


    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(@NonNull LocationSettingsResult result) {
            final Status status = result.getStatus();
            final LocationSettingsStates states = result.getLocationSettingsStates();

            switch (status.getStatusCode()) {

                case LocationSettingsStatusCodes.SUCCESS:
                    setInitialLocation();
                    break;

                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    // Location settings are not satisfied, but this can be fixed
                    // by showing the user a dialog.
                    try {
                        // Show the dialog by calling startResolutionForResult(),
                        // and check the result in onActivityResult().
                        status.startResolutionForResult(
                                MainActivity.this,
                                REQUEST_CHECK_SETTINGS);
                    } catch (IntentSender.SendIntentException e) {
                        // Ignore the error.
                    }
                    break;

                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    // Location settings are not satisfied. However, we have no way
                    // to fix the settings so we won't show the dialog.

                    break;

            }


        }
    });


}

I would like you to go through all the code inside createLocationRequest() and you will find that there is one new method will also need which setIntialLocation() , but before writing it lets handle the result on onActivityResult which is pass by startResolutionForResult(…) . You can write the follwoing snippet below the createLocationRequest() method.

 


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("onActivityResult()", Integer.toString(resultCode));

    //final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
    switch (requestCode)
    {
        case REQUEST_CHECK_SETTINGS:
            switch (resultCode)
            {
                case Activity.RESULT_OK:
                {

                    setInitialLocation();

                    Toast.makeText(LocationActivity.this, "Location enabled by user!", Toast.LENGTH_LONG).show();
                    mRequestingLocationUpdates = true;
                    break;
                }
                case Activity.RESULT_CANCELED:
                {
                    // The user was asked to change settings, but chose not to
                    Toast.makeText(LocationActivity.this, "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
                    mRequestingLocationUpdates = false;
                    break;
                }
                default:
                {
                    break;
                }
            }
            break;
    }
}

Writing Code for setInitialLocation() Method

The setIntialLocation() Method is responsible for taking you to the current location on GoogleMap. Its used onLocationChanged() Listener to give you current lat lng whenever device location changes.

  private void setInitialLocation() {


        if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {


                mLastLocation = location;

                try {
                    LatLng positionUpdate = new LatLng(location.getLatitude(), location.getLongitude());
                    CameraUpdate update = CameraUpdateFactory.newLatLngZoom(positionUpdate, 15);
                    mMap.animateCamera(update);
                
                } catch (Exception ex) {

                    ex.printStackTrace();
                    Log.e("MapException", ex.getMessage());

                }

            }

        });
    }

 

Almost you have put all ingredients for Fetching Device Location, one thing we also need to handle is RunTime Permssion. If you want to learn more about it, you can visit here.

Handling Location Permission

First we need to create a method called CheckMapPermission() . This method will handle our RunTime permission if the device will be greater than Lollipop 5.0 . Then this method will request a permission to the user at RunTime, user must have to allow it, and if the device is lower than 6.0 , method will not ask RunTime permission and everything will work fine.

 

private void CheckMapPermission() {
    
    if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
        
        if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1002);
        }else {
            
            setupLocationManager();
        }
    }
    else {
        setupLocationManager();
    }

}


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 1002: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

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

                    setupLocationManager();

                }
            } else {

                Toast.makeText(MainActivity.this,"Permission Denied",Toast.LENGTH_SHORT).show();
                //finish();
            }
        }
        break;
    }
}

Putting everything together.

Its time to run the app . All we need to is call CheckMapPermission() Method in OnCreate(…) and you are ready to go 🙂

android gps location google map

 

Source Code

You can find the Source Code of this article on Following github link.

https://github.com/YasirAmeen/AndroidFetchingLocation

See the result video

 

 

About the author

Yasir Ameen

I'm a programmer, teacher, and speaker. I work out of my home in Pakistan, Karachi for the Mobile, especially Android Platform. I discuss about technology, gadgets, codes, the devices we’re going and we’ve been. I’m excited about community, social equity, and media.

1 Comment

Leave a Comment