GPS koordinatlarınızı yorumlayarak çalışan bir çok mobil uygulama bulunmaktadır.Örneğin; Bitaksi, Mobiett, Teknosa gibi mobil uygulamaları ele alırsak, Bitaksi uygulaması, size en yakın taksiyi tavsiye eder, gitmek istediğiniz noktaya ne kadar sürede ulaşacağınızı hesaplar. Mobiett uygulaması, duraklara yaklaşan otobüslerin takip edilmesinde fayda sağlar.Son olarak Teknosa mobil uygulamasından bahsetmek gerekirse, bu uygulama ise en yakın Teknosa mağazalarına ulaşım konusunda yardım için kullanılır.Gördüğünüz gibi mobil uygulamalarda GPS koordinatlarını kullanarak hayatınızı çok daha kolaylaştırabilirsiniz.
Malum devir kolaylık ve hız devri olduğu için bende bu makalemde,bir Android uygulamasında kullanıcının Gps konumu kullanarak, kullanıcıya en yakın mesafedeki restoranları bulup, Google Maps üzerinde gösterilmesini örnekledim.
Projenin İşleyişi
İlk önce Android uygulama tarafında, kullanıcının GPS koordinat (latitude ve longitude) değerlerini buluyoruz. Sonrasında bu GPS koordinatlarını RESTful Web servis aracılığıyla sunucuya post ediyoruz. Php programlama dili ile programlama yaparak, Mysql veritabanımda bulunan restoranların latitude ve longitude değerlerini alıp, Android uygulama tarafından gelen GPS koordinat değerleri ile karşılaştırarak kullanıcının konumuna en yakın mesafedeki restoranları bulduk. Bulduğumuz bu restoranların latitude ve longitude değerlerini Android uygulama tarafına gönderdik ve bu konumları Google Maps üzerinde işaretleyerek gösterdik.
Sonuç olarak da aşağıdaki gibi bir görüntü ortaya çıkıyor.
Örnek projemizi kodlamaya başlamadan önce bazı işlemler yapmamız gerekmektedir.Bu işlemleri sırayla yapmaya başlayalım.
1- Google Play Services Yükleme
Google haritayla ilgili bir geliştirme yapacağımızdan dolayı, Google Play Services yüklememiz gerekmektedir. Bunun için Sdk manager’ı açıp Extras bölümünden Google Play Services işaretleyip, yükleme işlemini gerçekleştirin.
2- Google Maps API Key Oluşturma
Google Maps API Key oluşturma işlemini aşağıdaki video eğitimimi izleyerek öğrenebilirsiniz.
Şimdi ise projenin kodlarını yazmaya başlayalım…
Android Uygulamada Yapılacak İlgili Ayarlar ve Kod Yazımı
1-Oluşturduğumuz Android Projeye İlgili Kütüphaneleri Yükleme
Android Studio Ide ile oluşturduğum projemin app dizinin altındaki build.gradle dosyasını açıyoruz. Dependencies kod bloklarının arasına aşağıdaki kodları yerleştirerek Google Play services API ve Http Client kütüphanelerini yüklüyoruz.
1 2 |
compile 'com.google.android.gms:play-services-maps:7.8.0' compile 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2' |
2-AndroidManifest Dosyasına İlgili Ayarları Ekleme
• AndroidManifest dosyasına, daha önce üretmiş olduğumuz Google API Key’i ekleme işlemini yapacağız.Bunun için aşağıda görmüş olduğunuz meta-data tag kodunun içindeki value özelliğine Google API Key’i ekleyeniz.
1 2 3 |
<!-- Google API Key --> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyAwLlnq4oNcZIj0qarXtoPnfjtySbDlPCc" /> |
• Google maps ile ilgili işlemler yapabilmemiz için AndroidManifest.xml dosyamıza kodlar ekleyerek, bazı izinleri vermemiz gerekmektedir.
Kullanacağımız izinlerin açıklamaları aşağıda bulunmaktadır.
ACCESS_NETWORK_STATE –veri indirilebilir mi yoksa indirilemez miyi anlamak için ağ durumunu kontrol etmede kullanılan izin
INTERNET – internet bağlantı durumunu kontrol etmede kullanılan izin
WRITE_EXTERNAL_STORAGE – Google Maps’in harita datalarını harici depolamaya yazdığı gibi yazma için izin
ACCESS_COARSE_LOCATION – WiFi ve cep verileri kullanarak, kullanıcının yerini belirlemek için kullanılan izin
ACCESS_FINE_LOCATION – GPS kullanarak, kullanıcının konumu belirlemek için kullanılan izin
OpenGL ES V2 –Google Maps V2 için gerekli izin
İzinler ve Maps key’in AndroidManifest dosyasında eklenmiş hali sonuç olarak şu şekildedir.
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 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tugba.gps_googlemaps" > <uses-permission android:name="com.tugba.gps_googlemaps.permission.MAPS_RECEIVE" /> <permission android:name="com.tugba.gps_googlemaps.permission.MAPS_RECEIVE" android:protectionLevel="signature" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Maps V2 için OpenGL ES 2.0. gerekli --> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- Google API Key --> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyAwLlnq4oNcZIj0qarXtoPnfjtySbDlPCc" /> </application> </manifest> |
3-Xml Kodları
activity_main.xml kodları:
1 2 3 4 5 6 7 8 9 10 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <fragment android:id="@+id/map" android:name="com.google.android.gms.maps.MapFragment" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout> |
4-Java Kodları
MainActivity.java kodları:
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 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 96 97 98 99 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 |
import android.app.Activity; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.StrictMode; import android.util.Log; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapFragment; import com.google.android.gms.maps.model.CameraPosition; 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 org.json.JSONArray; import org.json.JSONObject; public class MainActivity extends Activity implements LocationListener { boolean isGPSEnabled = false; boolean isNetworkEnabled = false; boolean canGetLocation = false; Location location; // location double latitude; // latitude double longitude; // longitude private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute protected LocationManager locationManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getLocation(); sendLatLng_in_Server(getLatitude(), getLongitude()); showGoogleMap(getLatitude(), getLongitude(),"konumum"); } public Location getLocation() { try { locationManager = (LocationManager)getSystemService(LOCATION_SERVICE); // GPS durumunu(true/false) elde ettik isGPSEnabled = locationManager .isProviderEnabled(LocationManager.GPS_PROVIDER); // Network durumunu(true/false) elde ettik isNetworkEnabled = locationManager .isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { //Network olmadığında bu koşula girer } else { this.canGetLocation = true; //Network Provider'dan ilk lokasyonu aldık if (isNetworkEnabled) { locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } //Eğer GPS etkin ise GPS Services kullanarak latitude/longitude değerlerini alıyoruz if (isGPSEnabled) { if (location == null) { locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } } } } catch (Exception e) { e.printStackTrace(); } return location; } /** * GPS listener kullanılmasının durdurulması * Cihazda Gps kullanımı durdurulduğunda, uygulamada bu metod çağırılır * */ public void stopUsingGPS(){ if(locationManager != null){ locationManager.removeUpdates(MainActivity.this); } } /** * latitude(enlem) değerini donduren metod * */ public double getLatitude(){ if(location != null){ latitude = location.getLatitude(); } return latitude; } /** * longitude(boylam) değerini donduren metod * */ public double getLongitude(){ if(location != null){ longitude = location.getLongitude(); } return longitude; } @Override public void onLocationChanged(Location location) { } @Override public void onProviderDisabled(String provider) { } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } /** * Google Map üzerinde latitude ve longitude değerlerine göre konumları işaretleyerek gösteren metod * @param lat * @param lng * @param locatioName */ public void showGoogleMap(double lat,double lng,String locatioName){ LatLng TutorialsPoint = new LatLng(lat, lng); GoogleMap googleMap = null; try { if (googleMap == null) { googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap(); } //Haritanın üzerinde bulunan, haritayı büyütüp küçültmek için kullanılan zooming button aktif ettim googleMap.getUiSettings().setZoomControlsEnabled(true); //Harita üzerinde işaretlenmiş konumlara haritayı büyüterek yani zoomlama yaparak fokuslanmasını yapan kod CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(lat, lng)).zoom(12).build(); googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); //-- googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); //Google Map üzerinde konum işaretlemeyi sağlayan imleci olusturan kod //title metodu; imlec konulan yere isim vermenizi sağlar Marker TP = googleMap.addMarker(new MarkerOptions().position(TutorialsPoint).title(locatioName)); } catch (Exception e) { e.printStackTrace(); } } //Konumuma en yakın olan yerlerin enlem ve boylam değerlerini sunucudan alarak haritada //bu yerlerin işaretlenmesini sağlayan metod private void sendLatLng_in_Server(double latitude,double longitude){ //StrictMode kullanarak,ağ erişiminin güvenli bir şekilde yapılmasını sağlıyoruz... StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); String wcfUrl="http://www.tugbaustundag.com/restaruantMaps.php"; JSONObject obj=new JSONObject(); String jsonString=""; try { //Konum değerlerimi sunucuya gönderiyorum... obj.put("latitude",latitude); obj.put("longitude",longitude); HttpClientMy HttpClientMy=new HttpClientMy(); jsonString=HttpClientMy.callWebService(wcfUrl, obj); //Json objesi olusturuyoruz.. JSONObject jsonResponse = new JSONObject(jsonString); //Olusturdugumuz obje üzerinden json string deki dataları kullanıyoruz.. JSONArray jArray=jsonResponse.getJSONArray("Android"); //Konumuma en yakın olan yerlerin enlem ve boylam değerlerini sunucudan aldım. for(int i=0;i<jArray.length();i++) { JSONObject json_data=jArray.getJSONObject(i); String restoran = json_data.getString("restoran"); Log.w("restoran",restoran); Double lat= json_data.getDouble("latitude"); Double lng= json_data.getDouble("longitude"); //ve bana en yakın yerleri haritada işaretleyerek göstermek için showGoogleMap metodunu kullandım showGoogleMap(lat, lng,restoran); } } catch (Exception e) { e.printStackTrace(); } } } |
HttpClientMy.java kodları:
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 |
import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; import org.json.JSONObject; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URI; public class HttpClientMy { //RESTful Web servisini çağırıp, içerikleri sunucuya gönderen ve sunucudan data çekmeyi sağlayn methodu public static String callWebService(String wcfUrl,JSONObject jsonObject) { String jsonString = ""; try { //Bağlantıyı sağlamak için HttpClient sınıfımızı tanımlıyoruz HttpClient httpClient = new DefaultHttpClient(); HttpResponse response; //Post işlemi için sınıfımızı tanımlıyoruz... HttpPost post=new HttpPost(); //Json objesinde tuttugumuz icerikleri String hale getirip, setEntity methoduna atıyoruz.. HttpEntity httpEntity; StringEntity stringEntity=new StringEntity(jsonObject.toString(), HTTP.UTF_8); stringEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); httpEntity=stringEntity; post.setEntity(httpEntity); //RESTful Web Servisinin baglancağı url yi veriyoruz... post.setURI(new URI(wcfUrl)); post.setHeader("Content-type", "application/json"); // HttpEntity tutulan dataların HttpResponse tarafından çalıstırılmasını saglama.. response=httpClient.execute(post); //response değişkenindeki nesneyi, json string değerine çeviriyoruz... BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = rd.readLine()) != null) { sb.append(line + NL); } //Elde ettigimiz json string i değişkene atadık jsonString = sb.toString(); rd.close(); } catch (Exception e) { e.printStackTrace(); } return jsonString; } } |
Sunucuda Yapılacak İlgili Ayarlar ve Kod Yazımı
Sunucu veritabanındaki(mysql) tabloların oluşturulması
Sunucu veritabanındaki(mysql) tablonun oluşturulması gerekmektedir. restoranLokasyon tablosunu aşağıdaki resimde gösterildiği gibi oluşturulmalıdır.
Benim veritabanımda restoranların latitude ve longitude değerleri bulunmaktadır.Sizde veritabanınıza Google Maps’dan farklı restoranların latitude ve longitude değerlerini alıp, kayıt ederek örnek data oluşturabilirsiniz.
Php programlama dilini kullanarak yazılmış, sunucu taraflı kodlar
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 |
<?php //Veritabanımıza bağlanıyoruz.. mysql_connect("localhost","username","password")or die("baglanamadim"); mysql_query('SET NAMES utf8'); mysql_query('SET CHARACTER_SET utf8'); mysql_select_db("gps"); //İki konum arasındaki mesafeyi hesaplayan fonksiyon function calculate_distance($lat1, $lon1, $lat2, $lon2, $unit='N') { $theta = $lon1 - $lon2; $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); $dist = acos($dist); $dist = rad2deg($dist); $miles = $dist * 60 * 1.1515; $unit = strtoupper($unit); if ($unit == "K") { return ($miles * 1.609344); } else if ($unit == "N") { return ($miles * 0.8684); } else { return $miles; } } //RESTful Web servisinde varolan kullanıcının GPS koordinat değerlerini çekiyoruz.. $json = file_get_contents('php://input'); $obj = json_decode($json); //Mysql veritabanımda bulunan restoranların latitude ve longitude değerlerini ve //Android uygulama tarafından gelen GPS koordinat değerlerini calculate_distance fonksiyon gonderdim $sql=mysql_query("select * from restoranLokasyon"); while($row=mysql_fetch_assoc($sql)){ //Kullanıcının konumu ile veritabanındaki restoranların konumları arasındaki mesafeleri hesapladık ve milesArray array atadım. $milesArray[$row[id]]=calculate_distance($obj->{'latitude'},$obj->{'longitude'}, $row['latitude'], $row['longitude']); } //milesArray dizisindeki uzaklık değerlerini sıraladım asort($milesArray,SORT_NUMERIC); $i=0; //Kullanıcının konumuna en yakın olan yani uzaklığı en az olan 3 restoranın latitude ve longitude değerlerini $encode dizisine atadım foreach ($milesArray as $key => $id) { $sql2=mysql_query("select * from restoranLokasyon where id='".$key."'"); while($allRow=mysql_fetch_assoc($sql2)){ $new = array( 'latitude' => $allRow['latitude'], 'longitude' => $allRow['longitude'], 'restoran' => $allRow['restoran'] ); $encode[] = $new; } if($i>2){break;} $i++; } //$outputArr dizisini json ile şifreleyip(encode), Web servise gönderdim $outputArr = array(); $outputArr['Android'] = $encode; echo json_encode($outputArr); mysql_close(); ?> |
Son olarak ufak bir not: Bu yukarıda anlattığım projemin kodlarını indirmek isterseniz; yapmanız gereken tek şey github linkine tıklamak.
Hayatınızın daha da kolaylaşması dileğiyle…
Çok güzel uygulama. Teşekkürler…
Paylaşım için teşekkür ederim, uygulamayı çalıştırdığımda emilatörde de cihazda da, uygulama sorunsuz açılıyor ama harita gözükmüyor. Sorun neden kaynaklanıyor olabilir acaba hatam şu şekilde, Muhtemelen Maps Api den kaynaklanan bir hata var ama bir türlü hatayı düzeltemedim yardımcı olursanız sevinirim.
Authorization failure. Please see https://developers.google.com/maps/documentation/android/start for how to correctly set up the map.
E/Google Maps Android API: In the Google Developer Console (https://console.developers.google.com)
Ensure that the “Google Maps Android API v2” is enabled.
Ensure that the following Android Key exists:
API Key: AIzaSyC7JmS3f0VmOUVOQczuoHufztv5FaIMLmo
Android Application (;): 51:26:1F:66:64:58:06:FA:E8:A4:2F:6F:7C:E6:B5:95:D1:6A:F6:60
Paylaşım için teşekkür ederim, uygulamayı çalıştırdığımda emilatörde de cihazda da, uygulama sorunsuz açılıyor ama harita gözükmüyor. Sorun neden kaynaklanıyor olabilir acaba hatam şu şekilde, Muhtemelen Maps Api den kaynaklanan bir hata var ama bir türlü hatayı düzeltemedim yardımcı olursanız sevinirim.
(Kendi projemdeki kod hatasını atmışım sizin projenizdekini atarsam daha sağlıklı olur sanırım)
02-25 05:01:50.987 11578-11745/? E/Google Maps Android API: Authorization failure. Please see https://developers.google.com/maps/documentation/android/start for how to correctly set up the map.
02-25 05:01:50.988 11578-11745/? E/Google Maps Android API: In the Google Developer Console (https://console.developers.google.com)
Ensure that the “Google Maps Android API v2” is enabled.
Ensure that the following Android Key exists:
API Key: AIzaSyAwLlnq4oNcZIj0qarXtoPnfjtySbDlPCc
Android Application (;): 51:26:1F:66:64:58:06:FA:E8:A4:2F:6F:7C:E6:B5:95:D1:6A:F6:60;com.tugba.gps_googlemaps
tmm sorunumu hallettim, başkalarına yardımcı olmak adına kendi Api mi projeye yerleştirdiğimde sorun kalmadı 🙂
Yüreğinize kaleminize sağlık çok güzel bir anlatım
Merhaba Tuğba Hanım, Yaptığınız paylaşımları çok yakından takip ediyorum. Geleceği Yazanlar’dan yaptıklarınız gibi başarılarınızın devamını diliyorum.
locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); bu satırlarda Add Permission Check demekte lütfen yardım et.
Merhaba. Öncelikle Paylaşımınız için teşekkürler ikinci olarakta bu enlem ve boylam değerlerini kendimiz girmek yerine bir filtreleme kullanamıyor muyuz?
Merhaba Tuğba hanım,
Yaklaşık olarak 100.000 tane firma verisi olan bir sql var elimde. Bu sql sorgunuzdaki while döngüsü kaç sonuç sorguluyor? Veritabanının hepsi ise işe yaramaz gibi yavaşlatır diye düşünüyorum.