1. Başlamadan Önce
Bu codelab'de, Android için Yerler SDK'sını uygulamanıza nasıl entegre edeceğiniz ve Yerler SDK'sının her bir özelliğini nasıl kullanacağınız açıklanmaktadır.
Ön koşullar
- Kotlin ve Android geliştirme hakkında temel düzeyde bilgi sahibi olmak
Neler öğreneceksiniz?
- Kotlin uzantılarıyla Android için Yerler SDK'sını yükleme
- Belirli bir yer için yer ayrıntılarını yükleme
- Uygulamanıza Yer Otomatik Tamamlama widget'ı ekleme
- Cihazın mevcut konumuna göre Current Place nasıl yüklenir?
İhtiyacınız olanlar
Bu codelab'i tamamlamak için aşağıdaki hesaplara, hizmetlere ve araçlara ihtiyacınız vardır:
- Faturalandırmanın etkinleştirildiği bir Google Hesabı.
- Android Studio Bumblebee veya sonraki sürümler.
- Android Studio'da Google Play Hizmetleri'nin yüklü olması gerekir.
- Android 8 veya sonraki sürümlere dayalı Google API'leri platformunu çalıştıran bir Android cihaz ya da Android emülatörü (yükleme adımları için Android emülatöründe uygulamaları çalıştırma başlıklı makaleyi inceleyin).
2. Hazırlanın
Aşağıdaki etkinleştirme adımında Places API ve Android için Haritalar SDK'sı'nı etkinleştirin.
Google Haritalar Platformu'nu ayarlama
Henüz bir Google Cloud Platform hesabınız ve faturalandırmanın etkinleştirildiği bir projeniz yoksa lütfen faturalandırma hesabı ve proje oluşturmak için Google Haritalar Platformu'nu Kullanmaya Başlama kılavuzuna bakın.
- Cloud Console'da proje açılır menüsünü tıklayın ve bu codelab için kullanmak istediğiniz projeyi seçin.
- Bu codelab için gereken Google Haritalar Platformu API'lerini ve SDK'larını Google Cloud Marketplace'te etkinleştirin. Bunun için bu videodaki veya bu dokümandaki adımları uygulayın.
- Cloud Console'un Kimlik Bilgileri sayfasında bir API anahtarı oluşturun. Bu videodaki veya bu dokümandaki adımları uygulayabilirsiniz. Google Haritalar Platformu'na yapılan tüm istekler için API anahtarı gerekir.
3. Hızlı başlangıç
Bu codelab'i takip etmenize yardımcı olması için başlangıç kodunu indirerek mümkün olduğunca hızlı bir şekilde başlayabilirsiniz. Çözüme geçebilirsiniz ancak kendiniz oluşturmak için tüm adımları takip etmek istiyorsanız okumaya devam edin.
git
yüklüyse depoyu klonlayın.
git clone https://github.com/googlemaps/codelab-places-101-android-kotlin.git
Alternatif olarak, kaynak kodunu indirmek için bu düğmeyi tıklayın.
- Kodu indirdikten sonra Android Studio'da
/starter
dizinindeki projeyi açın. Bu proje, codelab'i tamamlamak için ihtiyacınız olan temel dosya yapısını içerir. Çalışmak için ihtiyaç duyduğunuz her şey/starter
dizininde bulunur.
Çalışan çözüm kodunun tamamını görmek isterseniz tamamlanmış kodu /solution
dizininde görüntüleyebilirsiniz.
4. API anahtarınızı projeye ekleme
Bu bölümde, API anahtarınızı uygulamanız tarafından güvenli bir şekilde referans verilebilecek şekilde nasıl saklayacağınız açıklanmaktadır. API anahtarınızı sürüm kontrol sisteminize işlememeniz gerekir. Bu nedenle, projenizin kök dizininin yerel kopyasına yerleştirilecek olan secrets.properties
dosyasında saklamanızı öneririz. secrets.properties
dosyası hakkında daha fazla bilgi için Gradle özellik dosyaları konusuna bakın.
Bu görevi kolaylaştırmak için Android İçin Secrets Gradle Plugin'i kullanmanızı öneririz.
Google Haritalar projenize Android İçin Secrets Gradle Plugin'i yüklemek üzere:
- Android Studio'da üst düzey
build.gradle.kts
veyabuild.gradle
dosyanızı açın vebuildscript
altındakidependencies
öğesine aşağıdaki kodu ekleyin.
build.gradle.kts
kullanıyorsanız şunları ekleyin:
buildscript {
dependencies {
classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1")
}
}
build.gradle
kullanıyorsanız şunları ekleyin:
buildscript {
dependencies {
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
}
}
- Modül düzeyindeki
build.gradle.kts
veyabuild.gradle
dosyanızı açın ve aşağıdaki koduplugins
öğesine ekleyin.
build.gradle.kts
kullanıyorsanız şunları ekleyin:
plugins {
// ...
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
}
build.gradle
kullanıyorsanız şunları ekleyin:
plugins {
// ...
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
- Modül düzeyindeki
build.gradle.kts
veyabuild.gradle
dosyanızdatargetSdk
vecompileSdk
değerlerinin 34 olarak ayarlandığından emin olun. - Dosyayı kaydedin ve projenizi Gradle ile senkronize edin.
secrets.properties
dosyasını en üst düzey dizininizde açın ve aşağıdaki kodu ekleyin.YOUR_API_KEY
kısmını API anahtarınızla değiştirin.secrets.properties
, sürüm kontrol sistemine kaydedilmekten hariç tutulduğu için anahtarınızı bu dosyada saklayın.
PLACES_API_KEY=YOUR_API_KEY
- Dosyayı kaydedin.
local.defaults.properties
dosyasını üst düzey dizininizde (secrets.properties
dosyasıyla aynı klasörde) oluşturun ve aşağıdaki kodu ekleyin.
PLACES_API_KEY=DEFAULT_API_KEY
Bu dosyanın amacı, secrets.properties
dosyası bulunamazsa API anahtarı için yedek bir konum sağlamaktır. Böylece derlemeler başarısız olmaz. Bu durum, uygulamayı secrets.properties
öğesini atlayan bir sürüm kontrol sisteminden klonlarsanız ve API anahtarınızı sağlamak için henüz yerel olarak bir secrets.properties
dosyası oluşturmadıysanız meydana gelebilir.
- Dosyayı kaydedin.
- Android Studio'da modül düzeyindeki
build.gradle.kts
veyabuild.gradle
dosyanızı açın vesecrets
özelliğini düzenleyin.secrets
özelliği yoksa ekleyin.
Eklentinin özelliklerini düzenleyerek propertiesFileName
değerini secrets.properties
, defaultPropertiesFileName
değerini local.defaults.properties
ve diğer özellikleri ayarlayın.
secrets {
// Optionally specify a different file name containing your secrets.
// The plugin defaults to "local.properties"
propertiesFileName = "secrets.properties"
// A properties file containing default secret values. This file can be
// checked in version control.
defaultPropertiesFileName = "local.defaults.properties"
}
5. Android için Yerler SDK'sını yükleme
Bu bölümde, Android için Yerler SDK'sını uygulamanızın bağımlılıklarına eklersiniz.
- API anahtarınıza artık uygulama içinden erişilebildiğine göre, Android için Yerler SDK'sı bağımlılığını uygulamanızın
build.gradle
dosyasına ekleyin.
Uygulama düzeyindeki build.gradle
dosyanızı değiştirerek Android için Yerler SDK'sı bağımlılığını ekleyin:
app-level build.gradle
dependencies {
// Dependency to include Places SDK for Android
implementation 'com.google.android.libraries.places:places:3.4.0'
}
- Uygulamayı çalıştırın.
Artık boş ekranlı bir uygulama görmelisiniz. Bu ekranı üç demo ile doldurmaya devam edin.
6. Places Android KTX'i yükleme
Bir veya daha fazla Google Haritalar Platformu Android SDK'sı kullanan Kotlin uygulamalarında, Kotlin uzantısı (KTX) kitaplıkları; eş yordamlar, uzantı özellikleri/işlevleri gibi Kotlin dil özelliklerinden yararlanmanızı sağlar. Her Google Haritalar SDK'sının, aşağıda gösterildiği gibi karşılık gelen bir KTX kitaplığı vardır:
Bu görevde, uygulamanızda Kotlin'e özgü dil özelliklerini kullanmak için Places Android KTX kitaplığını kullanın.
Places Android KTX bağımlılığını ekleyin
Kotlin'e özgü özelliklerden yararlanmak için bu SDK'ya karşılık gelen KTX kitaplığını uygulama düzeyindeki build.gradle
dosyanıza ekleyin.
build.gradle
dependencies {
// ...
// Places SDK for Android KTX Library
implementation 'com.google.maps.android:places-ktx:3.1.1'
}
7. Places istemcisini başlatma
Uygulama kapsamı için Yerler SDK'sını başlatma
DemoApplication.kt
dosyasında, app/src/main/java/com/google/codelabs/maps/placesdemo
klasöründe Android için Yerler SDK'sını başlatın. Aşağıdaki satırları onCreate
işlevinin sonuna yapıştırın:
// Initialize the SDK with the Google Maps Platform API key
Places.initialize(this, BuildConfig.PLACES_API_KEY)
Uygulamanızı oluşturduğunuzda Android İçin Secrets Gradle Plugin, secrets.properties
dosyanızdaki API anahtarını BuildConfig.PLACES_API_KEY
olarak kullanılabilir hale getirir.
Uygulama dosyasını manifeste ekleyin
Application
uzantısını DemoApplication
ile genişlettiğiniz için manifesti güncellemeniz gerekiyor. app/src/main
konumundaki AndroidManifest.xml
dosyasında application
öğesine android:name
özelliğini ekleyin:
<application
android:name=".DemoApplication"
...
</application>
Bu kod, uygulama manifestini src/main/java/com/google/codelabs/maps/placesdemo/
klasöründeki DemoApplication
sınıfına yönlendirir.
8. Yer Ayrıntılarını Getirme
Ayrıntılar ekranı oluşturma
app/src/main/res/layout/
klasöründe boş bir LinearLayout
içeren activity_details.xml
düzeni bulunur. <LinearLayout>
parantezleri arasına aşağıdaki kodu ekleyerek doğrusal düzeni doldurun.
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/details_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/details_input_hint"
android:text="@string/details_input_default" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/details_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/button_details" />
<TextView
android:id="@+id/details_response_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:textIsSelectable="true" />
Bu kod, kullanıcının herhangi bir yer kimliği girebileceği veya sağlanan varsayılanı kullanabileceği bir metin girişi alanı, yer ayrıntıları isteğini başlatacak bir düğme ve yanıttaki bilgileri görüntüleyecek bir TextView ekler. İlişkili dizeler, src/main/res/values/strings.xml
dosyasında sizin için tanımlanır.
Ayrıntılar etkinliği oluşturma
DetailsActivity.kt
klasöründe birsrc/main/java/com/google/codelabs/maps/placesdemo/
dosyası oluşturun ve bu dosyayı yeni oluşturduğunuz düzenle ilişkilendirin. Bu kodu dosyaya yapıştırın:
@ExperimentalCoroutinesApi
class DetailsActivity : AppCompatActivity() {
private lateinit var placesClient: PlacesClient
private lateinit var detailsButton: Button
private lateinit var detailsInput: TextInputEditText
private lateinit var responseView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_details)
// Set up view objects
detailsInput = findViewById(R.id.details_input)
detailsButton = findViewById(R.id.details_button)
responseView = findViewById(R.id.details_response_content)
val apiKey = BuildConfig.PLACES_API_KEY
// Log an error if apiKey is not set.
if (apiKey.isEmpty() || apiKey == "DEFAULT_API_KEY") {
Log.e(TAG, "No api key")
finish()
return
}
}
}
- Bu etkinlikle kullanılmak üzere bir Places Client oluşturun. Bu kodu,
onCreate
işlevinde API anahtarını kontrol eden kodun sonrasına yapıştırın.
// Retrieve a PlacesClient (previously initialized - see DemoApplication)
placesClient = Places.createClient(this)
- Places Client kurulduktan sonra düğmeye bir tıklama işleyicisi ekleyin. Bu kodu,
onCreate
işlevinde Places Client oluşturulduktan sonra yapıştırın.
// Upon button click, fetch and display the Place Details
detailsButton.setOnClickListener { button ->
button.isEnabled = false
val placeId = detailsInput.text.toString()
val placeFields = listOf(
Place.Field.NAME,
Place.Field.ID,
Place.Field.LAT_LNG,
Place.Field.ADDRESS
)
lifecycleScope.launch {
try {
val response = placesClient.awaitFetchPlace(placeId, placeFields)
responseView.text = response.prettyPrint()
} catch (e: Exception) {
e.printStackTrace()
responseView.text = e.message
}
button.isEnabled = true
}
}
Bu kod, giriş alanına girilen yer kimliğini alır, yer için hangi alanların isteneceği tanımlar, bir FetchPlaceRequest
oluşturur, görevi başlatır ve başarı veya başarısızlık durumunu dinler. İstek başarılı olursa işlev, TextView'u istenen ayrıntılarla doldurur.
Manifeste Ayrıntılar etkinliğini ekleme
app/src/main
konumundaki AndroidManifest.xml
dosyasında <application>
öğesinin alt öğesi olarak DetailsActivity
için bir <activity>
öğesi ekleyin:
<activity android:name=".DetailsActivity" android:label="@string/details_demo_title" />
Ayrıntılar etkinliğini demo menüsüne ekleme
Ana ekranda mevcut demoları listelemek için boş bir Demo
modülü sağlanır. Yer Ayrıntıları etkinliği oluşturduktan sonra, aşağıdaki kodu kullanarak Demo.kt
klasöründeki src/main/java/com/google/codelabs/maps/placesdemo/
dosyasına ekleyin:
DETAILS_FRAGMENT_DEMO(
R.string.details_demo_title,
R.string.details_demo_description,
DetailsActivity::class.java
),
İlişkili dizeler, src/main/res/values/strings.xml
dosyasında tanımlanır.
MainActivity.kt
öğesini inceleyin ve Demo
modülünün içeriğinde yineleme yapılarak doldurulan bir ListView oluşturduğunu gözlemleyin. Kullanıcı listedeki bir öğeye dokunduğunda tıklama işleyici, ilişkili etkinliği açar.
Uygulamayı çalıştırma
- Uygulamayı çalıştırın. Bu kez listede yer ayrıntıları demosunu sunan bir öğe görmelisiniz.
- Yer Ayrıntıları metnine dokunun. Giriş alanı ve düğmeyle birlikte oluşturduğunuz görünümü görürsünüz.
- "AYRINTILARI GÖSTER" düğmesine dokunun. Varsayılan yer kimliğini kullandıysanız Şekil 1'de gösterildiği gibi yer adı, adres ve harita koordinatları gösterilir.
1.şekil Yanıtın gösterildiği yer ayrıntıları etkinliği.
9. Yer Adı Otomatik Tamamlama ekleme
Otomatik tamamlama ekranı oluşturma
app/src/main/res/layout/
klasöründe boş bir LinearLayout
içeren activity_autocomplete.xml
düzeni sağlanır. Bu kodu <LinearLayout>
parantezleri arasına ekleyerek doğrusal düzeni doldurun.
<androidx.fragment.app.FragmentContainerView
android:id="@+id/autocomplete_fragment"
android:background="@android:color/white"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/autocomplete_response_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:textIsSelectable="true" />
Bu kod, AutocompleteSupportFragment
widget'ı ve yanıttaki bilgileri göstermek için bir TextView ekler. İlişkili dizeler, src/main/res/values/strings.xml
dosyasında tanımlanır.
Otomatik Tamamlama etkinliği oluşturma
src/main/java/com/google/codelabs/maps/placesdemo/
klasöründe birAutocompleteActivity.kt
dosyası oluşturun ve bu kodu kullanarak tanımlayın:
@ExperimentalCoroutinesApi
class AutocompleteActivity : AppCompatActivity() {
private lateinit var responseView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_autocomplete)
// Set up view objects
responseView = findViewById(R.id.autocomplete_response_content)
val autocompleteFragment =
supportFragmentManager.findFragmentById(R.id.autocomplete_fragment)
as AutocompleteSupportFragment
}
}
Bu kod, etkinliği düzen dosyasında tanımladığınız görünümler ve AutocompleteSupportFramgent
ile ilişkilendirir.
- Ardından, kullanıcı Yer Otomatik Tamamlama tarafından sunulan tahminlerden birini seçtiğinde ne olacağını tanımlayın. Bu kodu
onCreate
işlevinin sonuna ekleyin:
val placeFields: List<Place.Field> =
listOf(Place.Field.NAME, Place.Field.ID, Place.Field.ADDRESS, Place.Field.LAT_LNG)
autocompleteFragment.setPlaceFields(placeFields)
// Listen to place selection events
lifecycleScope.launchWhenCreated {
autocompleteFragment.placeSelectionEvents().collect { event ->
when (event) {
is PlaceSelectionSuccess -> {
val place = event.place
responseView.text = prettyPrintAutocompleteWidget(place, false)
}
is PlaceSelectionError -> Toast.makeText(
this@AutocompleteActivity,
"Failed to get place '${event.status.statusMessage}'",
Toast.LENGTH_SHORT
).show()
}
}
}
Bu kod, yer için hangi alanların isteneceği tanımlar, yer seçimi etkinliğini ve başarı veya başarısızlığı dinler. İstek başarılı olursa işlev, TextView'u yer ayrıntılarıyla doldurur. Yer Otomatik Tamamlama'nın bir Yer nesnesi döndürdüğünü unutmayın. Yer Otomatik Tamamlama widget'ı kullanılırken ayrı bir Yer Ayrıntıları isteği göndermenize gerek yoktur.
Otomatik Tamamlama etkinliğini manifest dosyasına ekleme
app/src/main
konumundaki AndroidManifest.xml
dosyasında <application>
öğesinin alt öğesi olarak AutocompleteActivity
için bir <activity>
öğesi ekleyin:
<activity android:name=".AutocompleteActivity" android:label="@string/autocomplete_fragment_demo_title" />
Otomatik tamamlama etkinliğini demo menüsüne ekleme
Daha önce olduğu gibi, Demo
modülündeki listeye ekleyerek Place Autocomplete demosunu ana ekrana ekleyin. Yer otomatik tamamlama etkinliği oluşturduktan sonra bu etkinliği src/main/java/com/google/codelabs/maps/placesdemo/
klasöründeki Demo.kt
dosyasına ekleyin. Bu kodu DETAILS_FRAGMENT_DEMO
öğesinin hemen sonrasına yapıştırın:
AUTOCOMPLETE_FRAGMENT_DEMO(
R.string.autocomplete_fragment_demo_title,
R.string.autocomplete_fragment_demo_description,
AutocompleteActivity::class.java
),
İlişkili dizeler, src/main/res/values/strings.xml
dosyasında tanımlanır.
Uygulamayı çalıştırma
- Uygulamayı çalıştırın. Bu kez ana ekran listesinde iki öğe görmeniz gerekir.
- Yer otomatik tamamlama satırına dokunun. Şekil 2'de gösterildiği gibi bir yer otomatik tamamlama girişi pop-up'ı görmeniz gerekir.
- Bir yerin adını yazmaya başlayın. Bu, bir kuruluş adı, adres veya coğrafi bölge olabilir. Tahminler, siz yazarken gösterilmelidir.
- Tahminlerden birini seçin. Tahminler kaybolur ve TextView, seçilen yerle ilgili ayrıntıları Şekil 3'te gösterildiği gibi görüntüler.
Şekil 2. Kullanıcı giriş alanına dokunduktan sonraki otomatik tamamlama etkinliği.
3.Şekil Kullanıcı "Niagara Şelalesi" yazıp seçtikten sonra yer ayrıntılarını gösteren otomatik tamamlama etkinliği.
10. Cihazın mevcut yerini alma
Mevcut Yer ekranı oluşturma
app/src/main/res/layout/
klasöründe boş bir LinearLayout
içeren activity_current.xml
düzeni sağlanmıştır. <LinearLayout>
ayraçlarının arasına aşağıdaki kodu ekleyerek doğrusal düzeni doldurun.
<Button
android:id="@+id/current_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/current_button" />
<TextView
android:id="@+id/current_response_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:scrollbars = "vertical"
android:textIsSelectable="true" />
Mevcut Yer etkinliği oluşturma
src/main/java/com/google/codelabs/maps/placesdemo/
klasöründe birCurrentPlaceActivity.kt
dosyası oluşturun ve bu kodu kullanarak tanımlayın:
@ExperimentalCoroutinesApi
class CurrentPlaceActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var placesClient: PlacesClient
private lateinit var currentButton: Button
private lateinit var responseView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_current)
// Retrieve a PlacesClient (previously initialized - see DemoApplication)
placesClient = Places.createClient(this)
// Set view objects
currentButton = findViewById(R.id.current_button)
responseView = findViewById(R.id.current_response_content)
// Set listener for initiating Current Place
currentButton.setOnClickListener {
checkPermissionThenFindCurrentPlace()
}
}
}
Bu kod, etkinliği düzen dosyasında tanımladığınız görünümlerle ilişkilendirir. Ayrıca, düğme tıklandığında checkPermissionThenFindCurrentPlace
işlevini çağırmak için düğmeye bir tıklama işleyici ekler.
checkPermissionThenFindCurrentPlace()
öğesini tanımlayarak ayrıntılı konum izninin olup olmadığını kontrol edin ve henüz verilmemişse bu izni isteyin. Bu koduonCreate
işlevinden sonra yapıştırın.
/**
* Checks that the user has granted permission for fine or coarse location.
* If granted, finds current Place.
* If not yet granted, launches the permission request.
* See https://developer.android.com/training/permissions/requesting
*/
private fun checkPermissionThenFindCurrentPlace() {
when {
(ContextCompat.checkSelfPermission(
this,
ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
this,
ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED) -> {
// You can use the API that requires the permission.
findCurrentPlace()
}
shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)
-> {
Log.d(TAG, "Showing permission rationale dialog")
// TODO: In an educational UI, explain to the user why your app requires this
// permission for a specific feature to behave as expected. In this UI,
// include a "cancel" or "no thanks" button that allows the user to
// continue using your app without granting the permission.
}
else -> {
// Ask for both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.
ActivityCompat.requestPermissions(
this,
arrayOf(
ACCESS_FINE_LOCATION,
ACCESS_COARSE_LOCATION
),
PERMISSION_REQUEST_CODE
)
}
}
}
companion object {
private const val TAG = "CurrentPlaceActivity"
private const val PERMISSION_REQUEST_CODE = 9
}
else
işlevinincheckPermissionThenFindCurrentPlace
dalırequestPermissions
işlevini çağırdığında uygulama, kullanıcıya izin isteği iletişim kutusu gösterir. Kullanıcı, Android 12'den daha eski bir işletim sisteminin yüklü olduğu bir cihaz kullanıyorsa yalnızca tam konum izni verebilir. Android 12 veya sonraki sürümleri çalıştıran bir cihaz kullanan kullanıcılara, Şekil 4'te gösterildiği gibi tam konum yerine yaklaşık (kaba) konum sağlama seçeneği sunulur.
Şekil 4. Android 12 veya sonraki sürümlerin yüklü olduğu bir cihazda kullanıcı izni istenirken tam veya yaklaşık konum izni verme seçeneği sunulur.
Kullanıcı, sistem izinleri iletişim kutusunu yanıtladıktan sonra sistem, onRequestPermissionsResult
işlevinin uygulamanızdaki uygulamasını çağırır. Sistem, izin iletişim kutusuna verilen kullanıcı yanıtını ve tanımladığınız istek kodunu iletir. Aşağıdaki kodu onRequestPermissionResult
altına yapıştırarak bu Anlık Yer etkinliğiyle ilgili konum izinlerinin istek kodunu işlemek için onRequestPermissionResult
işlevini geçersiz kılın.checkPermissionThenFindCurrentPlace
@SuppressLint("MissingPermission")
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>, grantResults: IntArray
) {
if (requestCode != PERMISSION_REQUEST_CODE) {
super.onRequestPermissionsResult(
requestCode,
permissions,
grantResults
)
return
} else if (
permissions.toList().zip(grantResults.toList())
.firstOrNull { (permission, grantResult) ->
grantResult == PackageManager.PERMISSION_GRANTED && (permission == ACCESS_FINE_LOCATION || permission == ACCESS_COARSE_LOCATION)
} != null
)
// At least one location permission has been granted, so proceed with Find Current Place
findCurrentPlace()
}
- İzin verildikten sonra
findCurrentPlace
işlevi çalışır. İşlevi,onRequestPermissionsResult
işlevinden sonra bu kodla tanımlayın.
/**
* Fetches a list of [PlaceLikelihood] instances that represent the Places the user is
* most likely to be at currently.
*/
@RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])
private fun findCurrentPlace() {
// Use fields to define the data types to return.
val placeFields: List<Place.Field> =
listOf(Place.Field.NAME, Place.Field.ID, Place.Field.ADDRESS, Place.Field.LAT_LNG)
// Call findCurrentPlace and handle the response (first check that the user has granted permission).
if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED
) {
// Retrieve likely places based on the device's current location
currentButton.isEnabled = false
lifecycleScope.launch {
val response = placesClient.awaitFindCurrentPlace(placeFields)
responseView.text = response.prettyPrint()
// Enable scrolling on the long list of likely places
val movementMethod = ScrollingMovementMethod()
responseView.movementMethod = movementMethod
}
} else {
Log.d(TAG, "LOCATION permission not granted")
checkPermissionThenFindCurrentPlace()
}
}
Bu kod, olası yerler için hangi alanların isteneceği tanımlar, FindCurrentPlaceRequest
oluşturur, görevi başlatır ve TextView'u istenen ayrıntılarla doldurur.
Mevcut Yer etkinliğini manifeste ekleyin
app/src/main
konumundaki AndroidManifest.xml
dosyasında <application>
öğesinin alt öğesi olarak CurrentPlaceActivity
için bir <activity>
öğesi ekleyin:
<activity android:name=".CurrentPlaceActivity" android:label="@string/current_demo_title" />
Mevcut Yer etkinliğini demo menüsüne ekleme
Tıpkı daha önce olduğu gibi, Demo
modülündeki listeye ekleyerek Current Place demosunu ana ekrana ekleyin. Mevcut Yer etkinliği oluşturduktan sonra bu etkinliği src/main/java/com/google/codelabs/maps/placesdemo/
klasöründeki Demo.kt
dosyasına ekleyin. Bu kodu AUTOCOMPLETE_FRAGMENT_DEMO
öğesinin hemen sonrasına yapıştırın:
CURRENT_FRAGMENT_DEMO(
R.string.current_demo_title,
R.string.current_demo_description,
CurrentPlaceActivity::class.java
),
İlişkili dizeler, src/main/res/values/strings.xml
dosyasında tanımlanır.
Uygulamayı çalıştırma
- Uygulamayı çalıştırın. Bu kez ana ekran listesinde üç öğe görmeniz gerekir.
- Geçerli Yer satırına dokunun. Ekranda bir düğme görmelisiniz.
- Düğmeye dokunun. Bu uygulamaya daha önce konum izni vermediyseniz izin isteği açılır.
- Uygulamaya cihazın konumuna erişim izni verin.
- Düğmeye tekrar dokunun. Bu kez, Şekil 5'te gösterildiği gibi, yakındaki 20'ye kadar yerin listesi ve olasılıkları görünür.
5.şekil Cihazın bildirilen konumu için olası mevcut yer eşleşmelerini gösterir.
11. Mevcut Yeri haritada gösterme
Harita bağımlılığını ekleyin
Modül düzeyindeki build.gradle
dosyanıza Android için Haritalar SDK'sı Google Play Hizmetleri bağımlılığını ekleyin.
app/build.gradle
dependencies {
// ...
implementation 'com.google.android.gms:play-services-maps:18.2.0'
}
Haritaları hesaba katmak için Android manifestini güncelleyin
meta-data
öğesinin içine aşağıdaki application
öğelerini ekleyin.
Bunlar, uygulamanın derlendiği Google Play Hizmetleri sürümünü yerleştirir ve API anahtarınızı belirtir.
AndroidManifest.xml
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
API anahtarını secrets.properties
adlı cihaza ekleyin
secrets.properties
dosyasını en üst düzey dizininizde açın ve aşağıdaki kodu ekleyin. YOUR_API_KEY
kısmını API anahtarınızla değiştirin.
MAPS_API_KEY=YOUR_API_KEY
local.defaults.properties
dosyasını üst düzey dizininizde (secrets.properties
dosyasıyla aynı klasör) açın ve aşağıdaki kodu ekleyin.
MAPS_API_KEY=DEFAULT_API_KEY
API anahtarını kontrol edin
onCreate()
içinde uygulama, Haritalar API anahtarını kontrol eder ve Haritalar destek parçasını başlatır. getMapAsync()
, harita geri arama özelliğine kaydolmak için kullanılır.
Bunu yapmak için aşağıdaki kodu ekleyin.
CurrentPlaceActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_current)
val apiKey = BuildConfig.MAPS_API_KEY
// Log an error if apiKey is not set.
if (apiKey.isEmpty() || apiKey == "DEFAULT_API_KEY") {
Log.e("Places test", "No api key")
finish()
return
}
// Retrieve a PlacesClient (previously initialized - see DemoApplication)
placesClient = Places.createClient(this)
(supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment?)?.getMapAsync(this)
// ...
}
Harita düzenini oluşturma
app/src/main/res/layout/
klasöründefragment_map.xml
adlı bir düzen dosyası oluşturun ve düzeni aşağıdaki kodla doldurun.
res/layout/fragment_map.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.google.codelabs.maps.placesdemo.CurrentPlaceActivity" />
Bu, harita için kapsayıcı görevi görecek ve GoogleMap
nesnesine erişim sağlayacak bir SupportMapFragment
tanımlar.
activity_current.xml
düzeninde,app/src/main/res/layout/
klasöründe bulunan doğrusal düzenin en altına aşağıdaki kodu ekleyin.
res/layout/activity_current.xml
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:text="@string/showing_most_likely_place"
style="@style/TextAppearance.AppCompat.Title"/>
<include layout="@layout/fragment_map"/>
Eklenen TextView
, oluşturulması gereken yeni bir dize kaynağına referans veriyor.
app/src/main/res/values/strings.xml
içinde aşağıdaki dize kaynağını ekleyin.
res/values/strings.xml
<string name="showing_most_likely_place">Showing most likely place</string>
Haritaya ek görünümler eklendiğinden, yer listesini gösteren TextView
öğesinin yüksekliği, bu görünümlerin görünür kalması için ayarlanmalıdır.
- Kimliği
current_response_content
olanTextView
öğesinemaxHeight
özelliğini ekleyin.
res/layout/activity_current.xml
android:maxHeight="200dp"
OnMapReadyCallback
işaretlemesini uygulayın
Sınıf bildirimine ekleyerek OnMapReadyCallback
arayüzünü uygulayın ve GoogleMap
nesnesi kullanılabilir olduğunda haritayı ayarlamak için onMapReady()
yöntemini geçersiz kılın:
CurrentPlaceActivity.kt
class CurrentPlaceActivity : AppCompatActivity(), OnMapReadyCallback {
Sınıfın sonuna aşağıdaki kodu ekleyin:
CurrentPlaceActivity.kt
override fun onMapReady(map: GoogleMap) {
this.map = map
lastKnownLocation?.let { location ->
map.moveCamera(
CameraUpdateFactory.newLatLngZoom(
location,
DEFAULT_ZOOM
)
)
}
}
Geri çağırmanın düzgün çalışması için bazı sınıf değişkenleri gerekir. Sınıf başlığının hemen ardından şunları ekleyin:
CurrentPlaceActivity.kt
private var map: GoogleMap? = null
private var lastKnownLocation: LatLng? = null
Aşağıdaki kodu sınıf arkadaşı nesnesine ekleyin:
CurrentPlaceActivity.kt
private const val DEFAULT_ZOOM = 15f
Uygulamayı çalıştırma
- Uygulamayı çalıştırın.
- Geçerli Yer satırına dokunun. Ekranda bir düğme görmelisiniz.
- Düğmeye dokunun. Bu uygulamaya daha önce konum izni vermediyseniz izin isteği açılır.
- Uygulamaya cihazın konumuna erişim izni verin.
- Düğmeye tekrar dokunun. Harita gösterilir.
6.şekil Haritayı gösteren Geçerli Yer etkinliği.
Haritayı bir yerle güncelleme
Sınıfın sonuna aşağıdaki kodu ekleyin:
CurrentPlaceActivity.kt
private data class LikelyPlace(
val name: String,
val address: String,
val attribution: List<String>,
val latLng: LatLng
)
private fun PlaceLikelihood.toLikelyPlace(): LikelyPlace? {
val name = this.place.name
val address = this.place.address
val latLng = this.place.latLng
val attributions = this.place.attributions ?: emptyList()
return if (name != null && address != null && latLng != null) {
LikelyPlace(name, address, attributions, latLng)
} else {
null
}
}
Bunlar, yerin verilerini depolamak ve biçimlendirmek için kullanılır.
Sınıfın başında, döndürülen yerin verilerini depolamak için kullanılan bir değişken oluşturmak üzere aşağıdaki kodu ekleyin.
CurrentPlaceActivity.kt
private val likelyPlaces = mutableListOf<LikelyPlace>()
Bu adımda kod , kullanıcıya bir Yerler listesi sunulacak ve kullanıcı haritada gösterilecek bir yer seçecek şekilde değiştirilir. Tüm Yerler verileri ekranda bir listede gösterilir.
findCurrentPlace
işlevinde, bu kod satırından önceki lifecycleScope.launch
bloğunda
CurrentPlaceActivity.kt
responseView.text = response.prettyPrint()
Aşağıdaki kodu ekleyin:
CurrentPlaceActivity.kt
likelyPlaces.clear()
likelyPlaces.addAll(
response.placeLikelihoods.take(M_MAX_ENTRIES).mapNotNull { placeLikelihood ->
placeLikelihood.toLikelyPlace()
}
)
openPlacesDialog()
Bu kod, gösterilecek maksimum yer sayısı için bir sabit gerektirir.
Yardımcı nesneye bu sabitin kodunu ekleyin.
CurrentPlaceActivity.kt
private const val M_MAX_ENTRIES = 5
Kullanıcının yer seçmesine olanak tanıyan iletişim kutusunu oluşturan aşağıdaki kodu ekleyin.
CurrentPlaceActivity.kt
/**
* Displays a form allowing the user to select a place from a list of likely places.
*/
private fun openPlacesDialog() {
// Ask the user to choose the place where they are now.
val listener =
DialogInterface.OnClickListener { _, which -> // The "which" argument contains the position of the selected item.
val likelyPlace = likelyPlaces[which]
lastKnownLocation = likelyPlace.latLng
val snippet = buildString {
append(likelyPlace.address)
if (likelyPlace.attribution.isNotEmpty()) {
append("\n")
append(likelyPlace.attribution.joinToString(", "))
}
}
val place = Place.builder().apply {
name = likelyPlace.name
latLng = likelyPlace.latLng
}.build()
map?.clear()
setPlaceOnMap(place, snippet)
}
// Display the dialog.
AlertDialog.Builder(this)
.setTitle(R.string.pick_place)
.setItems(likelyPlaces.map { it.name }.toTypedArray(), listener)
.setOnDismissListener {
currentButton.isEnabled = true
}
.show()
}
Android'deki en iyi uygulamalara uygun olarak iletişim kutusu, app/src/main/res/values/
klasöründeki strings.xml
kaynak dosyasına eklenmesi gereken bir dize kaynağına referans veriyor.
strings.xml
alanına aşağıdakileri ekleyin:
res/values/strings.xml
<string name="pick_place">Choose a place</string>
Bu işlevler daha sonra kamerayı hareket ettiren ve seçilen konuma işaretçi yerleştiren setPlaceOnMap
işlevini çağırır.
Aşağıdaki kodu ekleyin:
CurrentPlaceActivity.kt
private fun setPlaceOnMap(place: Place?, markerSnippet: String?) {
val latLng = place?.latLng ?: defaultLocation
map?.moveCamera(
CameraUpdateFactory.newLatLngZoom(
latLng,
DEFAULT_ZOOM
)
)
map?.addMarker(
MarkerOptions()
.position(latLng)
.title(place?.name)
.snippet(markerSnippet)
)
}
Haritaların durumunu kaydetmeniz ve geri yüklemeniz de önerilir.
Durumunu kaydetmek için onSaveInstanceState
işlevini geçersiz kılın ve aşağıdaki kodu ekleyin:
CurrentPlaceActivity.kt
/**
* Saves the state of the map when the activity is paused.
*/
override fun onSaveInstanceState(outState: Bundle) {
outState.putParcelable(KEY_LOCATION, lastKnownLocation)
super.onSaveInstanceState(outState)
}
Durumunu geri yüklemek için onCreate
bölümünde setContentView
çağrısından sonra aşağıdaki kodu ekleyin:
CurrentPlaceActivity.kt
if (savedInstanceState != null) {
lastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION)
}
Kaydetme ve geri yükleme için anahtar gerekir. Bu, yardımcı nesneden gelen sabit bir değerdir.
Eşlik eden nesne bloğuna aşağıdakileri ekleyin:
CurrentPlaceActivity.kt
// Key for storing activity state.
private const val KEY_LOCATION = "location"
Uygulamayı çalıştırma
- Uygulamayı çalıştırın.
- Geçerli Yer satırına dokunun. Ekranda bir düğme görmelisiniz.
- Düğmeye dokunun. Bu uygulamaya daha önce konum izni vermediyseniz izin isteği açılır.
- Uygulamaya cihazın konumuna erişim izni verin.
- Düğmeye tekrar dokunun.
- Dokunarak bir yer seçin. Harita yakınlaştırılır ve seçilen konuma yerleştirilen bir işaretçiyle ortalanır.
Şekil 7. Seçilen konumda işaretçi bulunan harita.
12. Tebrikler
Android için Yerler SDK'sını kullanarak Android uygulamasını başarıyla oluşturdunuz.
Öğrendikleriniz
- Android için Yerler SDK'sını yükleme ve yapılandırma.
- Android için Yerler SDK'sı için Kotlin Uzantıları'nı yükleyin.
- Yer ayrıntıları yükleniyor.
- Otomatik Yer Tamamlama ekleme
- Mevcut Yer'i alma
Sırada ne var?
- Daha fazla ilham almak için örnek ve demoların
android-places-demos
GitHub deposunu inceleyin veya çatallayın. - Google Haritalar Platformu ile Android uygulamaları oluşturmak için diğer Kotlin codelab'lerinden bilgi edinin.
- Aşağıdaki soruyu yanıtlayarak en yararlı bulacağınız içerikleri oluşturmamıza yardımcı olun:
Başka hangi codelab'leri görmek istersiniz?
İstediğiniz codelab listelenmiyor mu? Buradan yeni bir sorunla ilgili istekte bulunun.