Tuesday, 1 April 2014

Membuat Aplikasi Location Based Services di Android

Saya akan menulis tutorial tentang bagaimana cara membuat aplikasi yang bisa mendeteksi lokasi pengguna atau bahasa kerennya LBS (Location Based Services) atau Layanan Berbasis Lokasi. Jenis lokasi sendiri ada dua, yaitu coarse-location dan fine-location. Lokasi coarse/kasar adalah lokasi user yang ditentukan lewat BTS terdekat, mempunyai presisi yang tidak akurat, namun hemat baterai. Sedangkan lokasi fine-location/lokasi halus, adalah lokasi user yang didapatkan melalui GPS yang sekarang sudah umum ada di perangkat Android. Fine-location mempunyai presisi yang lebih tinggi, namun boros baterai.


Pada Android, penentuan lokasi ini semua diatur oleh sebuah kelas yang bernama LocationManager, jadi location manager-lah yang akan menentukan kapan kita harus memakai fine-location, atau coarse-location apabila suatu saat GPS dimatikan. Location Manager juga secara otomatis akan mendeteksi perubahan lokasi yang terjadi, karena dia mempunyai semacam listener class yang bernama LocationListener. Kelas itulah yang akan memantau semua event, seperti perubahan lokasi, provider berubah, dan akan menyesuaikan pendeteksian lokasi sesuai dengan keadaan yang ada.


Tampilan Awal TW-Maps
Pre-requisites

Menampilkan Android maps menggunakan MapView

Jadi, langkah pertama kamu harus mempunyai GoogleAPIs SDK terlebih dahulu! Setelah itu, untuk bisa menampilkan maps memakai MapView kamu harus mempunyai MapsAPIKey yang bisa didownload di site Android Maps API.
Langkah-langkah Mendapatkan Maps API Key (Environment Windows, yang lain bisa menyesuaikan ^^)
  1. Pertama-tama, kamu harus mendapatkan Android certificate MD5 fingerprint dari debug keystore yang biasanya terdapat di “C:\\Users\<your name>\.android\debug.keystore”
  2. Buka command prompt
  3. Ketikkan
    keytool -list -keystore "C:\\Users\<your name>\.android\debug.keystore".
    Ketika diminta untuk memasukkan password, kamu bisa mengosongkan saja atau tuliskan “android” sebagai password.
    Note: Apabila kamu menggunakan JDK 1.7, command yang harus diketik adalah
    keytool -v -list -keystore "C:\\Users\<your name>\.android\debug.keystore".
    Kemudian pilih yang MD5 Hash certificate, karena jika tidak, maka certificate fingerprint yang dicetak akan berformat SHA1, sedangkan yang dibutuhkan adalah MD5.
  4. Copy paste MD5 fingerprint yang telah di-generate
  5. Kemudian Sign-up untuk MapsAPIKey, dan pastekan fingerprint tersebut di sini.
  6. Dan, kamu pun memperoleh MapsAPIKey !
Next Step
Setelah memperoleh Maps API Key, sekarang kita akan membuat aplikasi contoh. Buka Eclipse dan buat Android Virtual Device baru yang mempunyai fitur Google APIs. Setelah itu create new Android Application, dan pastikan memakai AVD yang mempunyai fitur Google APIs.
Kemudian pada kelas main activity (misal TestMapActivity.java), pastekan kode berikut ini:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
 
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
 
@SuppressWarnings("unused")
public class TestMapActivity extends MapActivity {
    /** Called when the activity is first created. */
    private MapView map;
    private MapController controller;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initMapView();
        initMyLocation();
    }
 
    @Override
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }
 
    private void initMapView()
    {
        map = (MapView)findViewById(R.id.map );
        controller = map.getController();
        map.setSatellite(true);
        map.setBuiltInZoomControls(true);
    }
 
    private void initMyLocation()
    {
        final GeoPoint point = new GeoPoint(6,-108);
        final MyLocationOverlay overlay = new MyLocationOverlay(this, map);
        overlay.enableMyLocation();
 
        overlay.runOnFirstFix(new Runnable()
        {
            public void run()
            {
                controller.setZoom(8);
                controller.animateTo(point);
                controller.setCenter(point);
            }
        }
        );
        map.getOverlays().add(overlay);
    }
Pada kode di atas, ada beberapa hal yang perlu diperhatikan :
  • Pada saat activity pertama kali dibuat atau onCreate(), akan memanggil method initMapView() dan initMyLocation()
  • Method initMapView() berfungsi untuk inisialisasi peta, berisi :
    1
    2
    3
    4
    5
    6
    map = (MapView)findViewById(R.id.map );
    //untuk mengambil MapView dan menampilkan
    map.setSatellite(true);
    //untuk mengeset default view ke satellite mode
    map.setBuiltInZoomControls(true);
    //secara default menampilkan Zoom Controls</pre>
  • Kemudian method initMyLocation() berfungsi untuk inisialisasi lokasi peta saat pertama kali dibuka, berisi
1
2
3
4
5
6
7
8
final GeoPoint point = new GeoPoint(6,-108);
//berfungsi untuk mengeset koordinat awal pada titik 6,-108 (latitude, logitude)
controller.setZoom(8);
//berfungsi untuk mengeset zoom level maps ke level 8
controller.animateTo(point);
//untuk memindahkan lokasi awal peta ke koordinat "point"
controller.setCenter(point);
//untuk mengeset "point" sebagai koordinat awal peta
Layout
Pada Android main.xml isikan kode berikut, berfungsi sebagai layout yang akan menampilkan MapView:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/frame"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
 
    <com.google.android.maps.MapView
        android:id="@+id/map"
        android:apiKey="YourMapsAPIKey"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"/>
 
</LinearLayout>
Pada bagian
android:apiKey="YourMapsAPIKey"
, gantilah YourMapsAPIKey dengan Maps API KEY yang telah kamu peroleh tadi!
The Permission
MapView tentu saja membutuhkan koneksi internet untuk bisa mengakses peta dari Google Maps dan juga aplikasi akan membutuhkan akses untuk COARSE_LOCATION (deteksi lokasi berdasarkan GSM provider) atau FINE_LOCATION (deteksi lokasi berdasarkan GPS satelit), karena itu tambahkan permission berikut pada Android Manifest. Buka AndroidManifest.xml dan isikan kode berikut di baris sebelum
 <application> tag:
1
2
3
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />

Menampilkan Marker dan Info Window

Kita akan membuat class MapOverlay yang mengimplementasikan kelas ItemizedOverlay, kelas itu nantinya akan digunakan untuk membuat daftar marker dan menampilkan overlay.
MapOverlay.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package org.example.mymap;
 
import java.util.ArrayList;
 
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
 
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
 
@SuppressWarnings("rawtypes")
public class MapOverlay extends ItemizedOverlay {
 
    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
    Context mContext;
    public MapOverlay(Drawable defaultMarker, Context context) {
        super(boundCenterBottom(defaultMarker));
        // TODO Auto-generated constructor stub
        mContext = context;
    }
 
    public void addOverlay(OverlayItem overlay)
    {
        mOverlays.add(overlay);
        populate();
    }
 
    @Override
    protected OverlayItem createItem(int i) {
        // TODO Auto-generated method stub
        return mOverlays.get(i);
 
    }
 
    @Override
    public int size() {
        // TODO Auto-generated method stub
        return mOverlays.size();
    }
 
    @Override
    protected boolean onTap(int index) {
      OverlayItem item = mOverlays.get(index);
      AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
      dialog.setTitle(item.getTitle());
      dialog.setMessage(item.getSnippet());
      dialog.show();
      return true;
    }
 
}
Ada beberapa method yang akan kita override, di antaranya :
  • OverlayItem createItem(int i)
    Berfungsi untuk membuat Item yang akan dikembalikan untuk digunakan pada saat method ini dipanggil.
  • int size()
    Berfungsi untuk mengembalikan ukuran dari class MapOverlay.
  • boolean onTap(int index)
    Berfungsi untuk mendefinisikan event apa yang akan terjadi ketika marker tersebut ditap/diklik
Kemudian, pada Main class kita modifikasi kodenya seperti berikut ini :
TestMapActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.util.List;
 
import android.graphics.drawable.Drawable;
import android.os.Bundle;
 
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
 
public class TestMapActivity extends MapActivity {
   private MapView map;
   private MapController controller;
 
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      initMapView();
      initMyLocation();
   }
 
   /** Menemukan dan menginisialisasi MapView. */
   private void initMapView() {
      map = (MapView) findViewById(R.id.map);
      controller = map.getController();
      map.setSatellite(true);
      map.setBuiltInZoomControls(true);
 
   }
 
   /** Tracking lokasi awal pada map. */
   private void initMyLocation() {
      int lat, lng;
      lat = (int)(35.683183*1E6);
      lng = (int)(139.732435*1E6);
 
      GeoPoint point = new GeoPoint(lat,lng);
 
      List<Overlay> mapOverlays = map.getOverlays();
      Drawable marker = this.getResources().getDrawable(R.drawable.marker);
      MapOverlay itemizedOverlay = new MapOverlay(marker, this);
 
      OverlayItem overlayitem = new OverlayItem(point, "Sophia University!", "My Next Destination \o/");
      itemizedOverlay.addOverlay(overlayitem);
      controller.setZoom(16);
      controller.animateTo(point);
 
      mapOverlays.add(itemizedOverlay);
   }
 
   @Override
   protected boolean isRouteDisplayed() {
      // Required by MapActivity
      return false;
   }
}
Pada dasarnya, kelas di atas berfungsi untuk membuat sebuah array List<Overlay>, yang berisi item-item(marker) yang nantinya item tersebut mempunyai koordinat dan infonya sendiri-sendiri. Dan setiap item tersebut akan ditambahkan kepada kelas ItemizedOverlay yang telah kita buat, setelah itu kumpulan dari item yang ada pada ItemizedOverlay, kita tambahkan ke daftar List<Overlay> untuk ditampilkan.
GeoPoint digunakan untuk menampilkan koordinat yang berbasis microdegrees (degrees * 1e6), namun karena koordinat biasanya berformat double, maka sebelumnya harus kita konversi dahulu dengan cara mengkalikannya dengan 1E6.
MapViewMapView

 
Tools
Karena tidak semua orang punya handphone Android, kalian masih bisa menjalankan tutorial ini menggunakan Android Emulator yang ada di Eclipse, kemudian lokasi di GPS akan kita palsukan menggunakan Emulator Control.
Cara menampilkan Emulator Control, pada Eclipse :
  1. Klik menu Window
  2. Pilih Show View
  3. Pilih Other
  4. Pilih folder Android > Emulator Control
Maka akan muncul sebuah view baru pada bagian bawah bernama Emulator Control, scroll ke bawah dan kalian akan menemukan bagian Location Controls seperti gambar di bawah ini :

No comments:

Post a Comment