android.melbournehistorymap.MapsActivity.java Source code

Java tutorial

Introduction

Here is the source code for android.melbournehistorymap.MapsActivity.java

Source

package android.melbournehistorymap;

import android.Manifest;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Typeface;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.places.PlacePhotoMetadata;
import com.google.android.gms.location.places.PlacePhotoMetadataBuffer;
import com.google.android.gms.location.places.PlacePhotoMetadataResult;
import com.google.android.gms.location.places.PlacePhotoResult;
import com.google.android.gms.location.places.Places;
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.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.maps.android.SphericalUtil;

import java.io.UnsupportedEncodingException;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private static final long delay = 200L;
    String mode;
    String CurrLat;
    String CurrLong;
    RelativeLayout smallTile;
    RelativeLayout expandedTile;
    int ZOOM_RESTRICT_LEVEL = 15;
    ProgressBar spinner;
    private GoogleMap mMap;
    private Marker prevMarker;
    private int dirtyMarker = 0;
    private GoogleApiClient mGoogleApiClient;
    private LatLngBounds MELBOURNE = new LatLngBounds(new LatLng(-37.868764, 144.825287),
            new LatLng(-37.764955, 145.094594));
    private ResultCallback<PlacePhotoResult> mDisplayPhotoResultCallback = new ResultCallback<PlacePhotoResult>() {
        @Override
        public void onResult(PlacePhotoResult placePhotoResult) {

            ImageView mImageView = (ImageView) findViewById(R.id.imageView);
            ImageView mImageViewExpanded = (ImageView) findViewById(R.id.headerImage);
            if (!placePhotoResult.getStatus().isSuccess()) {
                return;
            }
            mImageView.setImageBitmap(placePhotoResult.getBitmap());
            mImageViewExpanded.setImageBitmap(placePhotoResult.getBitmap());
        }
    };
    //Source:
    //http://dimitar.me/how-to-detect-a-user-pantouchdrag-on-android-map-v2/
    private long lastTouched = 0;

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

        Typeface iconFont = FontManager.getTypeface(getApplicationContext(), FontManager.FONTAWESOME);
        FontManager.markAsIconContainer(findViewById(R.id.main_content), iconFont);

        Typeface medFont = FontManager.getTypeface(getApplicationContext(), FontManager.ROBO_MEDIUM);
        FontManager.markAsIconContainer(findViewById(R.id.placeDescription), medFont);
        FontManager.markAsIconContainer(findViewById(R.id.placeVic), medFont);
        FontManager.markAsIconContainer(findViewById(R.id.fullArticle), medFont);

        Typeface regFont = FontManager.getTypeface(getApplicationContext(), FontManager.ROBO_REG);
        FontManager.markAsIconContainer(findViewById(R.id.expPlaceVic), regFont);

        Typeface thinFont = FontManager.getTypeface(getApplicationContext(), FontManager.ROBO_THIN);
        //FontManager.markAsIconContainer(findViewById(R.id.placeDistance), thinFont);
        FontManager.markAsIconContainer(findViewById(R.id.expPlaceDistance), thinFont);
        FontManager.markAsIconContainer(findViewById(R.id.wikiLicense), thinFont);

        Typeface lightFont = FontManager.getTypeface(getApplicationContext(), FontManager.ROBO_LIGHT);
        FontManager.markAsIconContainer(findViewById(R.id.expPlaceDistance), lightFont);
        FontManager.markAsIconContainer(findViewById(R.id.photoAttribute), lightFont);
        FontManager.markAsIconContainer(findViewById(R.id.expPhotoAttribute), lightFont);

        Typeface boldFont = FontManager.getTypeface(getApplicationContext(), FontManager.ROBO_BOLD);
        FontManager.markAsIconContainer(findViewById(R.id.expPlaceTitle), boldFont);
        FontManager.markAsIconContainer(findViewById(R.id.placeTitle), boldFont);

        // 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);

        TextView fab = (TextView) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //                Snackbar.make(view, "Show history", Snackbar.LENGTH_LONG)
                //                        .setAction("Action", null).show();
                expandTile(view);
            }
        });

        Bundle extras = getIntent().getExtras();
        CurrLat = extras.getString("CLoc_Lat");
        CurrLong = extras.getString("CLoc_Long");

        smallTile = (RelativeLayout) findViewById(R.id.tile);
        expandedTile = (RelativeLayout) findViewById(R.id.expandedTile);

        //Initiliase connection to Google Places API
        mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).addApi(Places.GEO_DATA_API).addApi(LocationServices.API)
                .addApi(Places.PLACE_DETECTION_API).build();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_list) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * 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;
        spinner = (ProgressBar) findViewById(R.id.prograssSpinner);
        //check if permission has been granted
        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // Permission has already been granted
            return;
        }
        mMap.setMyLocationEnabled(true);
        mMap.getUiSettings().setZoomControlsEnabled(false);

        double lat;
        double lng;
        final int radius;
        int zoom;

        lat = Double.parseDouble(CurrLat);
        lng = Double.parseDouble(CurrLong);

        //build current location
        LatLng currentLocation = new LatLng(lat, lng);
        final LatLng realLocation = currentLocation;

        if (MELBOURNE.contains(currentLocation)) {
            mMap.getUiSettings().setMyLocationButtonEnabled(true);
            zoom = 17;
        } else {
            mMap.getUiSettings().setMyLocationButtonEnabled(false);
            lat = -37.81161508043379;
            lng = 144.9647320434451;
            zoom = 15;
            currentLocation = new LatLng(lat, lng);
        }

        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLocation, 13));

        CameraPosition cameraPosition = new CameraPosition.Builder().target(currentLocation) // Sets the center of the map to location user
                .zoom(zoom) // Sets the zoom
                .bearing(0) // Sets the orientation of the camera to east
                .tilt(25) // Sets the tilt of the camera to 30 degrees
                .build(); // Creates a CameraPosition from the builder

        //Animate user to map location, if in Melbourne or outside of Melbourne bounds
        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),
                new GoogleMap.CancelableCallback() {
                    @Override
                    public void onFinish() {
                        updateMap();
                    }

                    @Override
                    public void onCancel() {

                    }
                });

        final TextView placeTitle = (TextView) findViewById(R.id.placeTitle);
        final TextView placeVic = (TextView) findViewById(R.id.placeVic);
        final TextView expPlaceTitle = (TextView) findViewById(R.id.expPlaceTitle);
        final TextView expPlaceVic = (TextView) findViewById(R.id.expPlaceVic);
        final TextView expPlaceDescription = (TextView) findViewById(R.id.placeDescription);
        final TextView wikiLicense = (TextView) findViewById(R.id.wikiLicense);
        final TextView expPlaceDistance = (TextView) findViewById(R.id.expPlaceDistance);
        final RelativeLayout tile = (RelativeLayout) findViewById(R.id.tile);
        final TextView fab = (TextView) findViewById(R.id.fab);
        final RelativeLayout distanceCont = (RelativeLayout) findViewById(R.id.distanceContainer);

        //        String license = "Text is available under the <a rel=\"license\" href=\"//en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License\">Creative Commons Attribution-ShareAlike License</a><a rel=\"license\" href=\"//creativecommons.org/licenses/by-sa/3.0/\" style=\"display:none;\"></a>;\n" +
        //                "additional terms may apply.";
        //        wikiLicense.setText(Html.fromHtml(license));
        //        wikiLicense.setMovementMethod(LinkMovementMethod.getInstance());
        //Marker click
        mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {

            @Override
            public boolean onMarkerClick(Marker marker) {
                String title = marker.getTitle();
                mMap.setPadding(0, 0, 0, 620);
                //set clicked marker to full opacity
                marker.setAlpha(1f);
                //set previous marker back to partial opac (if there is a prevMarker
                if (dirtyMarker == 1) {
                    prevMarker.setAlpha(0.6f);
                }
                prevMarker = marker;
                dirtyMarker = 1;

                //Set DB helper
                DBHelper myDBHelper = new DBHelper(MapsActivity.this, WikiAPI.DB_NAME, null, WikiAPI.VERSION);

                //Only search for Wiki API requests if no place article returned.
                // **
                //Open DB as readable only.
                SQLiteDatabase db = myDBHelper.getReadableDatabase();
                //Set the query
                String dbFriendlyName = title.replace("\'", "\'\'");
                //Limit by 1 rows
                Cursor cursor = db.query(DBHelper.TABLE_NAME, null, "PLACE_NAME = '" + dbFriendlyName + "'", null,
                        null, null, null, "1");

                //move through each row returned in the query results
                while (cursor.moveToNext()) {

                    String place_ID = cursor.getString(cursor.getColumnIndex("PLACE_ID"));
                    String placeName = cursor.getString(cursor.getColumnIndex("PLACE_NAME"));
                    String placeLoc = cursor.getString(cursor.getColumnIndex("PLACE_LOCATION"));
                    String placeArticle = cursor.getString(cursor.getColumnIndex("ARTICLE"));
                    String placeLat = cursor.getString(cursor.getColumnIndex("LAT"));
                    String placeLng = cursor.getString(cursor.getColumnIndex("LNG"));

                    //Get Google Place photos
                    //Source: https://developers.google.com/places/android-api/photos
                    final String placeId = place_ID;
                    Places.GeoDataApi.getPlacePhotos(mGoogleApiClient, placeId)
                            .setResultCallback(new ResultCallback<PlacePhotoMetadataResult>() {
                                @Override
                                public void onResult(PlacePhotoMetadataResult photos) {
                                    if (!photos.getStatus().isSuccess()) {
                                        return;
                                    }
                                    ImageView mImageView = (ImageView) findViewById(R.id.imageView);
                                    ImageView mImageViewExpanded = (ImageView) findViewById(R.id.headerImage);
                                    TextView txtAttribute = (TextView) findViewById(R.id.photoAttribute);
                                    TextView expTxtAttribute = (TextView) findViewById(R.id.expPhotoAttribute);
                                    PlacePhotoMetadataBuffer photoMetadataBuffer = photos.getPhotoMetadata();
                                    if (photoMetadataBuffer.getCount() > 0) {
                                        // Display the first bitmap in an ImageView in the size of the view
                                        photoMetadataBuffer.get(0).getScaledPhoto(mGoogleApiClient, 600, 200)
                                                .setResultCallback(mDisplayPhotoResultCallback);
                                        //get photo attributions
                                        PlacePhotoMetadata photo = photoMetadataBuffer.get(0);
                                        CharSequence attribution = photo.getAttributions();
                                        if (attribution != null) {
                                            txtAttribute.setText(Html.fromHtml(String.valueOf(attribution)));
                                            expTxtAttribute.setText(Html.fromHtml(String.valueOf(attribution)));
                                            //http://stackoverflow.com/questions/4303160/how-can-i-make-links-in-fromhtml-clickable-android
                                            txtAttribute.setMovementMethod(LinkMovementMethod.getInstance());
                                            expTxtAttribute.setMovementMethod(LinkMovementMethod.getInstance());
                                        } else {
                                            txtAttribute.setText(" ");
                                            expTxtAttribute.setText(" ");
                                        }
                                    } else {
                                        //Reset image view as no photo was identified
                                        mImageView.setImageResource(android.R.color.transparent);
                                        mImageViewExpanded.setImageResource(android.R.color.transparent);
                                        txtAttribute.setText(R.string.no_photos);
                                        expTxtAttribute.setText(R.string.no_photos);
                                    }
                                    photoMetadataBuffer.release();
                                }
                            });

                    LatLng destLocation = new LatLng(Double.parseDouble(placeLat), Double.parseDouble(placeLng));
                    //Work out distance between current location and place location
                    //Source Library: https://github.com/googlemaps/android-maps-utils
                    double distance = SphericalUtil.computeDistanceBetween(realLocation, destLocation);
                    distance = Math.round(distance);
                    distance = distance * 0.001;
                    String strDistance = String.valueOf(distance);
                    String[] arrDistance = strDistance.split("\\.");
                    String unit = "km";
                    if (arrDistance[0] == "0") {
                        unit = "m";
                        strDistance = arrDistance[1];
                    } else {
                        strDistance = arrDistance[0] + "." + arrDistance[1].substring(0, 1);
                    }

                    placeArticle = placeArticle
                            .replaceAll("(<div class=\"thumb t).*\\s.*\\s.*\\s.*\\s.*\\s<\\/div>\\s<\\/div>", " ");

                    Spannable noUnderlineMessage = new SpannableString(Html.fromHtml(placeArticle));

                    //http://stackoverflow.com/questions/4096851/remove-underline-from-links-in-textview-android
                    for (URLSpan u : noUnderlineMessage.getSpans(0, noUnderlineMessage.length(), URLSpan.class)) {
                        noUnderlineMessage.setSpan(new UnderlineSpan() {
                            public void updateDrawState(TextPaint tp) {
                                tp.setUnderlineText(false);
                            }
                        }, noUnderlineMessage.getSpanStart(u), noUnderlineMessage.getSpanEnd(u), 0);
                    }

                    placeArticle = String.valueOf(noUnderlineMessage);
                    placeArticle = placeArticle.replaceAll("(\\[\\d\\])", " ");

                    placeTitle.setText(placeName);
                    expPlaceTitle.setText(placeName);
                    placeVic.setText(placeLoc);
                    expPlaceVic.setText(placeLoc);
                    expPlaceDescription.setText(placeArticle);
                    if (MELBOURNE.contains(realLocation)) {
                        expPlaceDistance.setText("Distance: " + strDistance + unit);
                        distanceCont.setVisibility(View.VISIBLE);
                    }
                }

                tile.setVisibility(View.VISIBLE);
                fab.setVisibility(View.VISIBLE);
                //Set to true to not show default behaviour.
                return false;
            }
        });

        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                int viewStatus = tile.getVisibility();
                if (viewStatus == View.VISIBLE) {
                    tile.setVisibility(View.INVISIBLE);
                    fab.setVisibility(View.INVISIBLE);
                    //set previous marker back to partial opac (if there is a prevMarker
                    if (dirtyMarker == 1) {
                        prevMarker.setAlpha(0.6f);
                    }
                }

                mMap.setPadding(0, 0, 0, 0);
            }
        });

        FloatingActionButton shareIcon = (FloatingActionButton) findViewById(R.id.shareIcon);
        shareIcon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //https://www.google.com.au/maps/place/Federation+Square/@-37.8179789,144.9668635,15z

                //Build implicit intent by triggering a SENDTO action, which will capture applications that allow for messages
                //that allow for messages to be sent to a specific user with data
                //http://developer.android.com/reference/android/content/Intent.html#ACTION_SENDTO
                Intent intent = new Intent(Intent.ACTION_SEND);
                intent.setType("text/plain");
                //Build SMS
                String encodedPlace = "empty";
                try {
                    encodedPlace = URLEncoder.encode(String.valueOf(expPlaceTitle.getText()), "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                intent.putExtra(Intent.EXTRA_TEXT, String.valueOf(expPlaceTitle.getText())
                        + " \n\nhttps://www.google.com.au/maps/place/" + encodedPlace);
                Intent sms = Intent.createChooser(intent, null);
                startActivity(sms);
            }
        });

        TextView fullArticle = (TextView) findViewById(R.id.fullArticle);
        fullArticle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String wikiPlace = WikiPlace.getName(String.valueOf(expPlaceTitle.getText()));
                String url = "https://en.wikipedia.org/wiki/" + wikiPlace;

                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(browserIntent);
            }
        });
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            lastTouched = SystemClock.uptimeMillis();
            break;
        case MotionEvent.ACTION_UP:
            final long now = SystemClock.uptimeMillis();
            if (now - lastTouched > delay) {
                //check if place details is open, if not then update the map
                if (expandedTile.getVisibility() == View.GONE) {
                    // Update the map
                    updateMap();
                }
            }
            break;
        }
        return super.dispatchTouchEvent(ev);
    }

    private void updateMap() {

        //Now get the maps central location
        LatLng mapCenter = mMap.getCameraPosition().target;
        //clear markers
        mMap.clear();

        //if user tries to zoom to far out of the world, bring them back down to earth...
        if (mMap.getCameraPosition().zoom < ZOOM_RESTRICT_LEVEL) {
            CameraPosition cameraPosition = new CameraPosition.Builder().target(mapCenter) // Sets the center of the map to location user
                    .zoom(ZOOM_RESTRICT_LEVEL) // Sets the zoom
                    .bearing(0) // Sets the orientation of the camera to east
                    .tilt(25) // Sets the tilt of the camera to 30 degrees
                    .build(); // Creates a CameraPosition from the builder

            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
        }

        //rebuild lat/lng variable to be used for Google Places API requests
        double lat = mapCenter.latitude;
        double lng = mapCenter.longitude;
        double zoom = mMap.getCameraPosition().zoom;

        LatLng leftBorder = mMap.getProjection().getVisibleRegion().farLeft;

        //Work out distance between current location and place location
        //Source Library: https://github.com/googlemaps/android-maps-utils

        double radius = SphericalUtil.computeDistanceBetween(mapCenter, leftBorder);

        //Now that we have the new long/latitude of the camera position include zoom level
        //Lets check the database to determine if the user has been here already
        //Set DB helper
        DBHelper myDBHelper = new DBHelper(MapsActivity.this, WikiAPI.DB_NAME, null, WikiAPI.VERSION);
        //Open DB as readable only.
        SQLiteDatabase db = myDBHelper.getWritableDatabase();
        //Prepare DB Search variables
        DecimalFormat dfLat = new DecimalFormat("#.##");
        DecimalFormat dfLng = new DecimalFormat("#.##");
        DecimalFormat dfZoom = new DecimalFormat("#");
        dfLat.setRoundingMode(RoundingMode.CEILING);
        dfLng.setRoundingMode(RoundingMode.CEILING);
        dfZoom.setRoundingMode(RoundingMode.CEILING);
        double dblLat = Double.parseDouble(dfLat.format(lat));
        double dblLng = Double.parseDouble(dfLng.format(lng));
        double dblZoom = Double.parseDouble(dfZoom.format(zoom));
        //Limit by 1 rows
        Cursor cursor = db.query(DBHelper.LOC_TABLE, null,
                "LAT LIKE '" + dblLat + "%' AND LNG LIKE '" + dblLng + "%' AND ZOOM = '" + dblZoom + "'", null,
                null, null, null, "1");

        int count = cursor.getCount();

        if (count == 0) {
            //user has not been to this location/zoom level  before
            //add the new location data, then trigger the google place webservice api
            ContentValues values = new ContentValues();

            values.put("lat", String.valueOf(dblLat));
            values.put("lng", String.valueOf(dblLng));
            values.put("zoom", String.valueOf(dblZoom));
            db.insert(DBHelper.LOC_TABLE, null, values);

            String url;
            url = updateURL(lat, lng, radius);
            List<List<String>> googlePlaces = null; //null on first reference, the list is updated within the method callstack
            db.close();

            GoogleAPI.callMapMethod(mMap, url, MapsActivity.this, googlePlaces, spinner);
        }
        if (count == 1) {
            //user has been here before
            //get place data from DB and not from the API
            //if place data returned hasn't been updated in 30 days - update data using getPlaceByID method
            Cursor placeCursor = db.query(DBHelper.TABLE_NAME, null, "PLACE_TYPES LIKE '%point_of_interest%'", null,
                    null, null, null, null);

            List<List<String>> googlePlaces = new ArrayList<List<String>>();

            while (placeCursor.moveToNext()) {
                String place_ID = placeCursor.getString(placeCursor.getColumnIndex("PLACE_ID"));
                String placeName = placeCursor.getString(placeCursor.getColumnIndex("PLACE_NAME"));
                String placeLoc = placeCursor.getString(placeCursor.getColumnIndex("PLACE_LOCATION"));
                String placeLat = placeCursor.getString(placeCursor.getColumnIndex("LAT"));
                String placeLng = placeCursor.getString(placeCursor.getColumnIndex("LNG"));

                //if lat and long from database is in the search bounds, add to the list of data to be shown
                LatLngBounds SEARCH_BOUNDS = mMap.getProjection().getVisibleRegion().latLngBounds;
                LatLng search_loc = new LatLng(Double.parseDouble(placeLat), Double.parseDouble(placeLng));

                if (SEARCH_BOUNDS.contains(search_loc)) {
                    //now what data do we want?
                    //Initiate a place data array
                    List<String> placeData = new ArrayList<String>();

                    //add place data to its array
                    placeData.add(placeName); //0
                    placeData.add(place_ID); //1
                    placeData.add(placeLoc); //2
                    placeData.add(String.valueOf(placeLat)); //3
                    placeData.add(String.valueOf(placeLng)); //4
                    placeData.add(""); //5
                    placeData.add(""); //6

                    //send the place specific data to the google places array list
                    googlePlaces.add(placeData);
                }
            }
            db.close();

            //TODO: Get this method off the main UI thread!
            GoogleAPI.filterPlaces(googlePlaces, mMap, this, spinner);
        }
    }

    private String updateURL(double lat, double lng, double radius) {

        String url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=" + lat + "," + lng
                + "&radius=" + radius + "&key=AIzaSyCHBqlH6N63H8af6VfhNLkfsSaFOwVTbvk";

        return url;
    }

    @Override
    public void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    public void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    @Override
    public void onRestart() {
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        String locationProvider = LocationManager.GPS_PROVIDER;
        Location mLastLocation = locationManager.getLastKnownLocation(locationProvider);

        double lat = mLastLocation.getLatitude();
        double lng = mLastLocation.getLongitude();
        final int radius;
        int zoom;

        //build current location
        LatLng currentLocation = new LatLng(lat, lng);

        if (MELBOURNE.contains(currentLocation)) {
            mMap.getUiSettings().setMyLocationButtonEnabled(true);
            zoom = 17;
        } else {
            mMap.getUiSettings().setMyLocationButtonEnabled(false);
            lat = -37.81161508043379;
            lng = 144.9647320434451;
            zoom = 15;
            currentLocation = new LatLng(lat, lng);
        }

        CameraPosition cameraPosition = new CameraPosition.Builder().target(currentLocation) // Sets the center of the map to location user
                .zoom(zoom) // Sets the zoom
                .bearing(0) // Sets the orientation of the camera to east
                .tilt(25) // Sets the tilt of the camera to 30 degrees
                .build(); // Creates a CameraPosition from the builder

        //Animate user to map location, if in Melbourne or outside of Melbourne bounds
        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition),
                new GoogleMap.CancelableCallback() {
                    @Override
                    public void onFinish() {
                        updateMap();
                    }

                    @Override
                    public void onCancel() {

                    }
                });

        updateMap();
        super.onRestart();
    }

    @Override
    public void onConnected(Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    public void onMapView(View v) {
        Toast.makeText(MapsActivity.this, "Map view", Toast.LENGTH_SHORT).show();
    }

    public void onListView(View v) {
        Intent intent = new Intent(MapsActivity.this, NearMeActivity.class);

        intent.putExtra("CLoc_Lat", CurrLat);
        intent.putExtra("CLoc_Long", CurrLong);

        MapsActivity.this.startActivity(intent);
        Toast.makeText(MapsActivity.this, "List view", Toast.LENGTH_SHORT).show();
    }

    public void onSettingsView(View v) {
        Intent intent = new Intent(MapsActivity.this, AboutActivity.class);

        intent.putExtra("CLoc_Lat", CurrLat);
        intent.putExtra("CLoc_Long", CurrLong);

        MapsActivity.this.startActivity(intent);
        Toast.makeText(MapsActivity.this, "About menu", Toast.LENGTH_SHORT).show();
    }

    public void expandTile(View view) {
        //        Toast.makeText(MapsActivity.this, "Expand", Toast.LENGTH_SHORT).show();
        TextView fab = (TextView) findViewById(R.id.fab);
        FloatingActionButton shareIcon = (FloatingActionButton) findViewById(R.id.shareIcon);
        //hide small tile
        smallTile.setVisibility(View.GONE);
        fab.setVisibility(View.GONE);
        //show big tile
        expandedTile.setVisibility(View.VISIBLE);
        shareIcon.setVisibility(View.VISIBLE);

        //lock the map
        mMap.getUiSettings().setAllGesturesEnabled(false);

        //Reset ScrollView to top
        ScrollView scrollView = (ScrollView) findViewById(R.id.scrollViewDesc);
        scrollView.fullScroll(View.FOCUS_UP);

        //disable mapicon from being clickable
        TextView mapIcon = (TextView) findViewById(R.id.iconMap);
        mapIcon.setClickable(false);
    }

    public void hideTile(View view) {
        TextView fab = (TextView) findViewById(R.id.fab);
        FloatingActionButton shareIcon = (FloatingActionButton) findViewById(R.id.shareIcon);
        //show small tile
        smallTile.setVisibility(View.VISIBLE);
        fab.setVisibility(View.VISIBLE);
        //hide big tile
        expandedTile.setVisibility(View.GONE);
        shareIcon.setVisibility(View.GONE);

        //unlock the map
        mMap.getUiSettings().setAllGesturesEnabled(true);

        //enable mapicon from being clickable
        TextView mapIcon = (TextView) findViewById(R.id.iconMap);
        mapIcon.setClickable(true);
    }

}