Anda di halaman 1dari 11

Buat project baru di Android Studio File ⇒ New Project.

Kemudian pilih Empty Activity dan melanjutkannya hingga selesai.

activity_main.xml
Layout untuk menampilkan data-data lokasi terdekat dari posisi perangkat Andorid pengguna.

1
2 <?xml version="1.0" encoding="utf-8"?>
3 <android.support.v4.widget.SwipeRefreshLayout
4 xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipe"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent">
7
8 <ListView
9 android:id="@+id/list"
10 android:layout_width="match_parent"
android:layout_height="wrap_content"
11 android:divider="@color/list_divider"
12 android:dividerHeight="2dp"
13 android:listSelector="@drawable/list_row_selector" />
14
15 </android.support.v4.widget.SwipeRefreshLayout>
16

list_row.xml
Sebagai tampilan custom listview yang berisi gambar, nama dan jarak terdekat dari posisi pengguna.

1
2
3 <?xml version="1.0" encoding="utf-8"?>
4 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
5 android:layout_width="fill_parent"
6 android:layout_height="wrap_content"
android:background="@drawable/list_row_selector"
7 android:padding="8dp" >
8
9 <com.android.volley.toolbox.NetworkImageView
10 android:id="@+id/gambar"
11 android:layout_width="80dp"
android:layout_height="80dp"
12
android:layout_alignParentLeft="true"
13 android:layout_marginRight="8dp" />
14
15 <TextView
16 android:id="@+id/nama"
17 android:layout_width="wrap_content"
android:layout_height="wrap_content"
18 android:layout_alignTop="@+id/gambar"
19 android:layout_toRightOf="@+id/gambar"
20 android:textStyle="bold" />
21
22 <TextView
23 android:id="@+id/jarak"
android:layout_width="fill_parent"
24 android:layout_height="wrap_content"
25 android:layout_marginTop="5dp"
26 android:layout_toRightOf="@+id/gambar"
27 android:layout_below="@+id/nama" />
28
</RelativeLayout>
29
30
31
Buat folder drawable didalam res dan isi file baru dengan nama list_row_bg.xml, list_row_bg_hover.xml,
dan list_row_selector.xml sebagai style listview.
list_row_bg.xml

1
<?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android"
3 android:shape="rectangle">
4 <gradient
5 android:startColor="@color/list_row_start_color"
6 android:endColor="@color/list_row_end_color"
android:angle="270" />
7 </shape>
8

list_row_bg_hover.xml

1
<?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android"
3 android:shape="rectangle" >
4
5 <gradient
6 android:angle="270"
7 android:endColor="@color/list_row_hover_end_color"
android:startColor="@color/list_row_hover_start_color" />
8
9 </shape>
10

list_row_selector.xml

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


2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
3
4 <item android:drawable="@drawable/list_row_bg" android:state_pressed="false" android:state_se
5 <item android:drawable="@drawable/list_row_bg_hover" android:state_pressed="true"/>
6 <item android:drawable="@drawable/list_row_bg_hover" android:state_pressed="false" android:st
7
</selector>
8

Masuk folder res=>values=>color.xml dan tambahkan code seperti berikut :


color.xml

1
2 <?xml version="1.0" encoding="utf-8"?>
<resources>
3
<color name="colorPrimary">#3F51B5</color>
4 <color name="colorPrimaryDark">#303F9F</color>
5 <color name="colorAccent">#FF4081</color>
6 <color name="list_divider">#d9d9d9</color>
7 <color name="list_row_start_color">#ffffff</color>
<color name="list_row_end_color">#ffffff</color>
8 <color name="list_row_hover_start_color">#ebeef0</color>
9 <color name="list_row_hover_end_color">#ebeef0</color>
10 </resources>
11

Buka build.gradle dan tambahkan volley library didalamnya.


1 compile 'com.mcxiaoke.volley:library:1.0.19'
build.gradle

1 dependencies {
2 compile fileTree(dir: 'libs', include: ['*.jar'])
3 testCompile 'junit:junit:4.12'
4 compile 'com.android.support:appcompat-v7:23.2.1'
5 compile 'com.mcxiaoke.volley:library:1.0.19' /*tambahan*/
}
6

Agar project terstruktur dan terorganisir, buat 4 paket dengan nama adapter, app, module, dan util. Untuk membuat paket
baru , klik kanan pada src=>New=>Peckage dan memberikan nama paket . Contoh : com.dedykuncoro.kuncorohaversine.

Buat class dengan nama LruBitmapCache.java didalam package util dan tambah coding seperti dibawah ini.
Class ini berfingsi untuk mengatur caching network image dalam penyimpanan.
LruBitmapCache.java
package com.dedykuncoro.kuncorohaversine.util;
1
2 import android.graphics.Bitmap;
3 import android.support.v4.util.LruCache;
4
5 import com.android.volley.toolbox.ImageLoader;
6
7 /**
8 * Created by Kuncoro on 03/29/2016.
*/
9 public class LruBitmapCache extends LruCache<String, Bitmap> implements
10 ImageLoader.ImageCache {
11 public static int getDefaultLruCacheSize() {
12 final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
13
14 return cacheSize;
15 }
16
17 public LruBitmapCache() {
18 this(getDefaultLruCacheSize());
19 }
20
public LruBitmapCache(int sizeInKiloBytes) {
21 super(sizeInKiloBytes);
22 }
23
24 @Override
25 protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
26
}
27
28 @Override
29 public Bitmap getBitmap(String url) {
30 return get(url);
}
31
32 @Override
33 public void putBitmap(String url, Bitmap bitmap) {
34 put(url, bitmap);
35 }
}
36
37
38
39
40
41
42

Buat class AppController.java didalam package app dan tambah coding seperti dibawah ini. Class tunggal yang
menginisialisasi class global yang diperlukan. Semua objek yang berhubungan dengan volley diinisialisasi di sini.
AppController.java

1 package com.dedykuncoro.kuncorohaversine.app;
2
3 import android.app.Application;
import android.text.TextUtils;
4
5 import com.android.volley.Request;
6 import com.android.volley.RequestQueue;
7 import com.android.volley.toolbox.ImageLoader;
8 import com.android.volley.toolbox.Volley;
9 import com.dedykuncoro.kuncorohaversine.util.LruBitmapCache;
10
/**
11 * Created by Kuncoro on 03/29/2016.
12 */
13 public class AppController extends Application {
14
15 public static final String TAG = AppController.class.getSimpleName();
16
private RequestQueue mRequestQueue;
17
private ImageLoader mImageLoader;
18
19 private static AppController mInstance;
20
21 @Override
22 public void onCreate() {
23 super.onCreate();
mInstance = this;
24 }
25
26 public static synchronized AppController getInstance() {
27 return mInstance;
28 }
29
30 public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
31 mRequestQueue = Volley.newRequestQueue(getApplicationContext());
32 }
33
34 return mRequestQueue;
35 }
36
public ImageLoader getImageLoader() {
37 getRequestQueue();
38 if (mImageLoader == null) {
39 mImageLoader = new ImageLoader(this.mRequestQueue,
40 new LruBitmapCache());
41 }
42 return this.mImageLoader;
}
43
44 public <T> void addToRequestQueue(Request<T> req, String tag) {
45 // set the default tag if tag is empty
46 req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
47 getRequestQueue().add(req);
}
48
49 public <T> void addToRequestQueue(Request<T> req) {
50 req.setTag(TAG);
51 getRequestQueue().add(req);
52 }
53
54 public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
55 mRequestQueue.cancelAll(tag);
56 }
57 }
58 }
59
60
61
62
63
64
65
66
67

Buat class Jarak.java didalam package module dan tambahkan coding seperti dibawah ini. Class ini berfungsi sebagai
membuat objek untuk setiap item yang diparsing JSON. Objek ini berisi informasi seperti id, nama, jarak, dan url gambar.
Jarak.java

1 package com.dedykuncoro.kuncorohaversine.module;
2
3 /**
* Created by Kuncoro on 03/29/2016.
4 */
5 public class Jarak {
6
7 private String nama, jarak, gambar;
8
9 public Jarak() {
}
10
11
public Jarak(String nama, String jarak, String gambar) {
12 this.nama = nama;
13 this.jarak = jarak;
14 this.gambar = gambar;
15 }
16
public String getNama() {
17 return nama;
18 }
19
20 public void setNama(String nama) {
21 this.nama = nama;
22 }
23
public String getJarak() {
24 return jarak;
25 }
26
27 public void setJarak(String jarak) {
28 this.jarak = jarak;
29 }
30
public String getGambar() {
31 return gambar;
32 }
33
34 public void setGambar(String gambar) {
35 this.gambar = gambar;
}
36
37 }
38
39
40
41
42
43

Buat class CustomListAdapter.java didalam package adapter dan tambahkan coding seperti dibawah ini. Class ini berfungsi
sebagai menampilkan data seperti id, nama, jarak, data url gambar kemudian ditampilkan ke dalam listview.
CustomListAdapter.java

1 package com.dedykuncoro.kuncorohaversine.adapter;
2
3 import android.app.Activity;
4 import android.content.Context;
import android.view.LayoutInflater;
5 import android.view.View;
6 import android.view.ViewGroup;
7 import android.widget.BaseAdapter;
8 import android.widget.TextView;
9
import com.android.volley.toolbox.ImageLoader;
10
import com.android.volley.toolbox.NetworkImageView;
11 import com.dedykuncoro.kuncorohaversine.R;
12 import com.dedykuncoro.kuncorohaversine.app.AppController;
13 import com.dedykuncoro.kuncorohaversine.module.Jarak;
14
15 import java.util.List;
16
/**
17 * Created by Kuncoro on 03/29/2016.
18 */
19 public class CustomListAdapter extends BaseAdapter {
20 private Activity activity;
21 private LayoutInflater inflater;
private List<Jarak> jarakItems;
22 ImageLoader imageLoader;
23
24 public CustomListAdapter(Activity activity, List<Jarak> jarakItems) {
25 this.activity = activity;
26 this.jarakItems = jarakItems;
}
27
28 @Override
29 public int getCount() {
30 return jarakItems.size();
31 }
32
33 @Override
public Object getItem(int location) {
34 return jarakItems.get(location);
35 }
36
37 @Override
38 public long getItemId(int position) {
39 return position;
40 }
41
@Override
42 public View getView(int position, View convertView, ViewGroup parent) {
43
44 if (inflater == null)
45 inflater = (LayoutInflater) activity
46 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
47 convertView = inflater.inflate(R.layout.list_row, null);
48
49 if (imageLoader == null)
50 imageLoader = AppController.getInstance().getImageLoader();
51 NetworkImageView thumbNail = (NetworkImageView) convertView
52 .findViewById(R.id.gambar);
TextView nama = (TextView) convertView.findViewById(R.id.nama);
53 TextView jarak = (TextView) convertView.findViewById(R.id.jarak);
54
55 Jarak j = jarakItems.get(position);
56
57 thumbNail.setImageUrl(j.getGambar(), imageLoader);
58 nama.setText(j.getNama());
jarak.setText(j.getJarak()+" Km");
59
60 return convertView;
61 }
62
63 }
64
65
66
67
68
69
70
71
72
73

Buka MainActivity.java dan tambahkan coding seperti dibawah ini. Class ini digunakan untuk mengirim parameter koordinat
bumi perangkat android ke web service, kemudian web service merespon dan menghitung menggunakan haversine formula
jarak antara lokasi perangkat Android pengguna dengan lokasi-lokasi yang berada dalam database. Setelah dilakukan
perhitungan, maka web service akan menampilkan JSON data-data lokasi berdasarkan lokasi terdekat dari perangkat
pengguna dan data tersebut akan ditampilkan pada listview aplikasi Android.
MainActivity.java

1 package com.dedykuncoro.kuncorohaversine;
2
import android.Manifest;
3 import android.content.Context;
4 import android.content.pm.PackageManager;
5 import android.location.Criteria;
6 import android.location.Location;
7 import android.location.LocationListener;
import android.location.LocationManager;
8 import android.os.Bundle;
9 import android.support.v4.app.ActivityCompat;
10 import android.support.v4.widget.SwipeRefreshLayout;
11 import android.support.v7.app.AppCompatActivity;
import android.util.Log;
12
import android.widget.ListView;
13 import android.widget.Toast;
14
15 import com.android.volley.Response;
16 import com.android.volley.VolleyError;
17 import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;
18 import com.dedykuncoro.kuncorohaversine.adapter.CustomListAdapter;
19 import com.dedykuncoro.kuncorohaversine.app.AppController;
20 import com.dedykuncoro.kuncorohaversine.module.Jarak;
21
22 import org.json.JSONArray;
import org.json.JSONException;
23 import org.json.JSONObject;
24
25 import java.util.ArrayList;
26 import java.util.List;
27
28 /**
29 * Created by Kuncoro on 03/29/2016.
*/
30 public class MainActivity extends AppCompatActivity implements LocationListener,
31 SwipeRefreshLayout.OnRefreshListener {
32
33 SwipeRefreshLayout swipe;
34 ListView list;
CustomListAdapter adapter;
35 List<Jarak> itemList = new ArrayList<>();
36 Double latitude, longitude;
37 Criteria criteria;
38 Location location;
39 LocationManager locationManager;
String provider;
40
41 // sesuaikan ip laptop/PC atau menggunakan ip emulator bawaan android studio 10.0.2.2
42 private static final String url = "http://172.20.10.2/android/haversine/haversine.php?lat=
43 private static final String TAG = MainActivity.class.getSimpleName();
44
45 @Override
46 protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
47 setContentView(R.layout.activity_main);
48
49 // menyamakan variabel pada layout dan java
50 list = (ListView) findViewById(R.id.list);
51 swipe = (SwipeRefreshLayout) findViewById(R.id.swipe);
52
// mengisi data dari adapter ke listview
53 adapter = new CustomListAdapter(this, itemList);
54 list.setAdapter(adapter);
55
56 locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
57 criteria = new Criteria();
58
59 provider = locationManager.getBestProvider(criteria, false);
60
swipe.setOnRefreshListener(this);
61
62 swipe.post(new Runnable() {
63 @Override
64 public void run() {
65 swipe.setRefreshing(true);
lokasi();
66 }
67 }
68 );
69
70 }
71
72 @Override
public void onRefresh(){
73 lokasi();
74 }
75
76 // fungsi ngecek lokasi GPS device pengguna
77 private void lokasi(){
78 location = locationManager.getLastKnownLocation(provider);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION
79 PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
80 Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRAN
81 // TODO: Consider calling
82 // ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
83 // public void onRequestPermissionsResult(int requestCode, String[] permissions
84 // int[] grantResults)
85 // to handle the case where the user grants the permission. See the documentation
86 // for ActivityCompat#requestPermissions for more details.
87 return;
}
88
89 // permintaan update lokasi device dalam waktu 10 detik
90 locationManager.requestLocationUpdates(provider, 10000, 1, this);
91
92 if(location!=null){
93 onLocationChanged(location);
callListVolley(latitude, longitude);
94 }else{
95 Toast.makeText(getBaseContext(), "Lokasi device pengguna tidak ditemukan.\nMohon
96 Toast.LENGTH_LONG).show();
97 /* latitude longitude Alun-alun Demak sebagai default jika tidak ditemukan lokasi
98 callListVolley(-6.894796, 110.638413);
}
99 }
100
101 // untuk menampilkan lokasi wisata terdekat dari device pengguna
102 private void callListVolley(double lat, double lng) {
103 itemList.clear();
104 adapter.notifyDataSetChanged();
105
swipe.setRefreshing(true);
106
107 JsonArrayRequest jArr = new JsonArrayRequest(url + lat +"&lng="+ lng,
108 new Response.Listener<JSONArray>() {
109 @Override
110 public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
111
112 // Parsing json
113 for (int i = 0; i < response.length(); i++) {
114 try {
115
116 JSONObject obj = response.getJSONObject(i);
117 Jarak j = new Jarak();
j.setNama(obj.getString("nama"));
118 j.setGambar(obj.getString("gambar"));
119
120 double jarak = Double.parseDouble(obj.getString("jarak"));
121
122 j.setJarak(""+round(jarak, 2));
123
124 itemList.add(j);
125
} catch (JSONException e) {
126 e.printStackTrace();
127 }
128
129 }
130
131 // memberitahu adapter jika ada perubahan data
132 adapter.notifyDataSetChanged();
133
swipe.setRefreshing(false);
134 }
135 }, new Response.ErrorListener() {
136
137 @Override
138 public void onErrorResponse(VolleyError error) {
139 VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(getBaseContext(), error.getMessage(), Toast.LENGTH_LONG).show(
140 swipe.setRefreshing(false);
141 }
142 });
143
144 // menambah permintaan ke queue
AppController.getInstance().addToRequestQueue(jArr);
145 }
146
147 @Override
148 public void onBackPressed(){
149 finish();
150 System.exit(0);
}
151
152 // untuk menyederhanakan angka dibelakan koma jarak
153 public static double round(double value, int places) {
154 if (places < 0) throw new IllegalArgumentException();
155
156 long factor = (long) Math.pow(10, places);
value = value * factor;
157 long tmp = Math.round(value);
158 return (double) tmp / factor;
159 }
160
161 // untuk menentukan lokasi gps dari device pengguna
162 @Override
public void onLocationChanged(Location location) {
163 latitude = location.getLatitude();
164 longitude = location.getLongitude();
165
166 // untuk melihat latitude longitude posisi device pengguna pada logcat ditemukan atau
167 Log.d(TAG, " "+ latitude +", "+longitude);
168 }
169
@Override
170 public void onStatusChanged(String provider, int status, Bundle extras) {
171
172 }
173
174 @Override
175 public void onProviderEnabled(String provider) {
176
}
177
178 @Override
179 public void onProviderDisabled(String provider) {
180
181 }
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

Tambahkan beberapa perijinan pada AndroidManifest.xml seperti dibawah ini :


AndroidManifest.xml

1
2
3 <?xml version="1.0" encoding="utf-8"?>
4 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
5 package="com.dedykuncoro.kuncorohaversine">
6
7 <!-- Tambahan -->
<uses-permission android:name="android.permission.INTERNET"/>
8
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
9 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
10 <!-- The following two permissions are not required to use
11 Google Maps Android API v2, but are recommended. -->
12 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
13 <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"
14 <!-- Tambahan -->
15
16 <application
17 android:name=".app.AppController" <!-- Tambahan -->
18 android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
19 android:label="@string/app_name"
20 android:supportsRtl="true"
21 android:theme="@style/AppTheme">
22 <activity android:name=".MainActivity">
<intent-filter>
23 <action android:name="android.intent.action.MAIN" />
24
25 <category android:name="android.intent.category.LAUNCHER" />
26 </intent-filter>
27 </activity>
28 </application>
29
</manifest>
30
31
32

Anda mungkin juga menyukai