Membuat Pencarian Tempat terdekat (Search Nearby Place) Menggunakan Google Map Berbasis Android

Google menyediakan API untuk mencari informasi tempat pada berbagai kategori, seperti: perusahaan, tempat menarik, lokasi geografis, dan lainnya.

Anda dapat mencari tempat bedasarkan kedekatan dengan lokasi Anda dengan menentukan lokasi berdasarkan jarak radius yang anda sesuaikan, lebih jelasnya anda bisa mengunjungi developers google

Kali ini, API yang kita gunakan untuk mencari tempat terdekat menggunakan api berikut

https://maps.googleapis.com/maps/api/place/nearbysearch/json?

Dari API diatas ada parameter yang harus diprelukan antara lain:

  • key - Kunci API aplikasi yang harus anda buat untuk ditempatkan di parameter key

  • location - Menentukan lokasi dari Lintang (Latitude) dan Bujur (Longitude)

  • radius - Menentukan jarak (dalam meter) seberapa jauh tempat yang akan tampil. Radius Maksimum yang diperbolehkan adalah 50.000 meter. Catatan: radius tidak boleh dibasukan jika rankby=distance

  • Jika rankby=distance yang ditentukan maka satu atau lebih dari keyword, name atau type diperlukan.

Sebagai contoh dari parameter tersebut bisa diterapkan seperti berikut:

https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670522,151.1957362&radius=1500&type=restaurant&keyword=cruise&key=YOUR_API_KEY

Ok saatnya kita membuat aplikasinya, yang harus anda lakukan terlebih dahulu adalah membuat API Key yang dapat anda buat di situs developers google.

Membuat Project Baru

Buat project dengan nama Google Map, jika anda sudah membuat project langkah selanjutnya dibagain gradle tambahkan beberapa dependencies berikut:

implementation 'com.google.android.gms:play-services-maps:16.1.0'
implementation 'com.google.android.gms:play-services-location:16.0.0'
implementation 'com.google.android.gms:play-services-places:16.0.0'
implementation 'com.google.android.libraries.places:places-compat:1.1.0'

Langkah selanjutnya menambahkan dibagian manifests uses permission dan meta data

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

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

Salin api key yang sebelumnya di dapat dari developers google, kemudian tempatka dibagain res -> values -> google_maps_api.xml

<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=A1:BC:B2:E3:AF:4D:D6:55:23:77:76:F2:A7:5F:03:F0:1C:E0:D9:C4%3Bcom.kodetr.googlemap

    You can also add your credentials to an existing key, using these values:

    Package name:
    A1:BC:B2:E3:AF:4D:D6:55:23:77:76:F2:A7:5F:03:F0:1C:E0:D9:C4

    SHA-1 certificate fingerprint:
    A1:BC:B2:E3:AF:4D:D6:55:23:77:76:F2:A7:5F:03:F0:1C:E0:D9:C4

    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">YOUR_API_KEY</string>
</resources>

Menggambil data dari json yang didapat dari response api untuk ditampung didalam HashMap

package com.kodetr.googlemap.nearbyplaces;

import android.util.Log;

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

import java.util.HashMap;

/**
 * Created by kodetr on 01/04/19.
 */
public class DataParser {

    private HashMap<String, String> getPlace(JSONObject googlePlaceJson) {
        HashMap<String, String> googlePlaceMap = new HashMap<String, String>();
        String placeName = "-NA-";
        String vicinity = "-NA-";
        String latitude = "";
        String longitude = "";
        String reference = "";

        Log.d("getPlace", "Entered");

        try {
            if (!googlePlaceJson.isNull("name")) {
                placeName = googlePlaceJson.getString("name");
            }
            if (!googlePlaceJson.isNull("vicinity")) {
                vicinity = googlePlaceJson.getString("vicinity");
            }
            latitude = googlePlaceJson.getJSONObject("geometry").getJSONObject("location").getString("lat");
            longitude = googlePlaceJson.getJSONObject("geometry").getJSONObject("location").getString("lng");
            reference = googlePlaceJson.getString("reference");
            googlePlaceMap.put("place_name", placeName);
            googlePlaceMap.put("vicinity", vicinity);
            googlePlaceMap.put("lat", latitude);
            googlePlaceMap.put("lng", longitude);
            googlePlaceMap.put("reference", reference);
            Log.d("getPlace", "Putting Places");
        } catch (JSONException e) {
            Log.d("getPlace", "Error");
            e.printStackTrace();
        }
        return googlePlaceMap;
    }
}

Menambahkan fungsi untuk menampung data dari fungsi getPlace untuk ditampung didalam List

  private List<HashMap<String, String>> getPlaces(JSONArray jsonArray) {
        int placesCount = jsonArray.length();
        List<HashMap<String, String>> placesList = new ArrayList<>();
        HashMap<String, String> placeMap = null;
        Log.d("Places", "getPlaces");

        for (int i = 0; i < placesCount; i++) {
            try {
                placeMap = getPlace((JSONObject) jsonArray.get(i));
                placesList.add(placeMap);
                Log.d("Places", "Adding places");

            } catch (JSONException e) {
                Log.d("Places", "Error in Adding places");
                e.printStackTrace();
            }
        }
        return placesList;
    }

Selanjutnya menambahkan fungsi untuk melakukan parsing data

public List<HashMap<String, String>> parse(String jsonData) {
        JSONArray jsonArray = null;
        JSONObject jsonObject;

        try {
            Log.d("Places", "parse");
            jsonObject = new JSONObject(jsonData);
            jsonArray = jsonObject.getJSONArray("results");
        } catch (JSONException e) {
            Log.d("Places", "parse error");
            e.printStackTrace();
        }
        return getPlaces(jsonArray);
    }

Membuat proses koneksi dari url api yang sudah terkoneksi, kemudian di inputan setelah itu dilakuan BufferedReader untuk membaca dari hasil inputan, jika sudah selesai maka akan memanggil proses memutuskan koneksi.

package com.kodetr.googlemap.nearbyplaces;

import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by kodetr on 01/04/19.
 */
public class DownloadUrl {

    public String readUrl(String strUrl) throws IOException {
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(strUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.connect();
            iStream = urlConnection.getInputStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

            StringBuffer sb = new StringBuffer();
            String line = "";
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

            data = sb.toString();
            Log.d("downloadUrl", data);
            br.close();

        } catch (Exception e) {
            Log.d("Exception", e.toString());
        } finally {
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }
}

Menampilkan hasil dari pencarian tempat, kembalian berupa response dari api.

package com.kodetr.googlemap.nearbyplaces;

import android.os.AsyncTask;
import android.util.Log;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import java.util.HashMap;
import java.util.List;

/**
 * Created by kodetr on 01/04/19.
 */
public class GetNearbyPlacesData extends AsyncTask<Object, String, String> {

    String googlePlacesData;
    GoogleMap mMap;
    String url;

    @Override
    protected String doInBackground(Object... params) {
        try {
            mMap = (GoogleMap) params[0];
            url = (String) params[1];
            DownloadUrl downloadUrl = new DownloadUrl();
            googlePlacesData = downloadUrl.readUrl(url);
        } catch (Exception e) {
            Log.d("GooglePlacesReadTask", e.toString());
        }
        return googlePlacesData;
    }

    @Override
    protected void onPostExecute(String result) {
        List<HashMap<String, String>> nearbyPlacesList = null;
        DataParser dataParser = new DataParser();
        nearbyPlacesList =  dataParser.parse(result);
        ShowNearbyPlaces(nearbyPlacesList);
    }

    private void ShowNearbyPlaces(List<HashMap<String, String>> nearbyPlacesList) {
        for (int i = 0; i < nearbyPlacesList.size(); i++) {
            MarkerOptions markerOptions = new MarkerOptions();
            HashMap<String, String> googlePlace = nearbyPlacesList.get(i);
            double lat = Double.parseDouble(googlePlace.get("lat"));
            double lng = Double.parseDouble(googlePlace.get("lng"));
            String placeName = googlePlace.get("place_name");
            String vicinity = googlePlace.get("vicinity");
            LatLng latLng = new LatLng(lat, lng);
            markerOptions.position(latLng);
            markerOptions.title(placeName + " : " + vicinity);
            mMap.addMarker(markerOptions);
            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
            //move map camera
            mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
            mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
        }
    }
}

Jika proses sudah diikuti dengan benar dan tidak ada error, berikutnya membuat design dimana anda bisa melihat hasil berupa dalam bentuk map, dibagian layout yang harus ditambahkan berupa mapFragment untuk menampilkan map, kemudian ada fungsi pencarian dengan menambahkan PlaceAutocompleteFragment

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MapsActivity">

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

    <LinearLayout
        android:layout_margin="20dp"
        android:background="@android:color/white"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <fragment
            android:id="@+id/place_autocomplete_fragment"
            android:name="com.google.android.libraries.places.compat.ui.PlaceAutocompleteFragment"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
</RelativeLayout>

Menampilkan lokasi marker dengan menentukan Lintang (Latitude) dan Bujur (Longitude) sebagi lokasi default dibagian method onMapReady dengan menggambil parameter dari GoogleMap.

@Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 8.5f));
        mMap.addMarker(new MarkerOptions()
                .position(sydney)
                .title("www.kodetr.com")
                .snippet("lokasi saya")
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
    }

Menggambil result dari PlaceAutocomplete dengan cara membuat action select

private void setupAutoCompleteFragment() {
    PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)
            getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
        autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
        @Override
        public void onPlaceSelected(Place place) {

        }

        @Override
        public void onError(Status status) {
        Log.e("Error", status.getStatusMessage());
        }
    });
}

Selanjutnya membuat fungsi untuk mengambil lokasi lintang dan bunjur yang didapat dari pencari menggunakan PlaceAutocomplete. Anda bisa masukan langsung url api beserta api key yang didapat dari langkah sebelumnya.

 private String getUrl(double latitude, double longitude, String nearbyPlace) {
    StringBuilder googlePlacesUrl = new StringBuilder(getString(R.string.nearby_url_api));
    googlePlacesUrl.append("location=" + latitude + "," + longitude);
    googlePlacesUrl.append("&radius=" + PROXIMITY_RADIUS_METERS);
    googlePlacesUrl.append("&type=" + nearbyPlace);
    googlePlacesUrl.append("&sensor=true");
    googlePlacesUrl.append("&key=" + getString(R.string.google_maps_key));
    Log.d("getUrl", googlePlacesUrl.toString());

    return (googlePlacesUrl.toString());
}

Anda dapat melihat kode lengkapnya seperti seperti dibawah

package com.kodetr.googlemap;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;

import com.google.android.gms.common.api.Status;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.libraries.places.compat.Place;
import com.google.android.libraries.places.compat.ui.PlaceAutocompleteFragment;
import com.google.android.libraries.places.compat.ui.PlaceSelectionListener;
import com.kodetr.googlemap.nearbyplaces.GetNearbyPlacesData;

/**
 * Created by kodetr on 01/04/19.
 */

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private LatLng sydney = new LatLng(-8.579892, 116.095239);
    private static final int PROXIMITY_RADIUS_METERS = 15000;
    private MapFragment mapFragment;

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

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

    private void setupAutoCompleteFragment() {
        PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)
                getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
        autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
            @Override
            public void onPlaceSelected(Place place) {
                sydney = place.getLatLng();

                String url = getUrl(sydney.latitude, sydney.longitude, "");
                Object[] DataTransfer = new Object[2];
                DataTransfer[0] = mMap;
                DataTransfer[1] = url;
                Log.d("onClick", url);
                GetNearbyPlacesData getNearbyPlacesData = new GetNearbyPlacesData();
                getNearbyPlacesData.execute(DataTransfer);
            }

            @Override
            public void onError(Status status) {
                Log.e("Error", status.getStatusMessage());
            }
        });
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 8.5f));
        mMap.addMarker(new MarkerOptions()
                .position(sydney)
                .title("www.kodetr.com")
                .snippet("lokasi saya")
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
    }

    private String getUrl(double latitude, double longitude, String nearbyPlace) {
        StringBuilder googlePlacesUrl = new StringBuilder(getString(R.string.nearby_url_api));
        googlePlacesUrl.append("location=" + latitude + "," + longitude);
        googlePlacesUrl.append("&radius=" + PROXIMITY_RADIUS_METERS);
        googlePlacesUrl.append("&type=" + nearbyPlace);
        googlePlacesUrl.append("&sensor=true");
        googlePlacesUrl.append("&key=" + getString(R.string.google_maps_key));
        Log.d("getUrl", googlePlacesUrl.toString());
        return (googlePlacesUrl.toString());
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mMap != null) {
            mMap.clear();
        }
    }
}

Jika semua sudah diikuti dengan benar selanjutnya anda bisa jalan aplikasinya.

Demikian yang dapat saya sampaikan dari artikel ini semoga bermanfaat, jika anda mengalami kesulitan anda bisa melihat vidio yang sudah disediakan atau melalui komentar dibawah, selamat mencoba.

Share Comments
comments powered by Disqus