Search code examples
androidandroid-studiogoogle-mapskotlingoogle-nearby

Search Nearby Places in Android Studio using Kotlin


I want to search for nearby places (ex: hospitals, schools, general clinics, etc.) in a certain radius of the user's current location. I have successfully managed to get the users current location, but don't know how to look for nearby places in the radius. I have managed to set up the html-attributions to get the nearby places, which looks like the following: https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${location.latitude},${location.longitude}&radius=1500&type=restaurant&key=YOUR_API_KEY (I have put my key)

But I don't seem to know where and how do I implement this Url. Only if someone could tell me how could I use this URL. That too could be of great help! Thank You!

This is my code currently:

package com.sampathpatro.vipalsiddh

import android.content.pm.PackageManager
import android.location.Address
import android.location.Geocoder
import android.location.Location
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
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.Marker
import com.google.android.gms.maps.model.MarkerOptions
import java.io.IOException

class MapsActivity : AppCompatActivity(), OnMapReadyCallback, GoogleMap.OnMarkerClickListener {

 private lateinit var map: GoogleMap
 private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
 private lateinit var lastLocation: Location

private fun placeMarkerOnMap(location: LatLng){
     val markerOptions = MarkerOptions().position(location)
     val titleString = getAddress(location)
     markerOptions.title(titleString)
     map.addMarker(markerOptions)
 }

 private fun getAddress(latLng: LatLng): String {
     val geocoder = Geocoder (this)
     val addresses: List<Address>
     val address: Address?
     var addressText = ""

     try {
         addresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1)

         if (null != addresses && addresses.isNotEmpty()){
             address = addresses[0]
             for (i in 0 until address.maxAddressLineIndex){
                 addressText += if (i==0) address.getAddressLine(i) else
                     "\n" + address.getAddressLine(i)
             }
         }
     } catch (e: IOException){
         Log.e("MapsActivity", e.localizedMessage)
     }
     return  addressText
 }

 companion object {
     private const val LOCATION_PERMISSION_REQUEST_CODE = 1
 }

 private fun setUpMap() {
     if(ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) !=
             PackageManager.PERMISSION_GRANTED) {
         ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
         LOCATION_PERMISSION_REQUEST_CODE)
         return
     }

     map.isMyLocationEnabled = true
     fusedLocationProviderClient.lastLocation.addOnSuccessListener(this) { location ->
         if (location != null){
             lastLocation = location
             val currentLatLng = LatLng(location.latitude, location.longitude)
             placeMarkerOnMap(currentLatLng)
             map.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 12f))
         }
     }
 }

 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     setContentView(R.layout.activity_maps)
     // Obtain the SupportMapFragment and get notified when the map is ready to be used.
     val mapFragment = supportFragmentManager
         .findFragmentById(R.id.map) as SupportMapFragment
     mapFragment.getMapAsync(this)

     fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(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 fun onMapReady(googleMap: GoogleMap) {
     map = googleMap

     map.uiSettings.isZoomControlsEnabled = true
     map.setOnMarkerClickListener(this)
     setUpMap()
 }

 override fun onMarkerClick(p0: Marker?) = false
} ```

Solution

  • Use OkHttp library to safely make API calls. include the library in your gradle file

    Use GSON library with it and it will make this easy for you , for simplicity i will simply get it to work by JSONObject

    in the module level gradle, include this

    implementation("com.squareup.okhttp3:okhttp:4.8.1")
    

    Use this method to make calls

    fun makeApiCall(location:Location){
        val request = Request.Builder().url("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${location.latitude},${location.longitude}&radius=1500&type=restaurant&key=YOUR_API_KEY")
                     .build()
    
        val response = OkHttpClient().newCall(request).execute().body().string()
        val jsonObject = JSONObject(response) // This will make the json below as an object for you
    
        // You can access all the attributes , nested ones using JSONArray and JSONObject here
    
    
    }
    

    When you make a api call , you get something like this as a response

                {
                    "debug_log" : {
                    "line" : []
                    },
                    "html_attributions" : [],
                    "logging_info" : {
                    "experiment_id" : [],
                    "query_geographic_location" : "AU"
                    },
                    "results" : [
                    {
                        "geometry" : {
                            "location" : {
                                "lat" : -33.86879,
                                "lng" : 151.194217
                            }
                        },
                        "icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
                        "id" : "21a0b251c9b8392186142c798263e289fe45b4aa",
                        "name" : "Rhythmboat Cruises",
                        "opening_hours" : {
                            "open_now" : false,
                            "weekday_text" : []
                        },
                        "photos" : [
                            {
                                "height" : 426,
                                "html_attributions" : [
                                "\u003ca href=\"https://www.google.com/maps/views/profile/104066891898402903288\"\u003eRhythmboat Cruises\u003c/a\u003e"
                                ],
                                "photo_reference" : "CmRdAAAA-YL_I_Gk02blOX6S0nKHry8PFu9pDyp3Y9AnqISsa3Eq8mkbdD5mXuu1Fax60s0nSy3iiX-h5j-ztyLHcc1-782MsLQsgLLa4t3ZgDmCMll-a8ABapZGnZwDKByk67LFEhBgedv_u_eYFsEo9ay8jxJjGhTUHKPJ4G82vBJqSNliuv7UlAtclw",
                                "width" : 640
                            }
                        ],
                        "place_id" : "ChIJyWEHuEmuEmsRm9hTkapTCrk",
                        "reference" : "CnRmAAAAvQlMKw-XtxEY4vWFCvudF7CEMQGI5ycNbfVgGl9rAF75fdiPOiLJw1k9NL2v8ZIJsOJuRS3Lm9Dw1vga4ajycAs7PlxN1MVnnYT9la0pBvEvSQNlyvszKANS1R4P7Mvk_jhqswMggqCUtwJ13LN2hRIQOiAkLTWUi3DOjVVOw7J5IRoUb_cJyJaJNqKdmkDM2f0OjQjh9F0",
                        "scope" : "GOOGLE",
                        "types" : [ "restaurant", "food", "point_of_interest", "establishment" ],
                        "vicinity" : "Pyrmont Bay Wharf (Near Australia Maritime Museum), Pyrmont, NSW 2009"
                    },
                    {
                        "geometry" : {
                            "location" : {
                                "lat" : -33.867591,
                                "lng" : 151.201196
                            }
                        },
                        "icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
                        "id" : "a97f9fb468bcd26b68a23072a55af82d4b325e0d",
                        "name" : "Australian Cruise Group",
                        "opening_hours" : {
                            "open_now" : false,
                            "weekday_text" : []
                        },
                        "photos" : [
                            {
                                "height" : 1331,
                                "html_attributions" : [
                                "\u003ca href=\"https://www.google.com/maps/views/profile/110751364053842618118\"\u003eAustralian Cruise Group\u003c/a\u003e"
                                ],
                                "photo_reference" : "CmRdAAAAtEoj29FJcNBccrsu6bHt0xgwVGhYlciCY1fe6gTr_d5_KkeP3LITnOwnpNRJWnX39B04-aIBOKXKJH6ltx948T5vWIYBoah1yZDXsWngWZ5kMsK7xyCB5P_q_xBIBxxUEhAYWeB4PiOm_Jy093fB-j0iGhSYmIs9xB2aa6u-RH8V8lZEk-Q5ig",
                                "width" : 2000
                            }
                        ],
                        "place_id" : "ChIJrTLr-GyuEmsRBfy61i59si0",
                        "reference" : "CnRqAAAAFbukrZvRNsc05TreHUCrPEya5NcN9v0fFLLaK-D1fSyxFTuQlUDhDstU3qwXKw_fADX4W6guUkexax1nufgiYIuGCKoZPEnup1r-LhGGNz9dn1uf9Of5iOtZ1XgCeDjJaYvGbSB3C0pAXL8r9kOsmhIQbx2Sia2DAWTjtSZwuh5aehoUhM6upqBCDLhGruZAGGsCOwAiIq8",
                        "scope" : "GOOGLE",
                        "types" : [
                            "restaurant",
                            "travel_agency",
                            "food",
                            "point_of_interest",
                            "establishment"
                        ],
                        "vicinity" : "32 The Promenade, King Street Wharf 5, Sydney"
                    },
                    {
                        "geometry" : {
                            "location" : {
                                "lat" : -33.870943,
                                "lng" : 151.190311
                            }
                        },
                        "icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/bar-71.png",
                        "id" : "e644f7f34cf875b9919c6548f1b721947362850a",
                        "name" : "Lunch Cruise with Jazz on Sydney Harbour",
                        "opening_hours" : {
                            "open_now" : false,
                            "weekday_text" : []
                        },
                        "photos" : [
                            {
                                "height" : 292,
                                "html_attributions" : [
                                "\u003ca href=\"https://www.google.com/maps/views/profile/105423912060796272053\"\u003eFrom a Google User\u003c/a\u003e"
                                ],
                                "photo_reference" : "CmRdAAAAR4bqFTKYWdBwZwdBdON_JRD7V_joTwwIPwRUpZIZWkSSd8GQ3P2O-_aQbUJdL2RhoAyzCUIF0f--DI4oXFneTpj5zZfFq-iFiT7i_x0tjnDveIY8tJv-6o0uWSSjYqabEhCKqQWZqrKAoddjDcc64N48GhQZ2T1_ntPzNKCooHpZzlYQ7AxFOA",
                                "width" : 438
                            }
                        ],
                        "place_id" : "ChIJLfySpTOuEmsRPCRKrzl8ZEY",
                        "reference" : "CoQBewAAAFd2fO_YWGTiT4RzXWb5tsOuOt7YyV_ScQOwm0tqJSrAyACCczeOzV-P_mgZLro1oKP_34Nt0nVC_1OEKAQUcd7cUm7xmAMSX-EkbSWiD0kOWGgGgKuDRtb0t_8qsxBGU_izugWCyK7SRWezTxELYNdkS0OEiSWPnvhxvXuQktBBEhAAtEe7fagW2kUR14T1QpVsGhQBO7YpIyYSPvo4zUJuL_bX30nJZw",
                        "scope" : "GOOGLE",
                        "types" : [ "bar", "restaurant", "food", "point_of_interest", "establishment" ],
                        "vicinity" : "37 Bank St, Pyrmont"
                        }
                    ],
                        "status" : "OK"
                }