Android- Google Maps API

Google Maps API, Google’ın haritalar özelliğini android uygulamalarımızda kullanma fırsatını sunar. Harita üzerinde dilediğimiz yere marker koyabilmek, belirlediğimiz iki veya daha fazla nokta arasına çizgiler çizmek, belli bir bölgeyi belirtmek için çokgenler koymak gibi bir çok interaktif işlemi yapabilmemizi sağlar.

Biz uygulamamızda bir EditText aracılığı ile gitmek istediğimiz konumu yazıp “Go” butonumuza tıkladığımızda haritada o konuma gideceğiz oraya bir marker ekleyeceğiz, ZoomIn ZoomOut yapabilmek için butonlarımızı ekleyeceğiz ve de son olarak Harita tipini değiştirmek için bir buton ekleyeceğiz. Bu işlevleri gerçekleştirebilmek için ponçik ponçik sınıflarla tanışacağız. Önce uygulamamızın son halinin bir fotoğrafını görelim bu sayede kodlarımızı açıklarken hayal edebilmemiz daha kolay olur diye düşünmekteyim.Son halimiz şu şekilde:

Evet şimdi adım adım uygulamamızı yazabiliriz.
Android Studio’da yeni bir proje başlattığımızda bir kaç yönerge sonrası “Add an Activity to Mobile” kısmına geldiğimizde “Google Maps Activity” seçiyoruz.
Bu seçimi yaptığımızda varsayılan olarak bizi şu hiyerarşi karşılıyor.

İlk işimiz “Google Play Service” paketini indirmek olmalı çünkü Google Maps API ; Google Play Service’n bir parçası. Bunun için Android Studio’da Tools/Android/Android SDK/SDK Tools yolunu izleyerek Google Play Service paketini indiriyoruz.

İkinci işlem olarak values klasörümüzde google_maps_api.xml dosyamızı açıyoruz.

Burada 7. satırımızdaki adrese gidip uygulamamız için “API KEY” ediniyoruz. Ve bu API KEY 18. satırda “YOUR_KEY_HERE” kısmına ekliyoruz.Bu işlemi yaptığımızda otomatik olarak AndroidManifest.xml dosyamıza da key eklenmiş olacaktır.Çünkü varsayılan olarak “google_maps_key” yolu verilmiştir. Bu key Google Maps sunucularına bağlanmak için gereklidir ve ücretsizdir. Bu sayede Google Maps üzerinde sınırsız harita gösterimini sağlamış oluyoruz.


Evet ön hazırlığı bitirmiş olduk. :) Şimdi hemen layout/activity_maps.xml’e gidelim ve tasarımımızı hazırlayalım. Uygulamamızın son halinin görüntüsünü görmüştük. Şimdi kodlama zamanı.

“activity_maps.xml” ilk açtığımızda bizi karşılayan kodlar :

Burada 5. satırda fragment etiketinin name attribute olarak verdiğimiz değer sayesinde Google Maps API içerisindeki MapFragment sınıfını baz aldığımızı belirttik. Java kısmına geçtiğimizde ayrıntılı olarak tekrar açıklayacağız.
Kendi tasarımımızdaki componentlerin yerleşimini de bir görsel üzerinde şu şekilde anlatmaya çalıştım:

Şimdi kodlarımızı görelim ve açıklamamız gereken kısımları açıklayalım. Görüntü ile kodları karşılaştırdığımızda kurguyu hayal etmemiz daha kolay olacaktır. :)

Burada 7–27 satırlara bakarsak LinearLayout içerisine EditText ve Butonu yerleştirdik ve 8. satırda orieantation attribute olarak horizontal verdik. Bu sayede EditText ve Butonu yatayda hizalamış olduk.

42. satırda fragment context’in MapsActivity sınıfından dolacağını belirttik.
Ve böylelikle tasarım kısmını bitirdik. Sırada MapsActivity.java kısmında neler oluyor o kısmı kurcalayalım.


Java kısmında butonlarımızın clicklenme olaylarını kontrol edeceğiz. Fragment’ın ne olduğundan bahsedeceğiz. Parça parça anlatıp kodları yazmaktansa yine tüm kodu paylaşıp satır numaralarıyla nerde nereyi kontrol ettik açıklamaya çalışacağım. MapsActivity.java dosyamız şu şekilde:

3. satırda MapsActivity sınıfımızın Fragment sınıfından extends edildiğini ve de onMapReadyCallback interface’ni implement ettiğini görüyoruz.Eğer extends etmek(kalıtmak) gibi terimlerine yabancıysanız Java SE Inheritance (Kalıtım) konusuna göz atmanızda fayda var. İlk olarak Fragment sınıfından bahsedelim.
Fragment sınıfı, bir Activity içerisinde birden fazla arayüz oluşturmamızı sağlayan sınıftır. Tek bir activity içerisinde birden fazla fragment, birden fazla ekran oluşturabiliriz.Burada bilmemiz gereken Fragment’ın yaşam süresi bağlı olduğu activity’nin yaşam süresiyle aynıdır. 
onMapReadyCallBack Interface: Haritamız hazır olduğunda onMapReady() metodunu tetikler ve GoogleMap’in null olmayan bir örneğini bize sunar. 68–75. satır arasında varsayılan olarak haritamızın Sydney veri olarak döndürdüğünü görebiliriz.

5. satırda GoogleMap sınıfından mMap oluşturarak , marker ekleme, zoom işlemleri , harita tipini değiştirme gibi tüm işlemlerimizi mMap üzerinden yapacağız.

12. satırda SupportMapFragment sınıfı ile FragmentManager sınıfına erişiyoruz ve tıpkı findViewById() metoduna benzeyen findFragmentById() metodu sayesinde “activity_maps.xml” de oluşturduğumuz fragmenta erişiyoruz. Bu fragment’ın getMapAsync() metodu da bize GoogleMap sınıfnı tipinden ponçik bir harita verisi döndürüyor. Bir sınıfın içerisinde neler oluyor merak ediyorsak editör üzerinden CTRL basılı tutarak tıklarsak içeride neler neler oluyor görebiliriz. :)

ZoomControls sınıfı: 16. satırda bizi karşılamakta olan sınıfımız isminden anlaşılacağı üzere zoomIn ve zoomOut işlemlerini gerçekleştiriyor.İlk olarak ZoomControls sınıfından zoom adında bir nesne oluşturduk. 17. satırda zoom nesnesine setOnZoomOutClickListener() metodunun onClick() metodunu override ederek , bizim tüm işlemlerimizde yanımızda olan mMap nesnemize zoomOut işlemini ve benzer olarak zoomIn işlemini yaptırdık.

getMapType() metodu: 30. satırda btn_MapType adında bir buton tanımlayıp, “activity_maps.xml”de tanımladığımız başlangıçta UYDU şeklinde gözüken butonumuzu atadık. Daha sonra setOnClickListener metodu ile haritamızın tipinin durumuna göre if kontrolü yaptık. Fark ettiysek haritayla ilgili bir işlem yapacaksak hemen mMap başvuruyoruz.Çünkü tümmm işlemlerden o sorumlu. Harita şefimiz diyebiliriz. :) Butona her tıkladığımızda Uydu görünümündeyse Normal, Normal görünümdeyse uyduya geçecek. Bunuda getMapType() ile olan durumunu kontrol ettik gelen sonuca göre de yeni durumu setMapType() ile set ettik ve butonun üzerindeki yazıyı da güncelledik.

Eveet. En can alıcı kısma gelmiş bulunmaktayız. Go butonuna tıkladığımızda neler olacak ? 
40. satırda btnGo adında bir buton oluşturduk ve btn_Go id’sine sahip Go butonunu atadık. Bu atama işlemini de her seferinde findViewById ile id’sinden çekmelerle uğraşmamak için yapıyoruz. Sonuç olarak butonumuzun adı btnGo.
btnGo setOnclickListener ile clicklenme anında neler olacak onları yazmaya başlıyoruz.

49. satırda EditText’imize etLocation adını verdik.
50. satırda etLocationdan gelen veriyi String bir ifadeye çevirip, String tipindeki location değişkenimize atadık.

51. satırda kullanıcının null yada “ “ boşluk girmesinin önüne geçen if kontrolümüzü yazdık. Yani kullanıcı bir veri girdiyse ;

52. satırda Address tipinde adressList adında bir liste oluşturduk.
53.satırda Geocoder sınıfından geocoder adında bir nesne oluşturduk. Geocoder sınıfı getFromLocationName() metodu ile bize EditTexte girilen tüm sonuçları döndürür. Bu dönen sonuçları da adressList’imize atadık.

59. satırda adressList’imizin içindeki adreslerden 0.sını yani ilk dönen sonucu yine Address tipinde address’e atadık.

LatLng sınıfı: 60. satırda bizi karşılayan bu sınıfın kurucu metodu iki parametre alır.Birincisi latitude(enlem), ikincisi longitude(boylam). Bizde adres listemizden dönen ilk adrese ait enlem ve boylam bilgilerini getLatitude() ve getLongitude() metodları sayesinde alıp Latlng sınıfından oluşturduğumuz latlng nesnesine atadık. Artık adresimizin enlem ve boylam bilgilerine de sahibiz.
Bu bilgiler sayesinde harita şefimiz olan mMap’e marker ekletebileceğiz ve kamera animatörümüze bu enlem ve boylam bilgilerine doğru git diyebileceğiz. Diyelim öyleyse. :)

61. satırda: mMap nesnemize addMarker metodu ile marker ekleme işlemi yaptıracağız.MarkerOptions() ile position ve title bilgisini gönderiyoruz. Position bilgimiz latlng içerisinde , title ise EditText’e girip Stringe çevirdiğimiz location değişkeni içerisinde. Marker’ı da eklemiş olduk.

animateCamera(): Kamerayı hareket ettirmek için yani konumu değiştirmek için CamareUpdate sınıfının animateCamera() metodunu kullanır. Kameramızı hareket ettirmenin ilk yolu zoom seviyesini değiştirmektir.Bunu da CameraUpdateFactory sınıfının statik metodu olan newLatLng(LatLng) ile yapıyoruz. Bu statik metod bizi enlem ve boylam bilgimize uçuruyor. :)

Efendim Go butonun clicklenme olayında:
EditTexte girilen veriyi aldık , Stringe çevirdik.
Bu isme sahip tüm konumları bulduk listemize ekledik.
Listemizin ilk elemanı bizim adresimiz oldu.
Bu adresin enlem ve boylam bilgilerini aldık.
Kameramızı oraya yönelttik ve oraya bir marker ekledik. :)

68–75. satırlardan zaten bahsetmiştik. Harita ilk yüklendiğinde Sydneyi göstermeyi sağlamıştık. Şimdi baktığınızda daha anlamlı gelecektir.Çünkü tüm ponçik sınıflarla tanıştık.

Son olarak baş belası izinler var.

77–85. satırlarda SDK VERSION kontrolü yaptık.
onRequestPermissionsResult() interface: Bu interface izin isteklerinin sonuçlarını alacağımız sözleşme gibi düşünebiliriz.Tek tek senin requestCode ile paketteki RequestCode aynı mı diye if blogunda kontroller yaparak haritanın setMyLocationEnabled() ile set edilip edilmeyeceğine karar veriyoruz.

Tüm sınıflardan bahsetmek istediğim için epey uzadı. Umarım açıklayıcı olmuştur. Eksik ve yanlışlarım olduysa geri dönüşlerinizi beklemekteyim. 
Yazı boyunca buradan faydalandım. 
Kodların tamamına şuracıktan erişebilirsiniz. :)