Dynamic Blinkie Text Generator at TextSpace.net

Feedburner

I heart FeedBurner

Jumat, 16 Maret 2018

Simpel aplikasi seperti Go-Jek

Halo Gaess ! Apa kabar ? Semoga selalu dalam kemudahan dan rezeki yang lapang. Aamiin
Di kesempatan ini kita saya akan membahas tentang Google API. Lebih spesifiknya kita akan membahas :
  • Google Maps API
  • Google Place Auto Complete
  • Google Direction API
Well, artikel ini adalah salah satu Request dari teman saya :D. Sebetulnya halangan terbesar untuk menulis adalah “Rasa Malas”, tapi ketika ada yang request mau tidak mau ada “Janji yang harus di Tepati” eaa.. Karena itu kalian boleh request topic apa yang perlu saya bahas, jika saya bisa InsyaAllah saya buatkan :)
Back To Topic…

Apa Sih Google API ?

Seperti yang kita ketahui saat ini Google bukan lagi hanya sebuah Mesin Pencari tapi telah berubah menjadi perusahaan teknologi raksasa dengan berbagaii macam produk inovatifnya.
Pada artikel sebelumnya saya juga membahas soal API loh, dimana study kasus nya kita membuat sebuah Aplikasi Portal Berita.
Salah satunya adalah Google Maps. Kita sebagai developer tidak hanya dapat menikmatinya saja, google membuka peluang bagi para developer untuk mengembangkan produk mereka dengan di kombinasikan dengan Maps sehingga terciptakan produk yang inovatif dan efisien.
“Gimana cara menggunakanya ?” ya dengan Google API tadi. Silahkan baca lebih lanjut tentang definisi API disini.

Google Maps API

Google maps api memungkinkan kita untuk menampilkan peta / maps di dalam aplikasi kita. Kita dapat mengatur mode peta seperti apa yang akan ditampilkan seperti mode “satelit” misalnya.

Google Place Auto Complete

Google menyediakan API yang membuat kita semakin mudah dalam melakukan input alamat seperti nama jalan, nama kota, nama daerah dan nama tempat. Dimana ketika kita mengetikan sebuah kata maka kita akan diberikan pilihan dalam bentuk auto complete secara realtime. Jika juga dapat melaukan filter disini, contoh jika kita ingin hanya ingin menampilkan alamat / tempat yang ada di Indonesia saja.

Google Direction API

API ini memungkinkan kita untuk mengerahui arah atau rute antara 2 titik koordinat atau lebih. Dengan memanfaatkan API ini kita dapat menggambar garis rute tersebut atau sering dikenal dengan istilah Polyline. Selain rute jika juga mendapatkan informasi berupa jarak, estimasi waktu tiba sampai step-step jalan yang harus kita lewati.

Persiapan Google API Key

Silahkan buka Google Console, gunakan project yang telah ada tau buat project baru. Ikuti langkah-langkah berikut jika ingin membuat project baru.
  • Silahkan beri nama apa saja untuk project anda. Anda akan mendapat API key, kita akan gunakan ini nanti. Simpan dulu saja dimana.
  • Klik Done jika sudah.
Sampai disini kita telah berhasil mendapatkan API key untuk dapat menggunakan layanan api google :)

Mengaktifkan Layanan API

Masih di google console. setelah project berhasil dibuat dan anda telah mendapatkan API key, berikutnya adalah mengaktifkan layanan API untuk project tersebut.
Silahkan Buka https://console.developers.google.com, pilih project yang baru saja kamu buat. Klik “ENABLE APIES AND SERVICES”.
Klik “View All” untuk bagian Maps aktifkan layanan api berikut :
  • Google Maps Android API
  • Google Maps Direction API
  • Google Places API for Android
  • Google Places API Web Services
Well done ! Sampai disini persiapan di Google Console telah selesai :)

Let’s DO IT !…….

Persiapan Project

Silahkan buat project android studio baru dengan nama Learn Google API, minimum API 16 : Jelly Bean dan Empty Activity.
Persiapan LibraySelain library yang saya sebutkan diatas, kita juga akan menggunakan tambahan library Retrofit2 dan Maps Utils, jadi semua library yang akan kita gunakan adalah :
  • Google Maps API
  • Google Place Auto Complete
  • Google Direction API
  • Maps Utils (untuk menggambar garis polyline)
  • Retrofit2 & GsonConverter (untuk komunikasi API)
Silahkan tambahkan depedencies berikut kedalam gradle (app).
dependencies {
    ...
    // Google MAPS
    implementation 'com.google.android.gms:play-services-maps:11.8.0'
    
    // Auto Complete Place & location
    implementation 'com.google.android.gms:play-services-places:11.8.0'
    implementation 'com.google.android.gms:play-services-location:11.8.0'
    
    // Maps Utils
    compile 'com.google.maps.android:android-maps-utils:0.4+'
    
    // Retrofit
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    ...
}
Sehingga gradle kalian terlihat seperti berikut :
build.gradle (Module : app)
Jangan lupa klik “Sync Now”.

Android Manifest

Di dalam AndroidManifest.xml kita akan mendefinisikan Permission dan Google API key kita. Berikut permission yang kita gunakan.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Dan meta tag untuk api key :
<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="YOU_KEY"/>
Sehingga Manifest kita terlihat seperti berikut :
AndroidManifest.xml

Android Activity

Buatlah 3 activity baru :
  • PlaceAutoCompleteActivity
  • DirectionActivity
  • OjekActivity
Jadi total kita punya 4 Activity disini
Tampilan Activity
Baik secara keseluruhan persiapan sudah selesai. Berikutnya kita akan mulai mengatur layout dan memprogram logika aplikasi.
Yah.. ini akan jadi tutorial yang panjang :v ..
Selamat bekerja :) ..

Main Activity

Pertama kita atur layout di activity_main.xml seperti berikut :
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="openAutoPlace"
        android:text="Place Auto Complete"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="openDirectionMap"
        android:text="Maps Direction"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="openOjek"
        android:text="Ojek Activity"/>
</LinearLayout>
Yap.. untuk event on click nya saya menggunakan method disini makanya anda pasti menemui tanda merah di attribut android:onClick. Sekarang kita buat methodnya, buka ActivityMain.java kemudian sesuaikan menjadi seperti berikut :
package com.khilman.www.learngoogleapi;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

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

        // Here, thisActivity is the current activity
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            // Permission is not granted
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {
                Toast.makeText(this, "Membutuhkan Izin Lokasi", Toast.LENGTH_SHORT).show();
            } else {

                // No explanation needed; request the permission
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                        1);
            }
        } else {
            // Permission has already been granted
            Toast.makeText(this, "Izin Lokasi diberikan", Toast.LENGTH_SHORT).show();
        }
    }

    public void openAutoPlace(View view) {
        startActivity(new Intent(this, PlaceAutoCompleteActivity.class));
    }

    public void openDirectionMap(View view) {
        startActivity(new Intent(this, DirectionActivity.class));
    }

    public void openOjek(View view) {
        startActivity(new Intent(this, OjekActivity.class));
    }
}

Place Auto Complete Activity

Diactivity ini kita akan mencoba menggunakan fitur place auto complete. Modelnya kita membuat 2 Text View untuk menampung alamat Titik jemput dan Titik tujuan. Kemudian nanti detail dari alamatnya akan di tampilkan pada text view dibawahnya lagi. Disini kita akan mendapatkan alamat lengkap, nama tempat dan koordinat lokasi tersebut.
Silahkan buka layout activity_place_auto_complete.xml kemudian sesuaikan kodenya menjadi seperti berikut.
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:elevation="1dp"
        android:paddingHorizontal="20dp"
        android:paddingVertical="15dp"
        android:background="@android:color/white">
        <HorizontalScrollView
            android:layout_width="match_parent"
            android:scrollbars="none"
            android:layout_height="wrap_content">
            <TextView
                android:id="@+id/tvPickUpFrom"
                android:layout_width="match_parent"
                android:maxLines="1"
                android:layout_height="wrap_content"
                android:text="Pick up from" />
        </HorizontalScrollView>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginHorizontal="0dp"
            android:layout_marginVertical="10dp"
            android:background="@android:color/darker_gray"></LinearLayout>
        <HorizontalScrollView
            android:layout_width="match_parent"
            android:scrollbars="none"
            android:layout_height="wrap_content">
            <TextView
                android:id="@+id/tvDestLocation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:maxLines="1"
                android:text="Send to" />
        </HorizontalScrollView>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            android:text="Pick Up Location Info :"
            android:textSize="18sp"/>
        <TextView
            android:id="@+id/tvPickUpAddr"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Pick up Address : Jl Anggreks Cendrawasi"
            android:textSize="14sp"/>
        <TextView
            android:id="@+id/tvPickUpLatLng"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Coordinate : 10.3, -0.2"
            android:textSize="14sp"/>
        <TextView
            android:id="@+id/tvPickUpName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Place Name : 12 KM"
            android:textSize="14sp"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            android:layout_marginTop="10dp"
            android:text="Destination Location Info :"
            android:textSize="18sp"/>
        <TextView
            android:id="@+id/tvDestLocAddr"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Destination Address : Jl Anggreks Cendrawasi"
            android:textSize="14sp"/>
        <TextView
            android:id="@+id/tvDestLocLatLng"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Coordinate : 10.3, -0.2"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/tvDestLocName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Place Name : 12 KM"
            android:textSize="14sp"/>
    </LinearLayout>
</LinearLayout>
Berikutnya kita atur logika activitynya, silahkan sesuaikan PlaceAutoCompleteActivity.java menjadi seperti berikut :
package com.khilman.www.learngoogleapi;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlaceAutocomplete;
import com.google.android.gms.maps.model.LatLng;
public class PlaceAutoCompleteActivity extends AppCompatActivity {
    // Deklarasi variable
    private TextView tvPickUpFrom, tvDestLocation;
    private TextView tvPickUpAddr, tvPickUpLatLng, tvPickUpName;
    private TextView tvDestLocAddr, tvDestLocLatLng, tvDestLocName;
    public static final int PICK_UP = 0;
    public static final int DEST_LOC = 1;
    private static int REQUEST_CODE = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_place_auto_complete);
        getSupportActionBar().setTitle("Place Auto Complete");
        // Inisialisasi Widget
        wigetInit();
        // Event OnClick
        tvPickUpFrom.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Jalankan Method untuk menampilkan Place Auto Complete
                // Bawa constant PICK_UP
                showPlaceAutoComplete(PICK_UP);
            }
        });
        // Event OnClick
        tvDestLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Jalankan Method untuk menampilkan Place Auto Complete
                // Bawa constant DEST_LOC
                showPlaceAutoComplete(DEST_LOC);
            }
        });
    }
    // Method untuk Inisilisasi Widget agar lebih rapih
    private void wigetInit() {
        tvPickUpFrom = findViewById(R.id.tvPickUpFrom);
        tvDestLocation = findViewById(R.id.tvDestLocation);
        tvPickUpAddr = findViewById(R.id.tvPickUpAddr);
        tvPickUpLatLng = findViewById(R.id.tvPickUpLatLng);
        tvPickUpName = findViewById(R.id.tvPickUpName);
        tvDestLocAddr = findViewById(R.id.tvDestLocAddr);
        tvDestLocLatLng = findViewById(R.id.tvDestLocLatLng);
        tvDestLocName = findViewById(R.id.tvDestLocName);
    }
    // Method menampilkan input Place Auto Complete
    private void showPlaceAutoComplete(int typeLocation) {
        // isi RESUT_CODE tergantung tipe lokasi yg dipilih.
        // titik jmput atau tujuan
        REQUEST_CODE = typeLocation;
        // Filter hanya tmpat yg ada di Indonesia
        AutocompleteFilter typeFilter = new AutocompleteFilter.Builder().setCountry("ID").build();
        try {
            // Intent untuk mengirim Implisit Intent
            Intent mIntent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY)
                    .setFilter(typeFilter)
                    .build(this);
            // jalankan intent impilist
            startActivityForResult(mIntent, REQUEST_CODE);
        } catch (GooglePlayServicesRepairableException e) {
            e.printStackTrace(); // cetak error
        } catch (GooglePlayServicesNotAvailableException e) {
            e.printStackTrace(); // cetak error
            // Display Toast
            Toast.makeText(this, "Layanan Play Services Tidak Tersedia", Toast.LENGTH_SHORT).show();
        }
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //Toast.makeText(this, "Sini Gaes", Toast.LENGTH_SHORT).show();
        // Pastikan Resultnya OK
        if (resultCode == RESULT_OK){
            //Toast.makeText(this, "Sini Gaes2", Toast.LENGTH_SHORT).show();
            // Tampung Data tempat ke variable
            Place placeData = PlaceAutocomplete.getPlace(this, data);
            if (placeData.isDataValid()){
                // Show in Log Cat
                Log.d("autoCompletePlace Data", placeData.toString());
                // Dapatkan Detail
                String placeAddress = placeData.getAddress().toString();
                LatLng placeLatLng = placeData.getLatLng();
                String placeName = placeData.getName().toString();
                // Cek user milih titik jemput atau titik tujuan
                switch (REQUEST_CODE){
                    case PICK_UP:
                        // Set ke widget lokasi asal
                        tvPickUpFrom.setText(placeAddress);
                        tvPickUpAddr.setText("Location Address : " + placeAddress);
                        tvPickUpLatLng.setText("LatLang : " + placeLatLng.toString());
                        tvPickUpName.setText("Place Name : " + placeName);
                        break;
                    case DEST_LOC:
                        // Set ke widget lokasi tujuan
                        tvDestLocation.setText(placeAddress);
                        tvDestLocAddr.setText("Destination Address : " + placeAddress);
                        tvDestLocLatLng.setText("LatLang : " + placeLatLng.toString());
                        tvDestLocName.setText("Place Name : " + placeName);
                        break;
                }
            } else {
                // Data tempat tidak valid
                Toast.makeText(this, "Invalid Place !", Toast.LENGTH_SHORT).show();
            }
        }
    }
}
Sekarang coba Running project, berikut adalah hasilnya :D yeaayy…
Place Auto Complete Activity

Direction Activity

Pada bagian ini kita akan menggunakan Google Direction API untuk mendapatkan informasi arah, seperti rute, waktu tempuh dan jarak.
Dokumentasi lebih lengkap mengenai direction API bisa teman-teman baca disini https://developers.google.com/maps/documentation/directions/intro#Waypoints
Model POJOKita akan membuat sebuah POJO sebagai Model penampung response JSON dari Direction API. Kita akan menggunakan bantuan Plugin Robo POJO Generator sama seperti di project sebelumnya Membuat Aplikasi Portal Berita.
Silahkan kunjungi link berikut untuk mendapatkan response json, kemudian silahkan ganti teks yang saya tebalkan dengan API yang tadi kamu telah dapatkan sbelumnya.
Jika berhasil kalian seharusnya melihat response json seperti ini https://pastebin.com/MgSpHZsE
Agar lebih rapi, silahkan tambahkan package baru dengan nama response. Kemudian generate POJO didalam package tersebut.
Pilih Folder > Klik Kanan > New > Generate POJO from JSON
Berinama Root Object Name dengan ReponseRoute.
Sehingga susunana foldernya terlihat seperti dibawah ini
Struktur Folder
Anda akan menemukan error pada setiap Class yang telah terbuat. Cek disemua class hapus 2 baris dibawah ini :
import javax.annotation.Generated;
@Generated(
“com.robohorse.robopojogenerator”)
Request Retrofitbuatlah sebuah package baru dengan nama network, kemudian tambahkan 1 java interface ApiServices.java dan 1 java class InitLibrary.java
ApiServices.java
package com.khilman.www.learngoogleapi.network;
import com.khilman.www.learngoogleapi.response.ResponseRoute;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface ApiServices {
    //https://maps.googleapis.com/maps/api/directions/
    // json?origin=Cirebon,ID&destination=Jakarta,ID&api_key=YOUR_API_KEY
    @GET("json")
    Call<ResponseRoute> request_route(
            @Query("origin") String origin,
            @Query("destination") String destination,
            @Query("api_key") String api_key
    );
}
InitLibrary.java
package com.khilman.www.learngoogleapi.network;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class InitLibrary {
    //https://maps.googleapis.com/maps/api/directions/json?origin=Cirebon,ID&destination=Jakarta,ID&api_key=YOUR_API_KEY
    public static String BASE_URL = "https://maps.googleapis.com/maps/api/directions/";
    public static Retrofit setInit(){
        return new Retrofit.Builder().baseUrl(BASE_URL)
                                    .addConverterFactory(GsonConverterFactory.create())
                                    .build();
    }
    public static ApiServices getInstance(){
        return setInit().create(ApiServices.class);
    }
}
Baik, sampai disini persiapan Retrofit untuk mengirim request ke Google API telah selesai.

Direction Activity

Kita akan menampilkan Maps di activity ini. Kemudian dibawahnya ada text view berisi informasi mengenai rute seperti lokasi awal, lokasi akhir, jarak dan estimasi waktu.
Kita akan menggambar rute di maps menggunakan bantuan library Map Utils. Jadi kita tinggal memasukan list titik-titik koordinat yang kita dapatkan dari response setelah mengirim request ke Google API.
LayoutSilahkan buka activity_direction.xml kemudian sesuaikan kodenya menjadi seperti berikut.
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_above="@+id/panelInfo"/>
    <LinearLayout
        android:id="@+id/panelInfo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        android:background="@android:color/white">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            android:text="Route Information :"
            android:textSize="18sp"/>
        <TextView
            android:id="@+id/tvStartAddress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="start address : Jl. Hidupku Cuma Kamu :'"
            android:textSize="14sp"/>
        <TextView
            android:id="@+id/tvEndAddress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="end address : Jl. Hidupku Cuma Kamu :'"
            android:textSize="14sp"/>
        <TextView
            android:id="@+id/tvDistance"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="distance : 0 km"
            android:textSize="14sp"/>
        <TextView
            android:id="@+id/tvDuration"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="duration : 0 hours"
            android:textSize="14sp"/>
    </LinearLayout>
</RelativeLayout>
ActivityBerikutnya buka DirectionActivity.java kemudian sesuaikan kodenya menjadi seperti berikut :
package com.khilman.www.learngoogleapi;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import com.google.android.gms.maps.CameraUpdate;
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.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.maps.android.PolyUtil;
import com.khilman.www.learngoogleapi.network.ApiServices;
import com.khilman.www.learngoogleapi.network.InitLibrary;
import com.khilman.www.learngoogleapi.response.Distance;
import com.khilman.www.learngoogleapi.response.Duration;
import com.khilman.www.learngoogleapi.response.LegsItem;
import com.khilman.www.learngoogleapi.response.ResponseRoute;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class DirectionActivity extends AppCompatActivity implements OnMapReadyCallback {
    private GoogleMap mMap;

    private String API_KEY = "YOUR_API_KEY";

    private LatLng pickUpLatLng = new LatLng(-6.175110, 106.865039); // Jakarta
    private LatLng locationLatLng = new LatLng(-6.197301,106.795951); // Cirebon

    private TextView tvStartAddress, tvEndAddress, tvDuration, tvDistance;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_direction);
        // Maps
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
        // Set Title bar
        getSupportActionBar().setTitle("Direction Maps API");
        // Inisialisasi Widget
        widgetInit();
        // jalankan method
        actionRoute();
    }

    private void widgetInit() {
        tvStartAddress = findViewById(R.id.tvStartAddress);
        tvEndAddress = findViewById(R.id.tvEndAddress);
        tvDuration = findViewById(R.id.tvDuration);
        tvDistance = findViewById(R.id.tvDistance);
    }

    private void actionRoute() {
        String lokasiAwal = pickUpLatLng.latitude + "," + pickUpLatLng.longitude;
        String lokasiAkhir = locationLatLng.latitude + "," + locationLatLng.longitude;

        // Panggil Retrofit
        ApiServices api = InitLibrary.getInstance();
        // Siapkan request
        Call<ResponseRoute> routeRequest = api.request_route(lokasiAwal, lokasiAkhir, API_KEY);
        // kirim request
        routeRequest.enqueue(new Callback<ResponseRoute>() {
            @Override
            public void onResponse(Call<ResponseRoute> call, Response<ResponseRoute> response) {

                if (response.isSuccessful()){
                    // tampung response ke variable
                    ResponseRoute dataDirection = response.body();

                    LegsItem dataLegs = dataDirection.getRoutes().get(0).getLegs().get(0);

                    // Dapatkan garis polyline
                    String polylinePoint = dataDirection.getRoutes().get(0).getOverviewPolyline().getPoints();
                    // Decode
                    List<LatLng> decodePath = PolyUtil.decode(polylinePoint);
                    // Gambar garis ke maps
                    mMap.addPolyline(new PolylineOptions().addAll(decodePath)
                                                            .width(8f).color(Color.argb(255, 56, 167, 252)))
                                                            .setGeodesic(true);

                    // Tambah Marker
                    mMap.addMarker(new MarkerOptions().position(pickUpLatLng).title("Lokasi Awal"));
                    mMap.addMarker(new MarkerOptions().position(locationLatLng).title("Lokasi Akhir"));
                    // Dapatkan jarak dan waktu
                    Distance dataDistance = dataLegs.getDistance();
                    Duration dataDuration = dataLegs.getDuration();

                    // Set Nilai Ke Widget
                    tvStartAddress.setText("start location : " + dataLegs.getStartAddress().toString());
                    tvEndAddress.setText("end location : " + dataLegs.getEndAddress().toString());

                    tvDistance.setText("distance : " + dataDistance.getText() + " (" + dataDistance.getValue() + ")");
                    tvDuration.setText("duration : " + dataDuration.getText() + " (" + dataDuration.getValue() + ")");
                    /** START
                     * Logic untuk membuat layar berada ditengah2 dua koordinat
                     */

                    LatLngBounds.Builder latLongBuilder = new LatLngBounds.Builder();
                    latLongBuilder.include(pickUpLatLng);
                    latLongBuilder.include(locationLatLng);

                    // Bounds Coordinata
                    LatLngBounds bounds = latLongBuilder.build();

                    int width = getResources().getDisplayMetrics().widthPixels;
                    int height = getResources().getDisplayMetrics().heightPixels;
                    int paddingMap = (int) (width * 0.2); //jarak dari
                    CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, paddingMap);
                    mMap.animateCamera(cu);

                    /** END
                     * Logic untuk membuat layar berada ditengah2 dua koordinat
                     */

                }
            }

            @Override
            public void onFailure(Call<ResponseRoute> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
    }
}
Note :
  • Jangan lupa mengubah isi constant API_KEY dengan api key mu ya
Sekarang coba running project, jika sudah sesuai activity kita akan terlihat seperti berikut ini :
Direction Activity

Ojek Activity

Finally ! kita hampir sampai di akhir artikel :D hehe. Ini adalah activity terakhir Kita.
LayoutSilahkan sesuaikan activity_ojek.xml seperti berikut :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:elevation="1dp"
        android:paddingHorizontal="20dp"
        android:paddingVertical="15dp"
        android:background="@android:color/white">

        <HorizontalScrollView
            android:layout_width="match_parent"
            android:scrollbars="none"
            android:layout_height="wrap_content">
            <TextView
                android:id="@+id/tvPickUpFrom"
                android:layout_width="match_parent"
                android:maxLines="1"
                android:layout_height="wrap_content"
                android:text="Pick up from" />
        </HorizontalScrollView>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginHorizontal="0dp"
            android:layout_marginVertical="10dp"
            android:background="@android:color/darker_gray"></LinearLayout>
        <HorizontalScrollView
            android:layout_width="match_parent"
            android:scrollbars="none"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/tvDestLocation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:maxLines="1"
                android:text="Destination Location" />
        </HorizontalScrollView>
    </LinearLayout>
    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"/>

    <LinearLayout
        android:id="@+id/infoPanel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:visibility="visible"
        android:layout_marginHorizontal="15dp"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="10dp"
            android:background="@android:color/white"
            android:gravity="center"
            android:paddingVertical="10dp"
            android:layout_marginBottom="-8dp"
            android:orientation="horizontal">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:orientation="vertical">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Price"
                    android:textSize="12sp" />

                <TextView
                    android:id="@+id/tvPrice"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Rp13.000" />

            </LinearLayout>

            <LinearLayout
                android:layout_width="1dp"
                android:layout_height="match_parent"
                android:layout_marginTop="5dp"
                android:background="@android:color/darker_gray"></LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:orientation="vertical">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Distance"
                    android:textSize="12sp" />

                <TextView
                    android:id="@+id/tvDistance"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="0.6 Km" />

            </LinearLayout>
        </LinearLayout>

        <Button
            android:id="@+id/btnNext"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:elevation="1dp"
            android:paddingVertical="20dp"
            android:text="Next" />
    </LinearLayout>

</RelativeLayout>
ActivityPada OjekActivity.java sesuaikan kodenya menjadi seperti berikut :
package com.khilman.www.learngoogleapi;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlaceAutocomplete;
import com.google.android.gms.maps.CameraUpdate;
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.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.maps.android.PolyUtil;
import com.khilman.www.learngoogleapi.network.ApiServices;
import com.khilman.www.learngoogleapi.network.InitLibrary;
import com.khilman.www.learngoogleapi.response.Distance;
import com.khilman.www.learngoogleapi.response.Duration;
import com.khilman.www.learngoogleapi.response.LegsItem;
import com.khilman.www.learngoogleapi.response.ResponseRoute;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class OjekActivity extends AppCompatActivity implements OnMapReadyCallback {
    private GoogleMap mMap;

    private String API_KEY = "CHANGE_WITH_YOU_API_KEY";

    public LatLng pickUpLatLng = null; 
    public LatLng locationLatLng = null; 

    private TextView tvStartAddress, tvEndAddress;
    private TextView tvPrice, tvDistance;
    private Button btnNext;
    private LinearLayout infoPanel;
    // Deklarasi variable
    private TextView tvPickUpFrom, tvDestLocation;

    public static final int PICK_UP = 0;
    public static final int DEST_LOC = 1;
    private static int REQUEST_CODE = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ojek);
        getSupportActionBar().setTitle("Ojek Hampir Online");

        // Inisialisasi Widget
        wigetInit();
        infoPanel.setVisibility(View.GONE);
        // Event OnClick
        tvPickUpFrom.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Jalankan Method untuk menampilkan Place Auto Complete
                // Bawa constant PICK_UP
                showPlaceAutoComplete(PICK_UP);
            }
        });
        // Event OnClick
        tvDestLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Jalankan Method untuk menampilkan Place Auto Complete
                // Bawa constant DEST_LOC
                showPlaceAutoComplete(DEST_LOC);
            }
        });


    }

    // Method untuk Inisilisasi Widget agar lebih rapih
    private void wigetInit() {
        // Maps
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        infoPanel = findViewById(R.id.infoPanel);
        // Widget
        tvPickUpFrom = findViewById(R.id.tvPickUpFrom);
        tvDestLocation = findViewById(R.id.tvDestLocation);

        tvPrice = findViewById(R.id.tvPrice);
        tvDistance = findViewById(R.id.tvDistance);
        btnNext = findViewById(R.id.btnNext);
    }

    // Method menampilkan input Place Auto Complete
    private void showPlaceAutoComplete(int typeLocation) {
        // isi RESUT_CODE tergantung tipe lokasi yg dipilih.
        // titik jmput atau tujuan
        REQUEST_CODE = typeLocation;

        // Filter hanya tmpat yg ada di Indonesia
        AutocompleteFilter typeFilter = new AutocompleteFilter.Builder().setCountry("ID").build();
        try {
            // Intent untuk mengirim Implisit Intent
            Intent mIntent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY)
                    .setFilter(typeFilter)
                    .build(this);
            // jalankan intent impilist
            startActivityForResult(mIntent, REQUEST_CODE);
        } catch (GooglePlayServicesRepairableException e) {
            e.printStackTrace(); // cetak error
        } catch (GooglePlayServicesNotAvailableException e) {
            e.printStackTrace(); // cetak error
            // Display Toast
            Toast.makeText(this, "Layanan Play Services Tidak Tersedia", Toast.LENGTH_SHORT).show();
        }

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //Toast.makeText(this, "Sini Gaes", Toast.LENGTH_SHORT).show();
        // Pastikan Resultnya OK
        if (resultCode == RESULT_OK) {
            //Toast.makeText(this, "Sini Gaes2", Toast.LENGTH_SHORT).show();
            // Tampung Data tempat ke variable
            Place placeData = PlaceAutocomplete.getPlace(this, data);

            if (placeData.isDataValid()) {
                // Show in Log Cat
                Log.d("autoCompletePlace Data", placeData.toString());

                // Dapatkan Detail
                String placeAddress = placeData.getAddress().toString();
                LatLng placeLatLng = placeData.getLatLng();
                String placeName = placeData.getName().toString();

                // Cek user milih titik jemput atau titik tujuan
                switch (REQUEST_CODE) {
                    case PICK_UP:
                        // Set ke widget lokasi asal
                        tvPickUpFrom.setText(placeAddress);
                        pickUpLatLng = placeData.getLatLng();
                        break;
                    case DEST_LOC:
                        // Set ke widget lokasi tujuan
                        tvDestLocation.setText(placeAddress);
                        locationLatLng = placeData.getLatLng();
                        break;
                }
                // Jalankan Action Route
                if (pickUpLatLng != null && locationLatLng != null) {
                    actionRoute(placeLatLng, REQUEST_CODE);
                }

            } else {
                // Data tempat tidak valid
                Toast.makeText(this, "Invalid Place !", Toast.LENGTH_SHORT).show();
            }
        }

    }

    @SuppressLint("MissingPermission")
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setPadding(10, 180, 10, 10);
        mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

        mMap.setMyLocationEnabled(true);
        mMap.getUiSettings().setCompassEnabled(true);
        mMap.getUiSettings().setZoomGesturesEnabled(true);
        mMap.getUiSettings().setRotateGesturesEnabled(false);
        mMap.getUiSettings().setZoomControlsEnabled(true);
    }

    private void actionRoute(LatLng placeLatLng, int requestCode) {
        String lokasiAwal = pickUpLatLng.latitude + "," + pickUpLatLng.longitude;
        String lokasiAkhir = locationLatLng.latitude + "," + locationLatLng.longitude;

        // Clear dulu Map nya
        mMap.clear();
        // Panggil Retrofit
        ApiServices api = InitLibrary.getInstance();
        // Siapkan request
        Call<ResponseRoute> routeRequest = api.request_route(lokasiAwal, lokasiAkhir, API_KEY);
        // kirim request
        routeRequest.enqueue(new Callback<ResponseRoute>() {
            @Override
            public void onResponse(Call<ResponseRoute> call, Response<ResponseRoute> response) {

                if (response.isSuccessful()){
                    // tampung response ke variable
                    ResponseRoute dataDirection = response.body();

                    LegsItem dataLegs = dataDirection.getRoutes().get(0).getLegs().get(0);

                    // Dapatkan garis polyline
                    String polylinePoint = dataDirection.getRoutes().get(0).getOverviewPolyline().getPoints();
                    // Decode
                    List<LatLng> decodePath = PolyUtil.decode(polylinePoint);
                    // Gambar garis ke maps
                    mMap.addPolyline(new PolylineOptions().addAll(decodePath)
                            .width(8f).color(Color.argb(255, 56, 167, 252)))
                            .setGeodesic(true);

                    // Tambah Marker
                    mMap.addMarker(new MarkerOptions().position(pickUpLatLng).title("Lokasi Awal"));
                    mMap.addMarker(new MarkerOptions().position(locationLatLng).title("Lokasi Akhir"));
                    // Dapatkan jarak dan waktu
                    Distance dataDistance = dataLegs.getDistance();
                    Duration dataDuration = dataLegs.getDuration();

                    // Set Nilai Ke Widget
                    double price_per_meter = 250;
                    double priceTotal = dataDistance.getValue() * price_per_meter; // Jarak * harga permeter

                    tvDistance.setText(dataDistance.getText());
                    tvPrice.setText(String.valueOf(priceTotal));
                    /** START
                     * Logic untuk membuat layar berada ditengah2 dua koordinat
                     */

                    LatLngBounds.Builder latLongBuilder = new LatLngBounds.Builder();
                    latLongBuilder.include(pickUpLatLng);
                    latLongBuilder.include(locationLatLng);

                    // Bounds Coordinata
                    LatLngBounds bounds = latLongBuilder.build();

                    int width = getResources().getDisplayMetrics().widthPixels;
                    int height = getResources().getDisplayMetrics().heightPixels;
                    int paddingMap = (int) (width * 0.2); //jarak dari
                    CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, paddingMap);
                    mMap.animateCamera(cu);

                    /** END
                     * Logic untuk membuat layar berada ditengah2 dua koordinat
                     */
                    // Tampilkan info panel
                    infoPanel.setVisibility(View.VISIBLE);

                    mMap.setPadding(10, 180, 10, 180);

                }
            }

            @Override
            public void onFailure(Call<ResponseRoute> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }
}

One Step Closer!!

Alhamdulillah, sampai disini kita telah menyelesaikan semua activity. Jika kamu mengikuti tutorial dengan benar aplikasi kamu terlihat seperti berikut ini :
Tampilan Ojek Activity

Penutup

Baik, kita telah menyelesaikan aplikasi “Hampir Ojek Online” kita. Kita telah belajar bagaimana caranya menggunakan beberapa layanan dari Google API.
Yang kita bahas saat ini masih belum apa-apa, masih banyak layanan Google API yang dapat kita manfaatkan dalam Project kita. Intinya jangan berhenti ngoprek, jenuh itu wajar tapi berhenti itu tanda orang malas belajar.
Jangan sungkan Investasi untuk masadepan seperti beli buku, tutorial, ikut private atau pergi ke Training Center seperti IMA-Studio. Salah satu training Mobile Apps TOP di Jakarta. Siapa tahu nanti ketemu saya di kelas hehe..
Jangan sungkan belajar hal baru, nanti kalau sudah bisa share lah ke kita-kita hehe..
Sekian dari saya, semoga bermanfaat. Terimakasih :)

Note :

Sumber : https://medium.com/@rizal_hilman/bermain-google-maps-api-android-kuy-bikin-aplikasi-kayak-go-jek-belajarapi-20b004d6abdf

Tidak ada komentar:

Posting Komentar