Friday 1 July 2016

Android Google Maps With Nearyby Places

Show User Current Location and Load Nearby Places (within 5km radius) using Volley.

Today im gonna show you how to show current location and load nearby places in android.
Previously had some trouble with other google places and maps tutorial coz of complexity and underinformations, but finally, here comes the simplest and cleanest code of all.

Project Structure:


1. Obtaining Api keys; Enabling Google Maps, Places for Android and Google Places Web Service

> We will get two api keys, one for Android Api Key for google maps and another one for Browser Api Key for google maps.
> In that case, we will enable three Apis:
1. Google Maps for Android
2. Google Places for Android
3. Google Places for Web Service


- This the one procedure that is very confusing, more especially when you use a wrong api key and your app fails to load all the nearby places.
* The best way around this is to create an android project with a map activity in android studio, there are some credentials we will need from the app to get the api keys.

i) Create a new android maps activity project and name is GPlaces, do review my previous maps project <Show Current Location> to get it right, because our app will built on top of that.

ii) Pick the api url from the google_maps_api.xml and paste it to the browser and follow the link to create an Android Api Key as shown in my previous maps post.

iii) Don't forget to copy the Android Key you created at the console and paste it to the  google_maps_api.xml


a) Generating the Browser API key

- On your Api Manager, go to Credentials tab from the left panel, All your Api Keys should be enlisted here. In our case, the Android Key that we enabled.



- Click on the Create credentials, which will popup a drop down list.



- Select API key, another popup will appear to prompt you to create a new key,



- Select Browser key, another page will open up, you can choose to rename the key and press Create button to complete. Just leave the other field blank.



- Copy the Api key from the popup that will appear and save it somewhere, will need it too.




- Now in your Credentials, You should have two keys.




b) Enabling Google Places Api for Android and Google Api Web Service  ,

- On your Api Manager, go to Overview tab from the left panel,
- Go to the Google Maps Apis, Click More, to see the Google Places Api for Web Service



- Click on Google Places API Web Service, which will load another page



- Click on the Enable button and go back

- * Follow the above steps to enable Google Places API for Android <Same Procedure>*



>> If you go back to Overview, then click on the Enabled APIs tab, You'll see 3 APIs Enabled



*** That's it, we are done with the Api stuffs, let's head to actual coding ***

2. Android app,

i) Create a New Android Project in android studio and select Scrolling Activity



ii) Import Volley Library; how to import custom library
compile 'com.mcxiaoke.volley:library:1.0.19'

Your build.gradle(Module: App)

apply plugin: 'com.android.application'
android {
    compileSdkVersion 24
    buildToolsVersion "24.0.0"
    defaultConfig {
        applicationId "com.androidmastermind.gplaces"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
 'proguard-rules.pro'        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.0.0'
    compile 'com.google.android.gms:play-services:9.2.0'
    compile 'com.mcxiaoke.volley:library:1.0.19'
}

iii) Create AppController.java class, this will extend Application. Volley will use this class to make the json request for us.

package com.androidmastermind.gplaces;

import android.app.Application;
import android.text.TextUtils;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

import static com.androidmastermind.gplaces.AppConfig.TAG;

public class AppController extends Application {

    private RequestQueue mRequestQueue;
    private static AppController mInstance;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;

    }

    public static synchronized AppController getInstance() {
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }

    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }

    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

iv) Create another class, AppConfig.java, this will hold all the references that we will need. also the keys for the json that we will have read from google after querying for the nearby places. Will also hold our Browser API key, you;ll paste it here

package com.androidmastermind.gplaces;

/** * Created by sydney on 6/26/2016. */
public final class AppConfig {

    public static final String TAG = "gplaces";

    public static final String RESULTS = "results";
    public static final String STATUS = "status";

    public static final String OK = "OK";
    public static final String ZERO_RESULTS = "ZERO_RESULTS";
    public static final String REQUEST_DENIED = "REQUEST_DENIED";
    public static final String OVER_QUERY_LIMIT = "OVER_QUERY_LIMIT";
    public static final String UNKNOWN_ERROR = "UNKNOWN_ERROR";
    public static final String INVALID_REQUEST = "INVALID_REQUEST";

    //    Key for nearby places json from google
    public static final String GEOMETRY = "geometry";
    public static final String LOCATION = "location";
    public static final String LATITUDE = "lat";
    public static final String LONGITUDE = "lng";
    public static final String ICON = "icon";
    public static final String SUPERMARKET_ID = "id";
    public static final String NAME = "name";
    public static final String PLACE_ID = "place_id";
    public static final String REFERENCE = "reference";
    public static final String VICINITY = "vicinity";
    public static final String PLACE_NAME = "place_name";

    // remember to change the browser api key
    public static final String GOOGLE_BROWSER_API_KEY =
 "AIzaSyBJvlD3dqnz42r9obhEClc2dEJAdXt9IK8";
    public static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
    public static final int PROXIMITY_RADIUS = 5000;
    // The minimum distance to change Updates in meters
    public static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
    // The minimum time between updates in milliseconds
    public static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
}

- If you wanna test your Browser API key now would be the best time, paste the below link on your browser and rem to change the key with your Browser api key. <Its very imperative that you know how the data is obtained, many other maps and places tutorials don't really show the kind of data your expecting>

https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-1.291863,36.824487&radius=5000&types=grocery_or_supermarket&sensor=true&key=AIzaSyBJvlD3dqnz42r9obhEClc2dEJAdXt9IK8

**** Sample of the query of the nearby places, The above url will show all the supermarkets around Technical University of Kenya within a radius of 5km <its in json format, and thus where volley comes in handy>****

v) The activity_maps.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mainCoordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MapsActivity">

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.design.widget.CoordinatorLayout>

vi) Finally, lets alter our MapsActivity.java and add some codes for fetching the nearby places and displaying the markers of all the places on the map.

package com.androidmastermind.gplaces;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import static com.androidmastermind.gplaces.AppConfig.*;

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback,
 LocationListener {

    private GoogleMap mMap;
    LocationManager locationManager;
    CoordinatorLayout mainCoordinatorLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!isGooglePlayServicesAvailable()) {
            return;
        }
        setContentView(R.layout.activity_maps);

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        mainCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.mainCoordinatorLayout);
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            showLocationSettings();
        }
    }

    private void showLocationSettings() {
        Snackbar snackbar = Snackbar
                .make(mainCoordinatorLayout, "Location Error: GPS Disabled!",
 Snackbar.LENGTH_LONG)
                .setAction("Enable", new View.OnClickListener() {
                    @Override                    public void onClick(View v) {

                        startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                    }
                });
        snackbar.setActionTextColor(Color.RED);
        snackbar.setDuration(Snackbar.LENGTH_INDEFINITE);

        View sbView = snackbar.getView();
        TextView textView = (TextView) sbView
.findViewById(android.support.design.R.id.snackbar_text);
        textView.setTextColor(Color.YELLOW);

        snackbar.show();
    }

    @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) {
            return;
        }
        mMap.setMyLocationEnabled(true);
        mMap.getUiSettings().setCompassEnabled(true);
        mMap.getUiSettings().setZoomControlsEnabled(true);

        showCurrentLocation();
    }

    private void showCurrentLocation() {
        Criteria criteria = new Criteria();
        String bestProvider = locationManager.getBestProvider(criteria, true);
        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) {
            return;
        }
        Location location = locationManager.getLastKnownLocation(bestProvider);

        if (location != null) {
            onLocationChanged(location);
        }
        locationManager.requestLocationUpdates(bestProvider, MIN_TIME_BW_UPDATES,
 MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
    }

    private void loadNearByPlaces(double latitude, double longitude) {
//YOU Can change this type at your own will, e.g hospital, cafe, restaurant.... and see how it all works
        String type = "grocery_or_supermarket";
        StringBuilder googlePlacesUrl = 
new StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
        googlePlacesUrl.append("location=").append(latitude).append(",").append(longitude);
        googlePlacesUrl.append("&radius=").append(PROXIMITY_RADIUS);
        googlePlacesUrl.append("&types=").append(type);
        googlePlacesUrl.append("&sensor=true");
        googlePlacesUrl.append("&key=" + GOOGLE_BROWSER_API_KEY);

        JsonObjectRequest request = new JsonObjectRequest(googlePlacesUrl.toString(),
 new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject result) {

                Log.i(TAG, "onResponse: Result= " + result.toString());
                parseLocationResult(result);
            }
        },
                new Response.ErrorListener() {
                    @Override                    public void onErrorResponse(VolleyError error) {
                        Log.e(TAG, "onErrorResponse: Error= " + error);
                        Log.e(TAG, "onErrorResponse: Error= " + error.getMessage());
                    }
                });

        AppController.getInstance().addToRequestQueue(request);
    }

    private void parseLocationResult(JSONObject result) {

        String id, place_id, placeName = null, reference, icon, vicinity = null;
        double latitude, longitude;

        try {
            JSONArray jsonArray = result.getJSONArray("results");

            if (result.getString(STATUS).equalsIgnoreCase(OK)) {

                mMap.clear();

                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject place = jsonArray.getJSONObject(i);

                    id = place.getString(SUPERMARKET_ID);
                    place_id = place.getString(PLACE_ID);
                    if (!place.isNull(NAME)) {
                        placeName = place.getString(NAME);
                    }
                    if (!place.isNull(VICINITY)) {
                        vicinity = place.getString(VICINITY);
                    }
                    latitude = place.getJSONObject(GEOMETRY).getJSONObject(LOCATION)
.getDouble(LATITUDE);
                    longitude = place.getJSONObject(GEOMETRY).getJSONObject(LOCATION)
.getDouble(LONGITUDE);
                    reference = place.getString(REFERENCE);
                    icon = place.getString(ICON);

                    MarkerOptions markerOptions = new MarkerOptions();
                    LatLng latLng = new LatLng(latitude, longitude);
                    markerOptions.position(latLng);
                    markerOptions.title(placeName + " : " + vicinity);

                    mMap.addMarker(markerOptions);
                }

                Toast.makeText(getBaseContext(), jsonArray.length() + " Supermarkets found!",
 Toast.LENGTH_LONG).show();
            } else if (result.getString(STATUS).equalsIgnoreCase(ZERO_RESULTS)) {
                Toast.makeText(getBaseContext(), "No Supermarket found in 5KM radius!!!",
 Toast.LENGTH_LONG).show();
            }

        } catch (JSONException e) {

            e.printStackTrace();
            Log.e(TAG, "parseLocationResult: Error=" + e.getMessage());
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();

        LatLng latLng = new LatLng(latitude, longitude);
        mMap.addMarker(new MarkerOptions().position(latLng).title("My Location"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(15));

        loadNearByPlaces(latitude, longitude);
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {
    }

    @Override
    public void onProviderEnabled(String s) {
    }

    @Override
    public void onProviderDisabled(String s) {
    }

    private boolean isGooglePlayServicesAvailable() {
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (apiAvailability.isUserResolvableError(resultCode)) {
                apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.i(TAG, "This device is not supported.");
                finish();
            }
            return false;
        }
        return true;
    }
}

vi) AndroidManifest.xml file

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

    <permission android:name="com.androidmastermind.gplaces.permission.MAPS_RECEIVE"
        android:protectionLevel="signature"/>

    <uses-permission android:name="com.androidmastermind.gplaces.permission.MAPS_RECEIVE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

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

    <application
        android:name=".AppController"
        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>

Running the project.

* First, set a location on the emulator.

a) If GPS is disabled



b) If GPS is enabled in your emulator or phone



***That's it, you've successfully loaded all the nearby supermarkets within the radius of 5km and are updated when a user moves for 10m***


See Also:
* Show User's Current Location



Thursday 30 June 2016

Genymotion: Set a location in Running Emulator

Hae there, this is probably one of the simplest things i get to do while running a project that requires location.
By default, a running genymotion virtual device location is disabled and it's usually preset at latitude =65.9667 and longitude = -18.5333

How to enable the location service and adding a custom location.

1. Open Genymotion,






2. Run a virtual device - i like using Google nexus 6 - API 22



3. On the side menu of the emulator, click on the GPS, and a GPS window will popup.



4. Turn the GPS on notice the default latitude and longitude values, those are the onces we are going to change




5. Get the co-ordinate of a place 

- Click here, then scroll down the page, Enter the name of the place you want e.g Technical University of Kenya and press Get GPS Coordinates.
latitude will be = -1.292001
and longitude is= 36.824594



- Copy the latitude and longitude and paste it to the virtual device GPS respectively, leave the rest to default.



- Close the GPS popup window, then you'll be good to go,

*** In case you want the emulator to virtualize your location as if your moving, just get other coordinates and enter them, you'll notice the location changing on the map in real time***

See Also:

* Show User's Current Location

Saturday 25 June 2016

Android Google Maps: Show current Location

Today im gonna show you how to create an android app that shows your current location on the map

Project Structure:



Procedure:
1. To start with, Create an new android project,
Go to start 'start a new project' from the welcome screen > Name it 'CurrentLocation' > Choose 'Google maps activity' *This is the main point* and finish to create the project.

2. After gradle has synced successfully, android studio will open google_maps_api.xml by default. in this xml file, we are required to get our api key from google console and replace it where there is this
phrase "YOUR_KEY_HERE"


 


* Android studio makes it very easy to get the api key because after creating the project, the hash signature is already written in the google_maps_api.xml file.

- Copy the url from the file and paste it to your browser, e.g in my case it's on line 7 in my editor,

https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=
8F:D7:78:DF:61:AB:F8:5B:53:E9:48:39:56:D4:3B:1F:05:E3:4E:05%3Bcom.androidmastermind.currentlocation

> Rememeber to use your projects url, else it won't work.

- The link takes you straight to google api console which will prompt you to enable the maps api by creating a project

- After the page loads, just click on continue...,  A project will be created as 'My Project' ,(will change this later)



-  Another page will load after some few seconds, click on 'Go to credentials'



- A page will load with the package name of your app and the sha-1 certificate fingerprint, You can rename the key the way you want, for my case ill leave it to default and press create.



- A popup window will appear with your api key, just copy it and click ok. At this point we are done with the console,



-  Go back to our android project, in the google_maps_api.xml, paste the api key

<resources>
    <!--    TODO: Before you run your application, you need a Google Maps API key.

    To get one, follow this link, follow the directions and press "Create" at the end:
    https://console.developers.google.com/flows/enableapi?
apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=
8F:D7:78:DF:61:AB:F8:5B:53:E9:48:39:56:D4:3B:1F:05:E3:4E:05%
3Bcom.androidmastermind.currentlocation
    You can also add your credentials to an existing key, using this line:
    8F:D7:78:DF:61:AB:F8:5B:53:E9:48:39:56:D4:3B:1F:05:E3:4E:05;com.androidmastermind.currentlocation
    Alternatively, follow the directions here:
    https://developers.google.com/maps/documentation/android/start#get-key
    Once you have your key (it starts with "AIza"), replace the "google_maps_key"    string in this file.    -->
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">
AIzaSyBIfHPW-nb4JdNK1TlWuV3XiVIWhmuDvqwN</string>
</resources>

- You can now test your app and see if it displays a map, by default, your supposed to see a map with a marker, if you click it it will popup with 'marker in sydney'
- For this, just fire up genymotion, or plug your device in debug mode.




- Now lets go back to our MainActivity.java and make some changes,
- first thing we will implement LocationListener, this will be monitoring the location in case you move from the current location.
* Be careful to import <<import android.location.LocationListener;>> for the locationlistner, else you may meet some errors later.


- Will also create a method, getCurrentLocation(), that will be fethching the current location, and check if google play services are available before displaying the location.

package com.androidmastermind.currentlocation;

import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,LocationListener {

    private static final String TAG = "CurrentLocation";
    private GoogleMap mMap;
    protected LocationManager locationManager;
    private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;


    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!isGooglePlayServicesAvailable()) {
            return;
        }
        setContentView(R.layout.activity_maps);

        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }


    /**     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        displayCurrentLocation(mMap);
    }

    private void displayCurrentLocation(GoogleMap mMap) {
        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 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;
        }
        mMap.setMyLocationEnabled(true);
        mMap.getUiSettings().setCompassEnabled(true);
        mMap.getUiSettings().setZoomControlsEnabled(true);

        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        Criteria criteria = new Criteria();
        String bestProvider = locationManager.getBestProvider(criteria, true);
        Location location = locationManager.getLastKnownLocation(bestProvider);

        if (location != null) {
            onLocationChanged(location);

        }

        locationManager.requestLocationUpdates(bestProvider, 20000, 0, this);

    }

    private boolean isGooglePlayServicesAvailable() {
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (apiAvailability.isUserResolvableError(resultCode)) {
                apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.i(TAG, "This device is not supported.");
                finish();
            }
            return false;
        }
        return true;
    }

    @Override    public void onLocationChanged(Location location) {
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();

        LatLng currentLocation = new LatLng(latitude, longitude);
        mMap.addMarker(new MarkerOptions().position(currentLocation).title("My Location"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(currentLocation));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }
}

* That's it, you've successfully created an app that monitors your current location.




> My current location was at Technical University of Kenya
* Run it on a real device to see how it behaves when you move around and change location

See Also:
* Show Nearby Places From a User's Location