Membuat alat pilih Current Place milik Anda sendiri untuk Android (Java)

1. Sebelum memulai

Pelajari cara menggunakan Google Maps Platform dan Places SDK for Android untuk menampilkan daftar berisi Tempat kepada pengguna Anda untuk mengidentifikasi lokasi mereka saat ini.

bd07a9ad2cb27a06.png

Prasyarat

  • Keterampilan Java Dasar

Yang akan Anda lakukan

  • Menambahkan peta ke aplikasi Android
  • Menggunakan izin akses lokasi untuk menentukan geolokasi pengguna.
  • Mengambil Tempat di dekat lokasi pengguna saat ini.
  • Menampilkan kemungkinan Tempat kepada pengguna untuk mengidentifikasi lokasi mereka saat ini.

Yang akan Anda buat

Anda membuat aplikasi Android dari awal, namun Anda dapat mendownload kode contoh untuk perbandingan saat men-debug. Download kode contoh dari GitHub, atau, jika Anda telah menyiapkan Git untuk penggunaan command-line, masukkan hal berikut:

git clone https://github.com/googlecodelabs/current-place-picker-android.git

Jika Anda menemui masalah (bug kode, kesalahan tata bahasa, kata-kata yang tidak jelas, atau hal lainnya) saat menyelesaikan codelab ini, laporkan masalah tersebut melalui link Laporkan kesalahan di sudut kiri bawah codelab.

2. Mulai

Sebelum memulai codelab ini, Anda perlu menyiapkan hal berikut:

Android Studio

Download Android Studio dari https://developer.android.com/studio.

Jika sudah memiliki Android Studio, pastikan Anda memiliki versi terbaru dengan mengklik Android Studio > Check for Updates....

1f36bae83b64e33.png

Lab ini ditulis menggunakan Android Studio 3.4.

Android SDK

Di Android Studio, Anda dapat mengonfigurasi SDK yang diinginkan menggunakan SDK Manager. Lab ini menggunakan Android Q SDK.

  1. Dari layar selamat datang Android Studio, klik Configure > SDK Manager.

d3fa03c269ec231c.png

  1. Pilih kotak centang SDK yang diinginkan, lalu klik Apply.

Jika Anda belum memiliki SDK, tindakan ini akan mulai mendownload SDK ke komputer Anda.

884e0aa1314f70d.png

Layanan Google Play

Dari SDK manager, Anda juga perlu menginstal layanan Google Play.

  1. Klik tab SDK Tools lalu centang kotak Google Play services.

Update jika status menampilkan Update available.

ad6211fd78f3b629.png

3. Menyiapkan emulator

Untuk menjalankan aplikasi, Anda dapat menghubungkan perangkat Anda sendiri atau menggunakan Android Emulator.

Jika menggunakan perangkat Anda sendiri, langsung buka Petunjuk perangkat asli: Mengupdate Layanan Google Play di bagian akhir halaman ini.

Menambahkan emulator

  1. Dari layar selamat datang Android Studio, klik Configure > AVD Manager.

5dd2d14c9c56d3f9.png

Tindakan ini akan membuka dialog Android Virtual Device Manager.

  1. Klik Create Virtual Device... untuk membuka daftar perangkat yang dapat Anda pilih.

2d44eada384f8b35.png

  1. Pilih perangkat dengan ikon Play d5722488d80cd6be.png di kolom Play Store lalu klik Next.

e0248f1c6e85ab7c.png

Anda akan melihat kumpulan gambar sistem yang dapat diinstal. Jika Q yang menargetkan Android 9.+ (Google Play) memiliki kata Download di sampingnya, klik Download.

316d0d1efabd9f24.png

  1. Klik Next untuk memberi nama pada perangkat virtual Anda, lalu klik Finish.

Anda kembali ke daftar Your Virtual Devices.

  1. Klik Start ba8adffe56d3b678.png di samping perangkat baru Anda:

7605864ed27f77ea.png

Setelah beberapa saat, emulator akan terbuka.

Petunjuk emulator—mengupdate layanan Google Play

  1. Setelah emulator terbuka, klik ... di menu navigasi yang muncul**.**

2e1156e02643d018.png

Tindakan ini akan membuka dialog Extended controls.

  1. Klik Google Play di menu.

Jika update tersedia, klik Update.

5afd2686c5cad0e5.png

  1. Login ke emulator dengan Akun Google.

Anda dapat menggunakan akun sendiri atau membuat akun baru secara gratis agar pengujian dan informasi pribadi Anda selalu terpisah.

Google Play kemudian terbuka di layanan Google Play.

  1. Klik Update untuk mendapatkan layanan Google Play versi terbaru.

f4bc067e80630b9c.png

Jika diminta untuk menyelesaikan penyiapan akun dan menambahkan opsi pembayaran, klik Skip.

Menetapkan lokasi di emulator

  1. Setelah emulator terbuka, ketik "maps" ke kotak penelusuran layar utama untuk menampilkan ikon aplikasi Google Maps.

2d996aadd53685a6.png

  1. Klik ikon untuk membukanya.

Anda akan melihat peta default.

  1. Di kanan bawah peta, klik Your Location c5b4e2fda57a7e71.png.

Anda diminta untuk memberikan izin pada ponsel untuk menggunakan lokasi.

f2b68044eabca151.png

  1. Klik ... untuk membuka menu Extended Control.
  2. Klik tab Location.
  3. Masukkan lintang dan bujur.

Masukkan lintang dan bujur yang Anda inginkan di sini, namun pastikan koordinat tersebut berada di area dengan banyak tempat.

(Gunakan Lintang 20.7818 dan Bujur -156.4624 untuk kota Kihei di Maui, Hawaii untuk mereplikasi hasil dari codelab ini.)

  1. Klik Send dan peta akan diupdate dengan lokasi ini.

f9576b35218f4187.png

Anda siap menjalankan aplikasi dan mengujinya dengan lokasi.

Petunjuk perangkat asli—mengupdate layanan Google Play

Jika Anda menggunakan perangkat Android asli, lakukan hal berikut:

  1. Gunakan kotak penelusuran di layar utama untuk menelusuri dan membuka Google Play services.
  2. Klik More Details.

Jika tersedia, klik Update.

ad16cdb975b5c3f7.png baf0379ef8a9c88c.png

4. Membuat app shell dengan aktivitas Google Maps

  1. Di layar selamat datang Android Studio, pilih Start a new Android Studio project.
  2. Pada tab Phone and Tablet, pilih Google Maps Activity.

c9c80aa8211a8761.png

Dialog Configure your project akan terbuka. Ini adalah tempat Anda memberi nama aplikasi dan membuat paket berdasarkan domain Anda.

Berikut adalah setelan untuk aplikasi yang bernama Current Place, yang sesuai dengan paket com.google.codelab.currentplace.

37f5b93b94ee118c.png

  1. Pilih Java sebagai bahasa lalu pilih Use androidx. artifacts*.

Tetap gunakan setelan default untuk setelan lainnya.

  1. Klik Finish.

5. Menambahkan dependensi Layanan Google ke file build Gradle

Untuk mengakses izin akses lokasi di Android, Anda memerlukan Lokasi Google dan Activity Recognition API dari layanan Google Play. Untuk informasi selengkapnya tentang cara menambahkan ini dan Google Play Services API lainnya, lihat Menyiapkan Layanan Google Play.

Project Android Studio biasanya memiliki dua file build.gradle. Satu untuk keseluruhan project dan satu untuk aplikasi. Jika Anda memiliki penjelajah Project Android Studio dalam tampilan Android, Anda dapat melihat keduanya di folder Gradle Scripts. Anda perlu mengedit file build.gradle (Module: app) untuk menambahkan layanan Google.

f3043429cf719c47.png

  1. Tambahkan dua baris ke bagian dependencies untuk menambahkan layanan Google untuk lokasi dan Places API (kode contoh dalam konteks).

build.gradle (Module: app)

plugins {
  id 'com.android.application'
}

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.google.codelab.currentplace"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'com.google.android.gms:play-services-maps:16.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

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

6. Mengaktifkan API Google Maps Platform dan mendapatkan kunci API

Untuk langkah pengaktifan berikut, Anda harus mengaktifkan Maps SDK for Android dan Places API.

Menyiapkan Google Maps Platform

Jika Anda belum memiliki akun Google Cloud Platform dan project dengan penagihan diaktifkan, lihat panduan Memulai Google Maps Platform untuk membuat akun penagihan dan project.

  1. Di Cloud Console, klik menu drop-down project lalu pilih project yang ingin Anda gunakan untuk codelab ini.

  1. Aktifkan API dan SDK Google Maps Platform yang diperlukan untuk codelab ini di Google Cloud Marketplace. Untuk melakukannya, ikuti langkah-langkah dalam video ini atau dokumentasi ini.
  2. Buat kunci API di halaman Kredensial di Cloud Console. Anda dapat mengikuti langkah-langkah dalam video ini atau dokumentasi ini. Semua permintaan ke Google Maps Platform memerlukan kunci API.

Salin kunci API yang baru saja Anda buat. Kembali ke Android Studio, dan temukan file google_maps_api.xml di bagian Android > app > res > values.

Ganti YOUR_KEY_HERE dengan kunci API yang Anda salin.

aa576e551a7a1009.png

Aplikasi Anda sekarang telah dikonfigurasi.

7. Mengedit file tata letak

  1. Di penjelajah project, buka file activity_maps.xml di Android > app > res > layout.

4e0d986480c57efa.png

  1. Anda akan melihat UI dasar terbuka di sebelah kanan layar, dengan tab di bagian bawah yang memungkinkan Anda memilih editor Design atau Text untuk tata letak. Pilih Text, lalu ganti seluruh konten file tata letak dengan ini:

activity_maps.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:minHeight="?attr/actionBarSize"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:titleTextColor="@android:color/white"
        android:background="@color/colorPrimary" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

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

        <ListView
            android:id="@+id/listPlaces"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>

Ini akan memberi Anda antarmuka pengguna yang terlihat seperti ini:

1bf786808a4697ce.png

8. Menyiapkan panel aplikasi

Untuk memberi pengguna tombol yang dapat diklik saat mereka ingin memilih tempat mereka saat ini, tambahkan panel aplikasi dengan ikon yang mencari tempat pengguna saat ini dan menampilkan kemungkinan tempat yang terdekat. Hasilnya akan terlihat seperti ini:

3a17c92b613a26c5.png

Di ponsel, hanya ikon tersebut yang ditampilkan. Pada tablet dengan ruang yang lebih besar, teks juga disertakan.

Membuat ikon

  1. Di penjelajah project, klik Android > app, lalu klik kanan folder res dan pilih New > Image Asset.

Asset Studio akan terbuka.

  1. Pada menu Icon Type, klik Action Bar and Tab Icons.
  2. Beri nama aset Anda ic_geolocate.
  3. Pilih Clip Art sebagai jenis aset**.**
  4. Klik gambar di samping Clip Art.

Tindakan ini akan membuka jendela Select Icon.

  1. Pilih ikon.

Anda dapat menggunakan kotak penelusuran untuk menemukan ikon yang terkait dengan niat Anda.

  1. Telusuri location dan pilih ikon terkait lokasi.

Ikon my location sama seperti ikon yang digunakan di aplikasi Google Maps saat pengguna ingin men-snap kamera ke lokasi mereka saat ini.

  1. Klik OK > Next > Finish, dan pastikan ada folder baru bernama drawable yang berisi file ikon baru Anda.

b9e0196137ed18ae.png

Menambahkan resource string

  1. Di penjelajah project, klik Android > app > res > values dan buka file strings.xml.
  2. Tambahkan baris berikut setelah <string name="title_activity_maps">Map</string>:

strings.xml

    <string name="action_geolocate">Pick Place</string>
    <string name="default_info_title">Default Location</string>
    <string name="default_info_snippet">No places found, because location permission is disabled.</string>

Baris pertama digunakan di panel aplikasi Anda jika ada ruang untuk menyertakan label teks di sebelah ikon tersebut. Baris lainnya digunakan untuk penanda yang Anda tambahkan ke peta.

Sekarang kode dalam file akan terlihat seperti ini:

<resources>
    <string name="app_name">Current Place</string>
    <string name="title_activity_maps">Map</string>
    <string name="action_geolocate">Pick Place</string>
    <string name="default_info_title">Default Location</string>
    <string name="default_info_snippet">No places found, because location permission is disabled.</string>
</resources>

Menambahkan panel aplikasi

  1. Di penjelajah project, klik Android > app, lalu klik kanan folder res dan pilih New > Directory untuk membuat subdirektori baru di bagian app/src/main/res.
  2. Beri nama direktori menu.
  3. Klik kanan folder menu lalu pilih New > File.
  4. Beri nama file menu.xml.
  5. Tempel kode ini:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <!-- "Locate me", should appear as action button if possible -->
    <item
        android:id="@+id/action_geolocate"
        android:icon="@drawable/ic_geolocate"
        android:title="@string/action_geolocate"
        app:showAsAction="always|withText" />

</menu>

Mengupdate gaya panel aplikasi

  1. Di penjelajah project, luaskan Android > app > res > values dan buka file styles.xml di dalamnya.
  2. Di tag <style>, edit properti induk menjadi "Theme.AppCompat.NoActionBar".
  3. Perhatikan properti name, yang Anda gunakan di langkah berikutnya.

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">

Mengupdate tema aplikasi di AndroidManifest.xml

  1. Klik Android > app > manifests lalu buka file AndroidManifest.xml.
  2. Cari garis android:theme lalu edit atau konfirmasikan nilainya menjadi @style/AppTheme.

AndroidManifest.xml

   <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

Kini Anda siap untuk memulai coding.

9. Melakukan inisialisasi aplikasi

  1. Di penjelajah project, temukan file MapsActivity.java.

File ini berada dalam folder yang sesuai dengan paket yang Anda buat untuk aplikasi Anda di langkah 1.

8b0fa27d417f5f55.png

  1. Buka file tersebut, dan Anda berada di editor kode Java.

Mengimpor Places SDK dan dependensi lainnya

Tambahkan baris ini ke bagian atas MapsActivity.java, menggantikan pernyataan impor yang ada.

Ini mencakup impor yang ada dan menambahkan banyak baris lainnya yang digunakan dalam kode di codelab ini.

MapsActivity.java

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.google.android.gms.common.api.ApiException;
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.MarkerOptions;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.libraries.places.api.Places;
import com.google.android.libraries.places.api.model.Place;
import com.google.android.libraries.places.api.model.PlaceLikelihood;
import com.google.android.libraries.places.api.net.FindCurrentPlaceRequest;
import com.google.android.libraries.places.api.net.FindCurrentPlaceResponse;
import com.google.android.libraries.places.api.net.PlacesClient;

import java.util.Arrays;
import java.util.List;

Mengupdate tanda tangan class

Places API menggunakan komponen AndroidX untuk dukungan kompatibilitas mundur sehingga Anda perlu menentukannya untuk memperluas AppCompatActivity. Ini menggantikan ekstensi FragmentActivity yang ditetapkan secara default untuk aktivitas peta.

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {

Menambahkan variabel class

Selanjutnya, deklarasikan berbagai variabel class yang digunakan dalam metode class yang berbeda-beda. Ini mencakup elemen UI dan kode status. Posisinya harus tepat di bawah deklarasi variabel untuk GoogleMap mMap.

    // New variables for Current Place picker
    private static final String TAG = "MapsActivity";
    ListView lstPlaces;
    private PlacesClient mPlacesClient;
    private FusedLocationProviderClient mFusedLocationProviderClient;

    // The geographical location where the device is currently located. That is, the last-known
    // location retrieved by the Fused Location Provider.
    private Location mLastKnownLocation;

    // A default location (Sydney, Australia) and default zoom to use when location permission is
    // not granted.
    private final LatLng mDefaultLocation = new LatLng(-33.8523341, 151.2106085);
    private static final int DEFAULT_ZOOM = 15;
    private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
    private boolean mLocationPermissionGranted;

    // Used for selecting the Current Place.
    private static final int M_MAX_ENTRIES = 5;
    private String[] mLikelyPlaceNames;
    private String[] mLikelyPlaceAddresses;
    private String[] mLikelyPlaceAttributions;
    private LatLng[] mLikelyPlaceLatLngs;

Mengupdate metode onCreate

Anda perlu mengupdate metode onCreate untuk menangani izin pengguna runtime untuk layanan lokasi, menyiapkan elemen UI, dan membuat klien Places API.

Tambahkan baris kode berikut yang terkait dengan toolbar tindakan, penyiapan tampilan, dan klien Places di akhir metode onCreate() yang ada.

MapsActivity.java onCreate()

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        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);

        //
        // PASTE THE LINES BELOW THIS COMMENT
        //

        // Set up the action toolbar
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Set up the views
        lstPlaces = (ListView) findViewById(R.id.listPlaces);

        // Initialize the Places client
        String apiKey = getString(R.string.google_maps_key);
        Places.initialize(getApplicationContext(), apiKey);
        mPlacesClient = Places.createClient(this);
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
    }

Menambahkan kode untuk menu panel aplikasi

Kedua metode ini menambahkan menu panel aplikasi (dengan satu item, ikon Pilih Tempat) dan menangani klik pengguna pada ikon.

Salin kedua metode ini ke dalam file Anda setelah metode onCreate.

MapsActivity.java onCreateOptionsMenu() dan onOptionsItemSelected()

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
           case R.id.action_geolocate:

                // COMMENTED OUT UNTIL WE DEFINE THE METHOD
                // Present the current place picker
                // pickCurrentPlace();
                return true;

            default:
                // If we got here, the user's action was not recognized.
                // Invoke the superclass to handle it.
                return super.onOptionsItemSelected(item);

        }
    }

Melakukan pengujian

  1. Dari Android Studio, klik Run atau Run menu > Run ‘app'.

28bea91c68c36fb2.png

  1. Anda akan diminta untuk memilih target deployment. Emulator yang berjalan seharusnya muncul dalam daftar ini. Pilih emulator tersebut, dan Android Studio akan men-deploy aplikasi ke emulator untuk Anda.

f44658ca91f6f41a.png

Setelah beberapa saat, aplikasi akan terbuka. Anda melihat peta yang berpusat di Sydney, Australia, dengan tombol tunggal dan daftar tempat yang kosong.

68eb8c70f4748350.png

Fokus peta tidak berpindah ke lokasi pengguna kecuali Anda meminta izin untuk mengakses lokasi perangkat.

10. Meminta dan menangani izin akses lokasi

Meminta izin akses lokasi setelah peta siap

  1. Tentukan metode yang bernama getLocationPermission yang meminta izin pengguna.

Tempel kode ini di bawah metode onOptionsSelected yang baru saja Anda buat.

MapsActivity.java getLocationPermission()

    private void getLocationPermission() {
        /*
         * Request location permission, so that we can get the location of the
         * device. The result of the permission request is handled by a callback,
         * onRequestPermissionsResult.
         */
        mLocationPermissionGranted = false;
        if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
                android.Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            mLocationPermissionGranted = true;
        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                    PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
        }
    }
  1. Tambahkan dua baris ke akhir metode onMapReady yang ada untuk mengaktifkan kontrol zoom dan meminta izin akses lokasi dari pengguna.

MapsActivity.java onMapReady()

   @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));

        //
        // PASTE THE LINES BELOW THIS COMMENT
        //

        // Enable the zoom controls for the map
        mMap.getUiSettings().setZoomControlsEnabled(true);

        // Prompt the user for permission.
        getLocationPermission();

    }

Menangani hasil dari izin yang diminta

Saat pengguna merespons dialog izin permintaan, callback ini dipanggil oleh Android.

Tempel kode ini setelah metode getLocationPermission():

MapsActivity.java onRequestPermissionsResult()

   /**
     * Handles the result of the request for location permissions
     */
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String permissions[],
                                           @NonNull int[] grantResults) {
        mLocationPermissionGranted = false;
        switch (requestCode) {
            case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    mLocationPermissionGranted = true;
                }
            }
        }
    }

11. Mendapatkan lokasi saat ini dan mengambil kemungkinan tempat

Saat pengguna mengklik Pilih Tempat di panel aplikasi, aplikasi akan memanggil metode pickCurrentPlace(), yang memanggil metode getDeviceLocation() yang Anda tentukan sebelumnya. Metode getDeviceLocation memanggil metode lain, getCurrentPlaceLikelihoods, setelah mengambil lokasi perangkat terbaru.

Memanggil findCurrentPlace API dan menangani responsnya

getCurrentPlaceLikelihoods membuat findCurrentPlaceRequest dan memanggil tugas findCurrentPlace Places API. Jika berhasil, tugas akan menampilkan findCurrentPlaceResponse, yang berisi daftar objek placeLikelihood. Setiap objek ini memiliki sejumlah properti, termasuk nama dan alamat tempat, serta probabilitas Anda berada di tempat tersebut (nilai ganda dari 0 hingga 1). Metode ini menangani respons dengan membuat daftar detail tempat dari placeLikelihoods.

Kode ini melakukan iterasi pada lima tempat yang paling mungkin dan menambahkan tempat dengan probabilitas lebih besar dari 0 ke daftar yang kemudian dirender. Jika Anda ingin menampilkan lebih dari atau kurang dari lima tempat, edit konstanta M_MAX_ENTRIES.

Tempel kode ini setelah metode onMapReady.

MapsActivity.java getCurrentPlaceLikelihoods()

   private void getCurrentPlaceLikelihoods() {
        // Use fields to define the data types to return.
        List<Place.Field> placeFields = Arrays.asList(Place.Field.NAME, Place.Field.ADDRESS,
                Place.Field.LAT_LNG);

        // Get the likely places - that is, the businesses and other points of interest that
        // are the best match for the device's current location.
        @SuppressWarnings("MissingPermission") final FindCurrentPlaceRequest request =
                FindCurrentPlaceRequest.builder(placeFields).build();
        Task<FindCurrentPlaceResponse> placeResponse = mPlacesClient.findCurrentPlace(request);
        placeResponse.addOnCompleteListener(this,
                new OnCompleteListener<FindCurrentPlaceResponse>() {
                    @Override
                    public void onComplete(@NonNull Task<FindCurrentPlaceResponse> task) {
                        if (task.isSuccessful()) {
                            FindCurrentPlaceResponse response = task.getResult();
                            // Set the count, handling cases where less than 5 entries are returned.
                            int count;
                            if (response.getPlaceLikelihoods().size() < M_MAX_ENTRIES) {
                                count = response.getPlaceLikelihoods().size();
                            } else {
                                count = M_MAX_ENTRIES;
                            }

                            int i = 0;
                            mLikelyPlaceNames = new String[count];
                            mLikelyPlaceAddresses = new String[count];
                            mLikelyPlaceAttributions = new String[count];
                            mLikelyPlaceLatLngs = new LatLng[count];

                            for (PlaceLikelihood placeLikelihood : response.getPlaceLikelihoods()) {
                                Place currPlace = placeLikelihood.getPlace();
                                mLikelyPlaceNames[i] = currPlace.getName();
                                mLikelyPlaceAddresses[i] = currPlace.getAddress();
                                mLikelyPlaceAttributions[i] = (currPlace.getAttributions() == null) ?
                                        null : TextUtils.join(" ", currPlace.getAttributions());
                                mLikelyPlaceLatLngs[i] = currPlace.getLatLng();

                                String currLatLng = (mLikelyPlaceLatLngs[i] == null) ?
                                        "" : mLikelyPlaceLatLngs[i].toString();

                                Log.i(TAG, String.format("Place " + currPlace.getName()
                                        + " has likelihood: " + placeLikelihood.getLikelihood()
                                        + " at " + currLatLng));

                                i++;
                                if (i > (count - 1)) {
                                    break;
                                }
                            }

                            // COMMENTED OUT UNTIL WE DEFINE THE METHOD
                            // Populate the ListView
                            // fillPlacesList();
                        } else {
                            Exception exception = task.getException();
                            if (exception instanceof ApiException) {
                                ApiException apiException = (ApiException) exception;
                                Log.e(TAG, "Place not found: " + apiException.getStatusCode());
                            }
                        }
                    }
                });
    }

Memindahkan kamera peta ke lokasi perangkat saat ini

Jika pengguna memberikan izin, aplikasi akan mengambil lokasi terbaru pengguna dan memindahkan kamera ke tengah di sekitar lokasi tersebut.

Jika pengguna menolak izin, aplikasi hanya memindahkan kamera ke lokasi default yang ditentukan di antara konstanta pada awal halaman ini (dalam kode contoh digunakan Sydney, Australia).

Tempel kode ini setelah metode getPlaceLikelihoods():

MapsActivity.java getDeviceLocation()

    private void getDeviceLocation() {
        /*
         * Get the best and most recent location of the device, which may be null in rare
         * cases when a location is not available.
         */
        try {
            if (mLocationPermissionGranted) {
                Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation();
                locationResult.addOnCompleteListener(this, new OnCompleteListener<Location>() {
                    @Override
                    public void onComplete(@NonNull Task<Location> task) {
                        if (task.isSuccessful()) {
                            // Set the map's camera position to the current location of the device.
                            mLastKnownLocation = task.getResult();
                            Log.d(TAG, "Latitude: " + mLastKnownLocation.getLatitude());
                            Log.d(TAG, "Longitude: " + mLastKnownLocation.getLongitude());
                            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
                                    new LatLng(mLastKnownLocation.getLatitude(),
                                            mLastKnownLocation.getLongitude()), DEFAULT_ZOOM));
                        } else {
                            Log.d(TAG, "Current location is null. Using defaults.");
                            Log.e(TAG, "Exception: %s", task.getException());
                            mMap.moveCamera(CameraUpdateFactory
                                    .newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
                        }

                       getCurrentPlaceLikelihoods();
                    }
                });
            }
        } catch (SecurityException e)  {
            Log.e("Exception: %s", e.getMessage());
        }
    }

Memeriksa izin akses lokasi saat pengguna mengklik Pilih Tempat

Saat pengguna mengetuk Pilih Tempat, metode ini akan memeriksa izin lokasi dan meminta izin kepada pengguna jika belum diberikan.

Jika pengguna telah memberikan izin, metode akan memanggil getDeviceLocation untuk memulai proses mendapatkan kemungkinan tempat saat ini.

  1. Tambahkan metode ini setelah getDeviceLocation():

MapsActivity.java pickCurrentPlace()

   private void pickCurrentPlace() {
        if (mMap == null) {
            return;
        }

        if (mLocationPermissionGranted) {
            getDeviceLocation();
        } else {
            // The user has not granted permission.
            Log.i(TAG, "The user did not grant location permission.");

            // Add a default marker, because the user hasn't selected a place.
            mMap.addMarker(new MarkerOptions()
                    .title(getString(R.string.default_info_title))
                    .position(mDefaultLocation)
                    .snippet(getString(R.string.default_info_snippet)));

            // Prompt the user for permission.
            getLocationPermission();
        }
    }
  1. Setelah pickCurrentPlace ditentukan, cari baris di onOptionsItemSelected() yang memanggil pickCurrentPlace lalu hapus tanda komentar.

MapsActivity.java onOptionItemSelected()

           case R.id.action_geolocate:

                // COMMENTED OUT UNTIL WE DEFINE THE METHOD
                // Present the Current Place picker
                pickCurrentPlace();
                return true;

Melakukan pengujian

Jika Anda menjalankan aplikasi sekarang dan mengetuk Pilih Tempat, aplikasi seharusnya meminta izin lokasi.

  • Jika Anda memberikan izin, preferensi tersebut akan disimpan dan Anda tidak akan dimintai izin lagi. Jika Anda menolak izin, Anda akan dimintai izin saat mengetuk tombol di lain waktu.
  • Meskipun getPlaceLikelihoods telah mengambil kemungkinan tempat saat ini, ListView belum menampilkannya. Di Android Studio, Anda dapat mengklik ⌘6 untuk memeriksa pernyataan yang diberi tag MapsActivity dalam log di Logcat untuk memverifikasi bahwa metode baru Anda berfungsi dengan benar.
  • Jika Anda memberikan izin, log akan mencakup pernyataan untuk Latitude: dan pernyataan untuk Longitude: yang menampilkan lokasi perangkat yang terdeteksi. Jika Anda sebelumnya menggunakan Google Maps dan menu yang diperluas pada emulator untuk menentukan lokasi bagi emulator, pernyataan ini akan menunjukkan lokasi tersebut.
  • Jika panggilan ke findCurrentPlace berhasil, log akan menyertakan lima pernyataan yang mencantumkan nama dan lokasi dari lima tempat yang paling mungkin.

d9896a245b81bf3.png

12. Mengisi Current Place Picker

Menyiapkan handler untuk tempat yang dipilih

Coba pikirkan hal yang kita inginkan terjadi saat pengguna mengklik item di ListView. Untuk mengonfirmasi pilihan pengguna terkait tempat mereka saat ini, Anda dapat menambahkan penanda ke peta di tempat tersebut. Jika pengguna mengklik penanda tersebut, jendela info akan muncul yang menampilkan nama dan alamat tempat.

Tempel handler klik ini setelah metode pickCurrentPlace.

MapsActivity.java listClickedHandler

    private AdapterView.OnItemClickListener listClickedHandler = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView parent, View v, int position, long id) {
            // position will give us the index of which place was selected in the array
            LatLng markerLatLng = mLikelyPlaceLatLngs[position];
            String markerSnippet = mLikelyPlaceAddresses[position];
            if (mLikelyPlaceAttributions[position] != null) {
                markerSnippet = markerSnippet + "\n" + mLikelyPlaceAttributions[position];
            }

            // Add a marker for the selected place, with an info window
            // showing information about that place.
            mMap.addMarker(new MarkerOptions()
                    .title(mLikelyPlaceNames[position])
                    .position(markerLatLng)
                    .snippet(markerSnippet));

           // Position the map's camera at the location of the marker.
            mMap.moveCamera(CameraUpdateFactory.newLatLng(markerLatLng));
        }
    };

Mengisi ListView

Setelah memiliki daftar tempat yang paling mungkin dikunjungi pengguna saat ini, Anda dapat menampilkan opsi tersebut kepada pengguna di ListView. Anda juga dapat menetapkan pemroses klik ListView agar menggunakan handler klik yang baru saja Anda tentukan.

Tempel metode ini setelah handler klik:

MapsActivity.java fillPlacesList()

    private void fillPlacesList() {
        // Set up an ArrayAdapter to convert likely places into TextViews to populate the ListView
        ArrayAdapter<String> placesAdapter =
                new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mLikelyPlaceNames);
        lstPlaces.setAdapter(placesAdapter);
        lstPlaces.setOnItemClickListener(listClickedHandler);
    }

Setelah fillPlacesList ditentukan, cari baris ke arah akhir findPlaceLikelihoods yang memanggil fillPlacesList lalu hapus tanda komentar.

MapsActivity.java fillPlaceLikelihoods()

               // COMMENTED OUT UNTIL WE DEFINE THE METHOD
                // Populate the ListView
                fillPlacesList();

Itulah semua kode yang dibutuhkan untuk Current Place Picker.

13. Menjalankan aplikasi

Menguji pemilihan tempat

  1. Jalankan kembali aplikasi.

Kali ini saat Anda mengetuk Pilih Tempat, aplikasi akan mengisi daftar dengan nama tempat yang dekat dengan lokasi. Di dekat lokasi ini di Maui, terdapat tempat seperti Ululani's Hawaiian Shave Ice dan Sugar Beach Bake Shop. Karena beberapa tempat sangat dekat dengan koordinat lokasi, tersebut ini adalah daftar kemungkinan tempat Anda berada.

  1. Klik nama tempat di ListView.

Anda akan melihat penanda yang ditambahkan ke peta.

  1. Ketuk penanda.

Anda dapat melihat Place Details.

e52303cc0de6a513.png 864c74342fb52a01.png

Menguji lokasi yang berbeda

Jika Anda ingin mengubah lokasi dan menggunakan emulator, lokasi perangkat tidak otomatis diupdate saat Anda mengupdate koordinat lokasi di menu yang diperluas pada emulator.

Untuk mengatasi hal ini, ikuti langkah-langkah berikut untuk menggunakan aplikasi Google Maps native untuk memaksa lokasi emulator diupdate:

  1. Buka Google Maps.
  2. Ketuk ... > Lokasi untuk mengubah lintang dan bujur ke koordinat baru, lalu ketuk Kirim.
  3. Misalnya, Anda dapat menggunakan Lintang: 49,2768 dan Bujur: -123,1142 untuk menetapkan lokasi ke pusat kota Vancouver, Kanada.
  4. Verifikasi bahwa Google Maps telah kembali terpusat di koordinat baru Anda. Anda mungkin perlu mengetuk tombol Lokasiku di aplikasi Google Maps untuk meminta pemusatan lagi.
  5. Kembali ke Current Place aplikasi Anda, lalu ketuk Pilih Tempat untuk mendapatkan peta pada koordinat baru dan melihat daftar baru tentang kemungkinan tempat saat ini.

9adb99d1ce25c184.png

Dan selesai! Anda telah membuat aplikasi sederhana yang memeriksa tempat-tempat di lokasi saat ini dan memberi Anda kemungkinan tempat Anda berada. Selamat menggunakan!

Sekarang lanjutkan dan jalankan aplikasi dengan modifikasi yang Anda buat untuk menyelesaikan langkah bonus ini.

14. Langkah berikutnya

Untuk mencegah pencurian kunci API, Anda harus mengamankannya agar hanya aplikasi Android Anda yang dapat menggunakan kunci tersebut. Jika tidak dibatasi, siapa pun yang memiliki kunci Anda dapat menggunakannya untuk memanggil Google Maps Platform API dan menyebabkan Anda dikenai tagihan.

Mendapatkan sertifikat SHA-1

Anda memerlukannya nanti saat membatasi kunci API. Berikut adalah kumpulan petunjuk untuk mendapatkan sertifikat debug Anda.

Untuk Linux atau macOS, buka jendela terminal dan masukkan hal berikut:

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

Untuk Windows Vista dan Windows 7, jalankan perintah berikut:

keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android

Anda akan melihat output yang serupa dengan hal berikut:

Alias name: androiddebugkey
Creation date: Jan 01, 2013
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Android Debug, O=Android, C=US
Issuer: CN=Android Debug, O=Android, C=US
Serial number: 4aa9b300
Valid from: Mon Jan 01 08:04:04 UTC 2013 until: Mon Jan 01 18:04:04 PST 2033
Certificate fingerprints:
     MD5:  AE:9F:95:D0:A6:86:89:BC:A8:70:BA:34:FF:6A:AC:F9
     SHA1: BB:0D:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:75
     Signature algorithm name: SHA1withRSA
     Version: 3

Baris yang diawali dengan SHA1 berisi sidik jari SHA-1 sertifikat. Sidik jari adalah rangkaian 20 angka heksadesimal dua digit yang dipisahkan dengan titik dua.

Jika sudah siap untuk merilis aplikasi, gunakan petunjuk dalam dokumentasi ini untuk mengambil sertifikat rilis.

Menambahkan pembatasan ke kunci API Anda

  1. Di Cloud Console, buka API & Layanan > Kredensial.

Kunci yang Anda gunakan untuk aplikasi ini harus tercantum di bagian Kunci API.

  1. Klik 6454a04865d551e6.png untuk mengedit setelan kunci.

316b052c621ee91c.png

  1. Di halaman kunci API, setelah Pembatasan kunci, tetapkan Pembatasan aplikasi dengan melakukan hal berikut:
  2. Pilih Aplikasi Android dan ikuti petunjuknya.
  3. Klik Aplikasi Android.
  4. Masukkan nama paket dan sidik jari sertifikat SHA-1 Anda (diambil di bagian sebelumnya).

Contoh:

com.google.codelab.currentplace
BB:0D:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:75s
  1. Untuk perlindungan lebih lanjut, tetapkan Pembatasan API dengan melakukan hal berikut.
  2. Setelah pembatasan API, pilih Batasi kunci.
  3. Pilih Maps SDK for Android dan Places API.
  4. Klik Selesai lalu Simpan.

15. Selamat

Anda membuat aplikasi sederhana yang memeriksa tempat-tempat yang paling mungkin di lokasi saat ini dan menambahkan penanda ke peta untuk tempat yang dipilih pengguna.

Mempelajari lebih lanjut