GPS ile En Yakın Noktaları Bulma: Android Location Services ve Google Maps Service API

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.

12

Ö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.

googleplayservices

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.

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.

<!-- 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.

<?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ı:

<?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ı:

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://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ı:

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.

db

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

<?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 aşağıya koyduğum KODLARI İNDİR resmine tıklamak.

download

Hayatınızın daha da kolaylaşması dileğiyle…

Kategori Genel
Etiketler