Google, Yandex ve Huawei API’leri ile Harita Yönlendirmeleri — Kotlin

Ali Şamil Küçük
15 min readNov 4, 2021

--

Selam! Bu yazımda sizlerle günlük hayatta sıkça kullandığımız haritalardaki yönlendirme işlemlerinin nasıl yapıldığını anlatacağım. Bu işlem ile basitçe kendinizin belirleyeceği iki nokta arasında rota çizdirme işlemini nasıl yapacağınızı öğreteceğim. Ayrıca yönlendirme işlemini ayrı ayrı Google Maps, Yandex Maps ve Huawei Maps üzerinde her platformun kendi MapsKit’i ile yapacağız. Uygulamanızda hangi platformun harita kitini kullanacağınıza kendiniz karar verebilirsiniz.

Yapacağımız işlemleri yeni bir proje oluşturarak ya da hali hazırda var olan projelerinizin üzerine ekleyerek kullanabilirsiniz. Her iki yolu tercih ederken de ilk olarak üzerinde durmamız gereken konu ise izinler.

İzinler

Hazırsak ilk iş bütün API’lerde ortak olarak kullanacağımız internet izinlerini yazarak başlayalım. Bu izinleri AndroidManifest.xml dosyasında manifest etiketinin altına yazıyoruz. Yapacağımız uygulamalarda kendi konumumuzu kullanmayacağımız için bu uygulamada konum izni almıyoruz.

İzinleri de aldığımıza göre ilk olarak Google Maps Mapkit ile rota nasıl çizilir öğrenmeye başlayalım.

Google Maps ve Google Directions API ile Rota Çizimi

Google Maps ve Directions API ile yönlendirme yaparken haritanın uygulamaya entegre edilmesi ve üzerinde işaretlemeler yapılması işlemlerini Google Maps API ile gerçekleştireceğiz. Daha sonra ise yaptığımız işaretlemelere göre yönlendirme işlemini ise Retrofit ve RxJava yardımı ile Directions API’ye istek yaparak gerçekleştireceğiz. Yaptığımız isteğin sonucunda bize API’den yönlendirmeyi çizebilmemiz için noktalar geri döndürülecek ve biz de bu noktalara göre yönlendirmemizi polyline ile çizerek işlemi tamamlayacağız.

Uygulamayı yazmaya başlamadan önce kullanacağımız kütüphaneleri projemize ekleyelim.

Kullanılacak Kütüphanelerin Eklenmesi

Google Maps ile yönlendirme işlemini gerçekleştirirken Google, Retrofit ve RxJava kütüphanelerini modül seviyesindeki build.gradle dosyasına ekliyoruz.

Retrofit kütüphanesini API’ye istek yaparken kullanmak için projemize eklerken, RxJava kütüphanemizi ise bu işlemleri yaparken isteklerimizin ana threadi bloklamasını ve uygulamanın OutOfMemory hatası ile karşılaşmasını önlemek için projemize ekliyoruz.

Kütüphaneleri ekledikten sonra yapmamız gereken işlem ise Google Maps aktivitesini oluşturmak ve ayarlamalarını yapmak.

Uygulamaya Google Maps API’yi Entegre Etmek

Android Studio ile geliştirme yaparken Google Maps API’yi uygulamanıza dahil etmeniz çok basit. Öncelikle Android Studio’nun sol kısmına yer alan navigasyon kısmında uygulamamızı geliştirirken kullandığımız paketin üstüne sağ tıklayarak New>Google>Google Maps Activity’e tıklıyoruz.

Daha sonra ise açılan pencerede aktivitemize bir isim veriyoruz ve finish butonuna basıyoruz.

Bu işlemi tamamladıktan sonra Google Maps aktivitemiz oluşuyor. Bundan sonra yapacağımız işlemleri bu aktivite üzerinden gerçekleştireceğiz ancak geliştirme yapmaya başlamadan önce düzenlememiz gereken bir dosya var. Bu dosya aktiviteyi oluştururken otomatik olarak res klasörünün altında kulunan values içinde google_maps_api.xml olarak oluşturuldu.

Bizim bu dosyada alt kısımda bulunan string tagına Google Maps API Key’imizi eklememiz gerekli. API Keyimizi ise https://console.developers.google.com ile başlayan linki koplayıp tarayıcımızın url kısmına yapıştırarak alacağız.

Linkimizi açtıktan sonra eğer hali hazırda bir Gmail hesabı açıksa bu ekranı görmeliyiz. Burada ise seçim kutusunu Create a project olarak bırakarak continue butonuna basıyoruz. Bu kısımdan sonra ise herhangi bir hata çıkmaması durumunda bize API’nin Android için oluşturuldu sayfasına yönlendirmeli.

Burada ise yapmamız gereken tek şey Create API key butonuna basmak. Böylece Maps API’mizi oluşturduk. Son olarak yapmamız gereken şey ise API Keys bölümünün altındaki API Key’in key kısmındaki kopyalama butonuna dokunmak.

API Key’imizi de aldığımıza göre artık uygulamamıza dönebiliriz ve aldığımız API Key’i google_maps_api.xml altındaki google_maps_key string etiketinin içine yapıştırmalıyız. Bütün yaptıklarımızı test etmek için ise aktivitemizi çalıştırmalı ve emulatorumuzden Google Maps arayüzünü görmeliyiz. Eğer uygulamayı çalıştırdığımızda haritayı görebilirsek her şeyi doğru yaptık demektir.

Haritayı gördüğümüze göre SDK’yi doğru şekilde projeye eklemişiz. Şimdi ise artık harita aktivite dosyamızda geliştirmeler yapmaya başlayabiliriz. Bir harita aktivitesi eklediğimizde diğer aktivitelerden farklı olarak otomatik olarak onMapReady fonksiyonu override ediliyor. Bu fonksiyon ise harita açıldığında yapılacak işlemleri içeriyor. Öncelikle buradaki googleMap nesnesi haricindeki diğer kodları siliyoruz. Tabi eğer haritamızın belirli bir konumda açılmasını vs. istiyor isek daha sonra bu kısmı tekrar düzenleyebiliriz. Şimdi hazırsak kod yazmaya başlayalım. Öncelikle harita üzerinden nokta seçebilmek için OnMapLongClickListener interfaceini uygulamamıza ekleyelim ve başlangıç ve bitiş noktalarını belirlemek için değişkenler oluşturalım. Ayrıca bir değişken de sadece 2 nokta işaretleyebilmek için oluşturuyoruz.

Interfacemizi projemize uyguladıktan sonra ise bir hata almalıyız. Hatanın çözümü ise onMapLongClick fonksiyonunu override etmek. Fonksiyonu override ettikten sonra ise onMapReady fonksiyonu içerisinde listenerı tanımlamamız gerekli. Böylece artık onMapLongClick fonksiyonı ile haritanın üzerine uzun tıklamalar yaptıkça aksiyon geliştirebileceğiz.

Hata mesajını da hallettiğimize göre artık haritanın üzerine nasıl işaretleme yapıldığına geçebiliriz. Harita üzerine işaretleme yaparken marker kullanacağız. Uzun tıklama yaparak marker eklemek için aşağıdaki kod parçasını kullanabiliriz.

Bu kod parçası ile haritaya her uzun tıklamamızda yeni bir marker ekleyecektir. Ancak biz bunun bu şekilde gerçekleşmesini istemiyoruz. Biz sadece 2 marker ekleyen bir kod parçası kullanacağız ve marker eklerken aynı zamanda da işaretlediğimiz konumları daha sonra Directions API ile kullanmak için 2 ayrı değişkene atayacağız.

Şimdiye kadar yaptığımız işlemlerde haritayı uygulamamıza bağladık ve üzerinde noktalarımızı belirleme işlemlerimizi başarı ile gerçekleştirdik. Bundan sonra ise artık Google Directions API kısmına geçiyoruz. Directions API’yi projemize entegre etmek için öncelikle mevcut API keyimizde Directions özelliğini açmalıyız. Directions API’yi mevcut API Key’imize eklemek için API keyimizi aldığımız ekrandaki arama kısmına Directions yazıyoruz ve sonuçlardan Directions API’yi seçiyoruz. Ardından açılan ekrandaki enable butonuna basarak API’yi mevcut API keyimize ekliyoruz.

Directions Api’yi etkinleştirdikten sonra ise bu APi’yi Retrofit yardımı ile kullanacağımızdan dolayı öncelikle data classlarımızı oluşturmalıyız. Bunun için öncelikle https://maps.googleapis.com/maps/api/directions/json?origin=Disneyland&destination=Universal+Studios+Hollywood&key=YOUR_API_KEY linkinin sonuna kendi Api keyimizi yazarak dönen JSON’ı kopyalıyoruz ardından da Android Studio’ya dönüp bir model package ı oluşturuyoruz. Oluşturduğumuz packagenin içinde kopyalamış olduğumuz JSON yardımı ile data classlarımızı oluşturacağız. Bunun için de JSON To Kotlin Class plugininden yardım alacağız. Bu plugini yüklemek için Android Studio’daki ayarlardan plugins alt başlığında JSON To Kotlin Class yazarak arama yapabilir ve install tuşu ile yükleyebilirsiniz. Plugini yükledikten sonra model packagenün üstüne sağ tıklayıp New’e tıklıyoruz ve Kotlin data class File from JSON seçeneğine tıklıyoruz. Buradaki kod kısmına daha önce kopyalamış oldupumuz JSON’ı yapıştırıp class name alanına base data classımızın adını yazıyoruz ve generate butonuna basıyoruz.

Böylelikle bütün data classlarımız model packageı altında oluşuyor.

Data Class’larımızı oluşturduğumuza göre şimdi istek ayarlarımızı yapacağımız interfacemizi oluşturabiliriz. Bunun için öncelikle aynı model packagemizi oluşturduğumuz gibi bir tane de service packagei oluşturuyoruz. Daha sonra ise package üzerine sağ tıklayıp New > Kotlin Class/File seçeneğini seçip çıkan seçeneklerden interfacei seçip ApiInterface adında bir dosya oluşturuyoruz. Bu dosya içinde API isteklerini içeren fonksiyonumuzu yazacağız.

Fonksiyonumuzu da yazdığımıza göre şimdi Retrofit ayarlarımızı yapacağımız ApiRetrofit Class’ımızı oluşturalım. Bu classı da interface gibi service packageı altında oluşturuyoruz. Service packagenin üstüne sağ tıklayıp New > Kotlin Class/File seçeneğini seçip çıkan seçeneklerden classı seçip ApiRetrofit adında bir class oluşturuyoruz. Bu class içerisindeki fonksiyonla Retrofit ayarlarımızı yapıp bir ApiInterface döndürüyoruz.

Retrofit fonksiyonumuzu da yazdığımıza göre sıra bu yaptığımız işlemleri aktivite içerisinde kullanmaya geldi. Ama öncelikle harita üzerinde rotayı çizmek için kullanacağımız Polyline fonksiyonunu tanımlayalım. Polyline fonksiyonu bizim ona vereceğimiz data classtan harita üzerindeki noktaları alıp o noktalara göre rota çizdirecek.

Geldik son aşamaya. Artık yazdığımız Retrofit fonksiyonunu çağırabiliriz. Ama aktivitenin içerisinde mi? Tabii ki hayır. Çünkü eğer aktivite içerisinde Retrofit’i çağırır isek herhangi bir sorun ile karşılaştığımızda arayüz işlemlerimiz bloklanabilir ve uygulamamız çökebilir. Bunun için öncelikle viewmodel adında bir paket oluşturuyoruz ve onun da içerisinde GoogleViewModel adında bir sınıf açıyoruz. Açtığımız bu sınıfta ilk iş ViewModel sınıfını kalıtım alıyoruz. Daha sonra ise noktalarımızı saklayacağımız points değişkenini, hata durumunda kullanacağımız error değişkenini ve Retrofit’i RxJava ile kullandığımız için bir disposable değişkenini oluşturuyoruz.

Son olarak da aktivite içerisinden çağıracağımız getData fonksiyonunu oluşturuyoruz ve içerisine Retrofit isteğini yapacağımız kodları ekliyoruz. Eklediğimiz kodların içerisinde de eğer işlem başarılı olursa koşulunun içinde points değişkenimizin değerini ve eğer işlem başarısız olursa error değişkenimizin değerini günceliyoruz.

Aktivitemizde View Modelimizi tanımlayıp son işlemleri gerçekleştirelim ve bu Google için yönlendirme işlemini tamamlayalım. Öncelikle global bir viewModel değişkeni oluşturalım ve bunu da onCreate altında tanımlayalım.

Daha sonra da onMapLongClick fonksiyonu altında viewModelimiz değişkenimizden Retrofit yardımı ile bir istek yapalım ve istekten sonra da dönen points değerini drawPolyline fonksiyonuna aktararak işlemimizi tamamlayalım.

Buraya kadar sorunsuz geldiysek biraz soluklanıp hemen Yandex Maps kısmına geçebiliriz.

Yandex Maps API İle Rota Çizimi

Yandex Maps ile rota çizdirmek için de daha evvel Google ile çalışırken olduğu gibi bir API keye ihtiyacımız var. Hadi işe koyulalım ve keyimizi alalım.

API Key’e Erişim

Yandex Maps API ile rota çizdirmek için Google’da olduğu gibi bir API keye ihtiyacımız var. Bu API keye ise Yandex Developer Console’a giriş yaptıktan sonra Connect APIs butonuna basınca açılan sekmeden Mapkit Mobile SDK’i seçip gerekli alanları doldurup erişiyoruz.

Keyimizi aldıkta sonra yapmamız gereken ilk işlem ise Yandex Maps kütüphanesini projeye eklemek.

Gerekli Kütüphanelerin Eklenmesi

Yandex Maps API ile çalışırken gereken maps kütüphanesini build.gradle dosyasına ekleyerek işe başlıyoruz.

Kütüphaneyi projemize eklediğimize göre artık bu kütüphanenin nimetlerinden yararlanabiliriz demektir. İlk olarak layout dosyasını düzenleyelim.

Map Fragmentinin Oluşturulması

Yandex Maps ile çalışırken Google Maps API’nin aksine layout dosyasına kendimiz müdahale etmeliyiz. Layoutun içine map görünümünü ekleyip layout kısmındaki işlemimizi de böylelikle bitirmiş oluyoruz.

Layotumuzu düzenlediysek asıl işleme yani API’yi projemize bağlama işlemine geçebiliriz.

API’yi Uygulamaya Bağlamak

API’yi uygulamaya bağlamak için öncelikle uygulamanın en başında gizli bir değişken olarak API keyimizi tutacağımız stringi tanımlıyoruz. Daha sonra ise onCreate fonksiyonun altında Apimizi bağlama kodlarını MapKitFactory objesinin yardımı ile yazıyoruz. Daha sonra ise yine onCreate fonksiyonu altında rota çizerken kullanacağımız DirectionsFactory’i de aktivitemize tanımlıyoruz.

API’mizin tanımlama işlemlerini yani projeye bağlama işlemini gerçekleştirdik. Şimdi ise bağlantısını gerçekleştirdiğimiz API’mizi layoutta bulunan harita görünümümüze bağlayalım.

API İle Layouttaki Map Görünümünü Bağlamak

API mizi tanımladığımıza göre artık API ile de map görünümünü birbirine bağlayabiliriz. Bunun için başlangıçta MapView sınıfından bir mapView objesi oluşturuyoruz ve bu objeye de onCreate altında layoutta yer alan görünümümüzü bağlıyoruz.

Görünüm bağlama işlemlerinden sonra artık işaretleme işlemleri ile birlikte API mizi kullanmaya başlayabiliriz.

Uzun Tıklama ve İşaretleme Yapma İşlemleri

Aynı Google Map Api’de yaptığımız gibi burada da uzun tıklama sonucu 2 noktayı işaretleme işlemlerini gerçekleştireceğiz. Öncelikle InputListener arayüzünü implemente ediyoruz ve override etmek zorunda olduğumuz onMapTap ve OnMapLongTap fonksiyonlarımızı tanımlıyoruz. Daha sonra onCreate altında listenerımızı görünümümüze bağlıyoruz.

Biz bu uygulamada onMapTap fonksiyonunu kullanmayacağımız için fonksiyonun içini boş bırakıyoruz. Daha sonra ise işaretleme yapmak için MapObjectCollection sınıfından mapObjects adında bir obje oluşturuyoruz.

Bu objeyi de onCreate altında tanımladıktan sonra işaretleme yapmaya hazırız. Burada yine Google Maps Api’de olduğu gibi 2 nokta işaretlemek için koşullu ifadelerden yararlanıyoruz.

Harita üzerinde işaretleme yapmayı da başardığımıza göre işaretlediğimiz noktalara göre rota çizdirme işlemine başlayabiliriz. Bunun için öncelikler DrivingSession.DrivingRouteListener interfaceini aktivitemize uyguluyoruz. Daha sonra da rota oluştururken kullanacağımız değişkenleri tanımlıyoruz ve onCreate fonksiyonu altındaki tanımlama işlemlerini tamamlıyoruz.

DrivingSession.DrivingRouteListener interfacesini uyguladığımızda onDrivingRoutes ve onDrivingRoutesError fonksiyonlarını override etmemiz gerekecek. onDrivingRoutes içinde haritaya polyline ekleme işlemini gerçekleştireceğiz. onDrivingRoutesError fonksiyonunda ise bir hata durumunda ekrana hata mesajı yazdıracak Toast’ımızı tanımlıyoruz.

Son olarak onMapLongTap altındaki koşullu ifadede başlangıç ve bitiş noktalarını ayrıca drivingOptions ve vehiceOptions değerlerini drivingSession değişkenine eşitliyoruz ve harita çizdirme işlemlerini tamamlıyoruz.

Son olarak aktivitenin başlama ve bitiş fonksiyonlarını yazmalıyız. Bu fonksiyonlar içinde de MapKitFactory ile Api’ye start ve stop özelliklerini tanımlıyarak Yandex Maps Api ile rota çizdirme işlemini de tamamlamış oluyoruz.

Umarım her şey yolunda gitmiştir ve Yandex ile olan yolculuğumuzu da hasarsız atlatmışızdır. Hadi gelin son olarak Huawei Maps’e bakalım.

Huawei Map Kit SDK İle Rota Çizimi

Huawei Map Kit ile rota çizdirme işlemi için ilk olarak AppGallery üzerinden bir proje oluşturmamız ve uygulamamıza göre ayarlarını yapmamız gerekiyor. Daha sonra ise Map Kit’i uygulamamıza ekleyip harita işlemlerine geçeceğiz.

Huawei AppGallery Entegrasyonu ve API Keyin Alınması

Huawei uygulama geliştirme kitleri ile çalışmak için öncelikle Huawei Developers’a kayıt olmamız gerekiyor. Kayıt işlemini tamamladıktan sonra ise hesabımızın onaylanması yaklaşık 1–2 günümüzü alıyor. Hesabımız onaylandıktan sonra ise AppGallery Connect sayfasını açarak My projects sayfasına gidiyoruz. Burada uygulamamız için bir proje ekleyeceğiz.

Sayfayı açtıktan sonra Add project butonuna basarak işleme başlıyoruz. İlk aşamada projemize bir isim veriyoruz.

Projemize isim verdikten sonra proje ayarlarımızın bulunduğu ana ekrana yönlendiriliyoruz. Burada projemize bir uygulama tanımlamalıyız. Bunun için Add app butonuna basıyoruz.

Butona bastıktan sonra bizden uygulamamızın özelliklerini belirtmemiz isteniyor. Burada Platform bilgisi için Android’i, Device için Mobile phone’u, App name için uygulamanızın adını, Package name için uygulamanızın paket adını, App category için App’i ve Default language için English(US)’i seçtikten sonra OK butonuna basıp yolumuza devam ediyoruz.

Bu sayfadan sonra karşımıza nasıl kullanılır ekranları çıkıyor. Bu ekranları atlayıp tekrar projemizin ana ekranına dönüyoruz. Ana ekrana döndükten sonra ise ilk iş Map Kit’i etkinleştirmek için Manage APIs sekmesinden arama kısmına Map Kit yazarak Map Kit’i bulup etkinleştiriyoruz.

Son olarak ise Map Kit’i kullanabilmek için uygulamamıza SHA-256 anahtarını eklememiz gerekiyor. Bunun için Android Studio’ya dönüyoruz. Android Studio’da sağ kısımdaki araç çubuğunda bulunan Gradle’a tıklıyoruz. Açılan araç çubuğundan Tasks paketine tıklayıp daha sonra onun altında bulunan Android paketini açıyoruz. Paketi açtıktan sonra signingReport görevine çift tıklayıp çalıştırıyoruz. Bu görevi çalıştırdığımızda Android Studio’nun içinde bulunan run terminali çalışacak ve içinde de uygulamamızın SHA-256 değeri ve birkaç farklı değer yer alacak.

SHA-256 değerimizi kopyalıyoruz ve AppGallery Connect’teki ana sayfada yer alan SHA_256 certificate fingerprint alanına yapıştırıyoruz ve agconnect-services.json adlı dosyayı indiriyoruz.

Dosyamızı indirdikten sonra dosyayı projemizin içinde bulunan app dosyasının içine taşıyoruz.

Bu aşamadan sonra artık kütüphanelerimizi uygulamamıza entegre edebiliriz. Bunun için diğer yaptığımız uygulamalardan farklı olarak ilk önce proje seviyesindeki build.gradle dosyasından başlayacağız. Burada Huawei repolarını entegre edeceğiz. Eğer entegrasyon süreci sonunda “Could not find com.huawei.hms:maps:6.0.0.301” gibi bir hata ile karşılaşırsanız Gradle versiyonunuzun sürümünü 3.5.4 ile değiştirerek tekrar deneyebilirsiniz.

Bu aşamayı da tamamladıysak modül seviyesindeki build.gradle dosyasına gerekli eklemeleri yapalım. Bu dosyada ise öncelikle ‘com.huawei.agconnect’ eklentisini ekliyoruz ve ardından maps kütüphanesini dependencies altında tanımlıyoruz.

Eveeet bütün dosyalarımız tamam olduğuna göre Gradle dosyamızın senkronizasyon işlemini yapıp kapatabiliriz. Şimdi ise işlemlerimizi gerçekleştireceğimiz aktivitemizi oluşturalım ve kütüphanelerin doğru uygulandığını teyit etmek için layout dosyasında bir MapView görünümü oluşturalım.

Eğer <com.huawei.hms.maps.MapView etiketimizi sorunsuz bir biçiminde oluşturabiliyorsak işe başlamak için her şey tamam demektir.

Map Kit’in Aktiviteye Tanımlanması ve Harita Üzerinde İşaretleme Yapmak

Daha evvel defalarca gördüğümüz gibi bu aktiviteler tek başlarına çok şeyi başaramıyorlar. Hadi onlara biraz destek atalım ve ihtiyacımız olan fonksiyonları içeren OnMapReadyCallback arayüzünü uygulayalım ve hemen gerekli onMapReady fonksiyonunu override edelim.

Map Kit ile işlem yapmak için bazı değişkenlere ihtiyacımız var. Bunları haritayı aktiviteye bağlarken, konumları kaydederken ve lanet olası network işlemlerini viewden uzak tutmak için kullanacağız.

Şimdi de yaklaşık 500 kelimedir kurmak için uğraştığımız bu haritayı onCreate fonksiyonu altında aktiviteye bağlayalım. İlk olarak daha evvel MapView olarak oluşturduğumuz mMapView değişkeninden başlayalım. Bu değişken her ne kadar masum gibi görünse de aslında bizim harita görünümümüzü findviewbyid yardımı ile bularak her şeyin başlangıç noktası oluyor. Daha sonra ise mMapViewden onCreate methodu ile haritayı başlatıyor ve getMapAsync methodu ile yaptığımız isteği kaydediyoruz.

Evet tanımlama işlerinden de kurtulduğumuza göre zevkli kısıma yani onMapReady fonksiyonuna geçebiliriz. Daha önceden de dediğim gibi bu fonksiyonu OnMapReadyCallback arayüzünü aktivitemize uyguladığımızda zorlamalara dayanamayarak override etmiştik. onMapReady fonksiyonunu aslında Google Maps ile uğraşırken de görmüştük. Eğer geriye dönüp biraz göz atarsak bu fonksiyonun harita açıldığında yapılması planlanan işlemler için yazıldığını görürüz. Biz ise daha önceden demeyi sevmiyorum ama Google’da yaptığımız gibi bu fonksiyonu uzun tıklamalar sonucunda bir işaretleyici dinleyicisi atamak için kullanacağız. Tabi bir farkla. Google’da dinleyiciyi onMapReady altında tanımlayıp hazır gelen fonksiyonu kullanıyorduk. Bu sefer fonksiyonu kendimiz tanımlayıp onMapReady fonksiyonun altında setOnMapLongClickListener içinde çağıracağız. Sizi duyar gibiyim neden direkt burada yapmadık diyorsunuz. Öyle de yapabiliriz ama üstün olmayan kodlama becerilerime göre her şey çok karışık görünebilir.

onMapReady fonksiyonunu da anladıysak dinleyici fonksiyonumuza geçelim. Burada yazdığım kodları koşullu ifadelerin içine aldım. Bunun sebebi ise yazdığım koşul bizim sadece 2 noktayı işaretlememizi sağlıyor. Böylece rota çizdirme işlemindeki başlangıç ve bitiş noktalarını belirleyebiliyoruz. Belirleme yaparken de öncelikle belirlediğimiz noktalara işaretleyici ekliyoruz ki nereyi işaretlediğimizi bilelim. Bunun için addMarker methodunu kullanıyoruz. İşaretleyicilerimizi de eklediysek işaretlediğimiz yerlerdeki konumları kaydetmeyi de unutmayalım. Tam da bu fonksiyon içerisinde origin ve destination değişkenlerinin tanımlamalarını gerçekleştiriyoruz. Ve daha sonradan API operasyonunda kullanacağımız directionPoints değişkeninin değer atamasını da aradan çıkarıyoruz.

Eveeet ilk olarak haritamızı tanımladık daha sonra da değişkenlerimizi tanımladık. İşte şimdi zurnanın tam olarak zırt dediği yerdeyiz. Retrofit ve RxJava kendilerini özletmek istemedikleri için geri geldiler ve bizden bir API isteği yapmamızı istiyorlar. Bu istek aslında karşılıklı kazanç sağlayacak. Biz bir Post isteğinde bulunacağız onlar da bize ihtiyacımız olan rotaya ait koordinatları verecekler. Ama işe başlamadan önce AppGallery Connect’teki projemizden API keyimizi kopyalıyoruz istek yaparken bu işimize yarayacak.

API keyimizi cebimizde tutalım ve öncelikle data classlarımızı oluşturalım. Bu data classlar çektiğimiz verilerin depolanmasında önem taşıyacak. Data classlarımızı oluşturmak için örnek bir geri dömüş değerine ihtiyacımız var. Bu değere ise hemen şuracıktaki linkten ulaşıyoruz.

Buradaki bütün Json’u kopyalamalıyız ama üstteki HTTP dönüş kodlar hariç tabi onlara ihtiyacımız yok. Ve ardından model paketinin altında huawei adında bir paket daha açmalıyız ve pakete sağ tıkladıktan sonra New>Kotlin data class File from JSON seçeneğini seçmeliyiz. Bu seçenekle data classlarımızı kopyaladığımız Json değeri sayesinde oluşturabileceğiz. Json kısmına kopyaladığımız Json’u yapıştırıyoruz ve sınıf adına ise DirectionResponse yazıyoruz. Bu isim istek yaparken bize lazım olacak.

Vee bütün data classlarımız emrinize amede.

Şimdi ise API’yi çağırmak için gerekli olan arayüzü yazıyoruz. Servis paketinin altında yeni bir huawei paketi açarak işe başlıyoruz. Bu paketin altında ise öncelikle HuaweiApiInterface adında bir arayüz oluşturuyoruz. Oluşturduğumuz arayüzün içinde https://mapapi.cloud.huawei.com/mapApi/v1/routeService/driving adresine yapacağımız isteğin ayarlamalarını ve istek yaparken beraberinde göndereceğimiz değerlerle geri dönüşte alacağımız değeri belirtiyoruz.

Arayüzü tanımladıysak şimdi sırada ne var? Tabii ki de Retrofit servisini yazmak. Bu servisi ve beraberinde kullanacağımız RxJava’yı servis paketi altında HuaweiApiRetrofit sınıfı içinde tanımlayacağız.

Retrofiti de tanımladığımıza göre sıra bu Retrofit sınıfını bir yerden çağırmaya geldi. Bu işlemi yaparken çok dikkat etmeliyiz çünkü kazara view paketi içerisinde bu işlemi yaparak 7 büyük yazılımcılık günahından birini işleyebiliriz. Şaka bir yana bunu yapmamız bizim arayüz işlemlerimizi sekteye uğratıp uygulamayı çökertmemize sebep olabilir. Bundan dolayı ViewModel kullanacağız. ViewModel içerisinde API çağırma işlemlerimizi gerçekleştirip gelen değerleri de tekrardan aktiviteye göndererek güvenli bir şekilde bu işin içinden çıkmaya çalışacağız. Öncelikle viewmodel adında bir paket oluşturarak işe girişiyoruz. Daha sonra da HuaweiViewModel adında bir sınıf oluşturuyoruz. Bu sınıfın bir viewmodel olabilmesi için gerekli koşul ise ViewModel sınıfının kalıtım alınması olduğundan hemen bu işlemi gerçekleştiriyoruz.

Daha sonra ise değişkenlerimizi tanımlıyoruz. Buradaki değişkenleri aktivitede yaptığımızdan biraz farklı olarak değişebilir canlı veri olarak tanımlıyoruz. Bu da bize viewmodel da yaptığımız anlık değişikliklerin sonucunu aynı anda aktivite içerisinde görmemizde yardımcı olacak. Tabi bir tane de normal bir değer tanımlıyoruz. Disposable dediğimiz bu değer ile Retrofit operasyonumuzu çağıracağız.

Son olarak ise getPoint adında bir fonksiyon oluşturuyoruz ve bu fonksiyonun içerisinde Retrofit sınıfımızı çağırıyoruz. Bu çağırma işlemi normal Retrofit çağırma işleminden biraz daha farklı çünkü bu sefer işin içinde RxJava da var. Peki neden mi aramıza kara kedi girdi? Çünkü RxJava sayesinde uzun süreli gerçekleşen Retrofit operasyonlarından kaynaklanan aşırı bellek kullanımını engelliyoruz ve kodumuz daha güvenli bir hal alıyor. Son olarak da çağırma işleminin başarlı olması durumunda points değişkenini güncelliyoruz ve eğer bir problem olursa diye de error değişkeninin değerini atıyoruz. Ve viewmodelden yavaşça uzaklaşarak aktivitemize geri dönüyoruz.

Her şeyden önce aktivitemize artık bir View Modele sahip olduğumuzu söylememiz lazım. Bunun için zaten daha evvelden viewModel değişkenini oluşturmuştuk. Şimdi de bu viewModeli onCreate altında tanımlayalım.

Pekii View Model içerisinde bulunan fonksiyona nasıl istek yapacağız? Cevap çok basit. viewModel değişkeni yardımı ile normal bir fonksiyon çağırır gibi fonksiyonumuzu çağırıyoruz ve daha sonra da gözlemleme fonksiyonu yardımı ile viewmodeldaki points değişkenine ulaşıyoruz. Değişkenin değerlerini de birazdan yazacağımız addPolyLines fonksiyonuna gönderiyoruz.

Gerçekten son noktaya gelmiş bulunmaktayız xD. Şimdiye kadar haritayı oluşturduk, noktaları aldık, API isteğimizi yaptık hem de View Modelde çağırdık. Gereken verilerimizi de aldığımıza göre polyline fonksiyonunu oluşturalım ve API içerisinden gelen değerleri birer birer polylinea ekleyelim ve rotamızı çizdirelim.

Tabii ki haritamızı çalıştırma ve durdurma komutlarını da eklemeyi unutmayalım.

Uygulamayı yazmayı bitirdik şimdi çalıştırmaya çalışacağız peki Android Studio’nun kendi emulatorleri ile çalışacak mı? Tabii ki hayır. Çünkü uygulamayı çalıştırmak için bir Huawei telefona ihtiyacımız var. Peki telefonu nasıl bulacağız? Huawei’nin Cloud Debugging özelliğinden yararlanacağız. Bunun için ayarlardan eklentilere gidiyoruz ve HMS Toolkit adlı eklentiyi Android Studio’ya ekliyoruz ve Android Studio’yu yeniden başlatıyoruz. Böylece artık bir Huawei telefona sahibiz. Huawei cihaz üzerinden uygulamayı çalıştırmak için ise üst kısımda bulunan araçlardan HMS yazan açılır pencereyi açıp Cloud Debugging özelliğini seçiyoruz ve telefonumuzun özelliklerini belirleyip çalıştırıyoruz.

Mutlu son :D

Bütün platformlarla olan işlemleri bitirdiğimize göre şimdi isterseniz bu 3 platformun artılarını eksilerini konuşalım.

Artılar Eksiler

Öncelikle Google’dan başlayalım. Google’ın entegrasyonunda herhangi bir sorunla karşılaşmadım ancak okuduğum kadarıyla Yandex Maps Avrupa ve Rusya’da daha iyi çalışıyormuş ve Google’a kıyasla daha ucuz. Fakat Yandex tarafında da dökümantasyon eksiği var çoğu döküman Rusça’dan İngilizce’ye çevrilmemiş. Huawei ise Google servislerinden yararlanamadığı için kendi servisini geliştirmiş. Geliştirme sürecinde bir takım problemlerle karşılaşmış olsam bile Huawei Map Kit’i entegre etmek Google Maps kadar kolaydı. Hatta yazılış biçimi neredeyse birebir aynıydı. Ama Huawei ile geliştirme yaparken de maalesef Android Studio emulatorlerini kullanamıyorsunuz ve bu da açıkçası geliştirme sürecini az da olsa yavaşlatıyor.

Sizlere bu 3 platformun entegrasyonunu elimden geldiğince aktarmaya çalıştım. Umarım başarılı olmuşumdur ve okurken keyif almışsınızdır. Projenin Github linkini ve örnek videosunu da hemen şuracığa bırakıyorum.

Umarım Roma maçı öncesi Trabzonspora uğur getirir :)

Kaynakça

Google:https://developers.google.com/maps/documentation/directions/quickstart

Yandex:https://github.com/yandex/mapkit-android-demo

Huawei:https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-brief-introduction-0000001061991343

--

--