Kalau di lihat sampai sekarang masih banyak pengunjung yang
mengakses dan bertanya-tanya tentang tutorial lama berjudul membuat
aplikasi location based services di Android. Tentu
saja tutorial itu sudah tidak berlaku lagi, karena sekarang sudah jaman nya menggunakan Maps API v2, oleh karena itu di bawah ini akan di bahas bagaimana cara membuat aplikasi LBS menggunakan Maps API v2.
Android mempunyai dua macam jenis lokasi sendiri, 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.
Pre-Requisites
Untuk membuat tutorial ini, kalian harus mempelajari beberapa tutorial yang pernah saya tulis sebelumnya. Karena itu saya sarankan agar kalian membaca daftar tutorial di bawah ini sebelum melanjutkan ke langkah berikutnya :- Tutorial Menampilkan Maps pada Android Menggunakan Google Maps API v2 dan Maps Fragment
- Tutorial Menampilkan Marker dan InfoWindow pada Android Maps
- Menampilkan Embedded User Location
Down to Code
Oke, pertama-tama kita akan membuat tampilannya. Sama seperti di postingan sebelumnya, aplikasi ini akan mempunyai dua tampilan, yaitu tampilan Menu dan tampilan Maps yang akan menampilkan peta dan lokasi pengguna.Oh ya, jika kalian menggunakan SDK Android terbaru, maka Main Activity yang ter-create akan mempunyai dua buah layout xml, yaitu layout untuk Activity tersebut dan layout untuk Fragment. Berikut ini adalah layout untuk Activity-nya :
activity_main.xml
1
2
3
4
5
6
7
| android:id = "@+id/container" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = "id.web.twoh.twohmaps.MainActivity" tools:ignore = "MergeRootFrame" /> |
fragment_main.xml
01
02
03
04
05
06
07
08
09
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
| android:layout_width = "match_parent" android:layout_height = "match_parent" android:paddingBottom = "@dimen/activity_vertical_margin" android:paddingLeft = "@dimen/activity_horizontal_margin" android:paddingRight = "@dimen/activity_horizontal_margin" android:paddingTop = "@dimen/activity_vertical_margin" android:orientation = "vertical" android:background = "@drawable/bg_main" android:gravity = "center_horizontal|center_vertical" tools:context = "id.web.twoh.twohmaps.MainActivity$PlaceholderFragment" > < TextView android:id = "@+id/NamaProgram" android:text = "TWOH Maps v2" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:textColor = "#ffffff" android:textStyle = "bold" /> < Button android:id = "@+id/btGetLocation" android:text = "Get Location" android:layout_width = "wrap_content" android:layout_height = "wrap_content" /> < Button android:id = "@+id/btViewOnMap" android:text = "View On Map" android:layout_width = "wrap_content" android:layout_height = "wrap_content" /> < Button android:id = "@+id/btCheckIn" android:text = "Check In" android:layout_width = "wrap_content" android:layout_height = "wrap_content" /> < Button android:id = "@+id/btAbout" android:text = "About" android:layout_width = "wrap_content" android:layout_height = "wrap_content" /> </ LinearLayout > |
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
| package id.web.twoh.twohmaps; import android.support.v7.app.ActionBarActivity; import android.support.v4.app.Fragment; import android.content.Context; import android.content.Intent; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.Toast; import id.web.twoh.twohmaps.R; public class MainActivity extends ActionBarActivity { protected LocationManager locationManager; private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 10 ; // dalam Meters private static final long MINIMUM_TIME_BETWEEN_UPDATES = 60000 ; // dalam Milliseconds @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState == null ) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()).commit(); } locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MINIMUM_TIME_BETWEEN_UPDATES, MINIMUM_DISTANCE_CHANGE_FOR_UPDATES, new MyLocationListener() ); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true ; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true ; } return super .onOptionsItemSelected(item); } protected void showCurrentLocation() { Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location != null ) { String message = String.format( "Lokasi saat ini \n Longitude: %1$s \n Latitude: %2$s" , location.getLongitude(), location.getLatitude() ); Toast.makeText( this , message, Toast.LENGTH_LONG).show(); } } private class MyLocationListener implements LocationListener { public void onLocationChanged(Location location) { String message = String.format( "Deteksi Lokasi Baru \n Longitude: %1$s \n Latitude: %2$s" , location.getLongitude(), location.getLatitude() ); Toast.makeText(MainActivity. this , message, Toast.LENGTH_LONG).show(); //switchToMap(); } public void onStatusChanged(String s, int i, Bundle b) { Toast.makeText(MainActivity. this , "Status provider berubah" , Toast.LENGTH_LONG).show(); } public void onProviderDisabled(String s) { Toast.makeText(MainActivity. this , "Provider dinonaktifkan oleh user, GPS off" , Toast.LENGTH_LONG).show(); } public void onProviderEnabled(String s) { Toast.makeText(MainActivity. this , "Provider diaktifkan oleh user, GPS on" , Toast.LENGTH_LONG).show(); } } public static class PlaceholderFragment extends Fragment { private Button btMaps; private Button btCheckIn; private Button btGetLocation; Location location; public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false ); btMaps = (Button)rootView.findViewById(R.id.btViewOnMap); btMaps.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { switchToMap(); } }); btCheckIn = (Button)rootView.findViewById(R.id.btCheckIn); btCheckIn.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { switchToCheckIn(); } }); btGetLocation = (Button) rootView.findViewById(R.id.btGetLocation); btGetLocation.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { showCurrentLocation(); } }); return rootView; } @Override public void onActivityCreated(Bundle savedInstanceState) { super .onCreate(savedInstanceState); location = ((MainActivity)getActivity()).locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location== null ) { location = ((MainActivity)getActivity()).locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } } private void switchToMap() { Intent i = new Intent(getActivity(), MapsActivity. class ); Bundle b = new Bundle(); if (location!= null ) { b.putDouble( "longitude" , location.getLongitude()); b.putDouble( "latitude" , location.getLatitude()); Log.v( "info" , "The lat " +location.getLatitude()); Log.v( "info" , "The lng " +location.getLongitude()); i.putExtras(b); startActivity(i); } else { Toast.makeText(getActivity(), "Nyalakan lokasimu" , Toast.LENGTH_LONG).show(); } } public void switchToCheckIn() { //not yet implemented } protected void showCurrentLocation() { if (location != null ) { String message = String.format( "Lokasi saat ini \n Longitude: %1$s \n Latitude: %2$s" , location.getLongitude(), location.getLatitude() ); Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show(); } } } } |
Selebihnya, kelas ini juga berfungsi untuk mendeteksi lokasi user, seperti di postingan LBS yang lama. Untuk bisa mendeteksi lokasi, pertama-tama kita harus menginstansiasi kelas Location Manager yang berfungsi untuk mengakses location services, location manager akan diturunkan dari kelas parent Context dan didapatkan lewat method getSystemService() . Kemudian kita meminta update lokasi dari perangkat menggunakan method requestLocationUpdates(), pada method itu kita akan menggunakan beberapa parameter, yaitu jenis provider layanan lokasi yang diinginkan (pada kasus ini adalah layanan GPS), kemudian interval minimum untuk pemberitahuan (dalam milisekon), jarak minimun untuk pemberitahuan (dalam meter), dan yang terakhir adalah sebuah kelas yang mengimplementasikan LocationListener. Location Listener seperti yang telah dijelaskan di atas, berfungsi untuk memantau perubahan pada lokasi pengguna dan juga perubahan pada status provider.
Interface LocationListener diimplementasikan ke dalam inner class bernama MyLocationListener, pada kelas tersebut terdapat methods yang berfungsi untuk menghandle event apabila terjadi perubahan pada lokasi user atau perubahan pada status provider, dalam kasus ini kita hanya akan menampilkan Toast yang berisikan info. Kemudian apabila kita mengeklik tombol GetLocation, maka method showCurrentLocation() akan dieksekusi. Method itu akan memanggil getLastKnownLocation() dari kelas LocationManager yang akan memberikan Location terakhir yang terdeteksi. Dari object Location tersebut, kita akan dapat mengetahui parameter-parameter seperti latitude, longitude, altitude, speed, dsb.
Kemudian tombol satunya lagi adalah tombol View On Map, yang akan memunculkan lokasi kita pada Android Maps. Ketika tombol tersebut di-klik, informasi lokasi seperti latitude dan longitude, akan dimasukkan ke dalam sebuah Bundle, info itu akan di-pack dan diikutkan sebagai sebuah extra pada Intent, yang nantinya akan diteruskan ke Activity selanjutnya, yaitu Activity MapsActivity.java.
Activity MapsActivity pada dasarnya tidak jauh berbeda dengan yang pernah saya tuliskan di tutorial untuk menampilkan marker koordinat pengguna. Kita hanya perlu menambahkan beberapa baris kode yang berfungsi untuk meng-unpack koordinat yang tadi diikutsertakan pada Bundle dari aktivitas sebelumnya, dan mengaplikasikan koordinat tersebut pada peta, berikut ini kode lengkapnya :
MapsActivity.java
01
02
03
04
05
06
07
08
09
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
| package id.web.twoh.twohmaps; import java.util.ArrayList; import id.web.twoh.twohmaps.R; import id.web.twoh.twohmaps.model.DBLokasi; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.widget.Toast; public class MapsActivity extends FragmentActivity{ private GoogleMap map; private DBLokasi lokasi; private ArrayList<DBLokasi> values; @SuppressWarnings ( "unchecked" ) @Override protected void onCreate(Bundle arg0) { super .onCreate(arg0); setContentView(R.layout.activity_map); SupportMapFragment mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); map = mapFrag.getMap(); map.setMyLocationEnabled( true ); Bundle b = this .getIntent().getExtras(); if (b.containsKey( "longitude" )){ final LatLng latLng = new LatLng(b.getDouble( "latitude" ), b.getDouble( "longitude" )); map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16 )); map.addMarker( new MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))); map.setOnMarkerClickListener( new OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { Toast.makeText(MapsActivity. this , "Lokasi saat ini " +latLng.latitude+ "," +latLng.longitude,Toast.LENGTH_SHORT).show(); return false ; } }); } else if ( this .getIntent().getSerializableExtra( "lokasi" )!= null ) { lokasi = (DBLokasi) this .getIntent().getSerializableExtra( "lokasi" ); if (lokasi!= null ) { LatLng latLng = new LatLng(lokasi.getLatD(), lokasi.getLngD()); map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16 )); map.addMarker( new MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))); } map.setOnMarkerClickListener( new OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { // see next post <img src="http://i1.wp.com/www.twoh.co/wp-includes/images/smilies/icon_smile.gif?w=955" alt=":)" class="wp-smiley" height="15" width="15"> return false ; } }); } else { LatLng init; DBLokasi lokInit; LatLng latLng; values = ((ArrayList<DBLokasi>) this .getIntent().getSerializableExtra( "arraylokasi" )); lokInit = values.get( 0 ); init = new LatLng(lokInit.getLatD(), lokInit.getLngD()); map.animateCamera(CameraUpdateFactory.newLatLngZoom(init, 16 )); for (DBLokasi lok : values) { latLng = new LatLng(lok.getLatD(), lok.getLngD()); map.addMarker( new MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))); } map.setOnMarkerClickListener( new OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { // see next post <img src="http://i1.wp.com/www.twoh.co/wp-includes/images/smilies/icon_smile.gif?w=955" alt=":)" class="wp-smiley" height="15" width="15"> return false ; } }); } } } |
activity_map.xml
01
02
03
04
05
06
07
08
09
10
11
12
| <? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" > < fragment android:id = "@+id/map" android:layout_width = "match_parent" android:layout_height = "match_parent" android:name = "com.google.android.gms.maps.SupportMapFragment" /> </ LinearLayout > |
Yang membedakan dengan membuat layanan berbasis lokasi menggunakan MapsV1 adalah, kita tidak perlu menggunakan kelas MapsOverlay untuk menampilkan marker. Semuanya sudah dihandle pada kelas MapsActivity.java.
Dan ini adalah tampilan aplikasi ketika dijalankan, oh iya jangan lupa bahwa tutorial ini hanya bisa dijalankan di device Android langsung, dan tidak bisa dijalankan di emulator Android. Sehingga pastikan kalian mencobanya di smartphone Android.
Demo
Ketika tombol “Get Location” diklik :Klik “View On Map” untuk membuat visualisasi dari lokasi dimana kalian berada B-)
Dan inilah yang muncul ketika kalian klik pada Marker :
Oke, seperti kira-kira seperti itu. Jika masih ada yang bingung silahkan bertanya di bagian komentar. Untuk source code-nya bisa diambil di GitHub saya. Semoga membantu.
Sumber : http://www.twoh.co/2014/08/membuat-aplikasi-location-based-services-di-android-menggunakan-maps-api-v2
saya mengalami error di src nya mas, rata2 error semuanya di MainActivity, MapsActivity dan di res bagian values.. mohon pencerahannya
BalasHapus