Android (Java) için kendi Geçerli Yer seçicinizi oluşturma

1. Başlamadan önce

Kullanıcılarınıza mevcut konumlarını belirleyebilecekleri bir Yerler listesi sunmak için Google Haritalar Platformu'nu ve Android için Places SDK'sını nasıl kullanacağınızı öğrenin.

bd07a9ad2cb27a06.png

Ön koşullar

  • Temel Java becerileri

Yapacaklarınız

  • Android uygulamasına harita ekleme.
  • Kullanıcıyı coğrafi olarak konumlandırmak için konum izinlerini kullanın.
  • Kullanıcının mevcut konumuna yakın yerleri getirin.
  • Kullanıcının mevcut konumunu belirlemesi için olası yerleri gösterin.

Ne oluşturacaksınız?

Android uygulamanızı sıfırdan oluşturursunuz ancak hata ayıklama sırasında karşılaştırma yapmak için örnek kodu indirebilirsiniz. GitHub'dan örnek kodu indirin veya komut satırı kullanımı için Git'i ayarladıysanız aşağıdakileri girin:

git clone https://github.com/googlecodelabs/current-place-picker-android.git

Bu codelab'i uygularken herhangi bir sorunla (kod hataları, dilbilgisi hataları, net olmayan ifadeler vb.) karşılaşırsanız lütfen codelab'in sol alt köşesindeki Hata bildir bağlantısını kullanarak sorunu bildirin.

2. Başlayın

Bu codelab'e başlamadan önce aşağıdakileri ayarlamanız gerekir:

Android Studio

Android Studio'yu https://developer.android.com/studio adresinden indirin.

Android Studio'nuz varsa Android Studio > Check for Updates... (Güncellemeleri Denetle) seçeneğini tıklayarak en son sürümü kullandığınızdan emin olun.

1f36bae83b64e33.png

Bu laboratuvar, Android Studio 3.4 kullanılarak yazılmıştır.

Android SDK

Android Studio'da SDK Yöneticisi'ni kullanarak istediğiniz SDK'ları yapılandırabilirsiniz. Bu laboratuvarda Android Q SDK'sı kullanılır.

  1. Android Studio karşılama ekranında Configure (Yapılandır) > SDK Manager'ı (SDK Yöneticisi) tıklayın.

d3fa03c269ec231c.png

  1. İstediğiniz SDK onay kutusunu işaretleyin ve Uygula'yı tıklayın.

Henüz SDK'nız yoksa bu işlem, SDK'nın makinenize indirilmesini başlatır.

884e0aa1314f70d.png

Google Play Hizmetleri

SDK yöneticisinden Google Play Hizmetleri'ni de yüklemeniz gerekir.

  1. SDK Tools (SDK Araçları) sekmesini tıklayın ve Google Play services (Google Play Hizmetleri) onay kutusunu seçin.

Durum Güncelleme mevcut olarak görünüyorsa güncelleyin.

ad6211fd78f3b629.png

3. Emülatörü hazırlama

Uygulamayı çalıştırmak için kendi cihazınızı bağlayabilir veya Android Emulator'ı kullanabilirsiniz.

Kendi cihazınızı kullanıyorsanız bu sayfanın sonundaki Gerçek cihaz talimatları: Google Play Hizmetleri'ni güncelleme bölümüne gidin.

Emülatör ekleme

  1. Android Studio karşılama ekranında Yapılandır > AVD Yöneticisi'ni tıklayın.

5dd2d14c9c56d3f9.png

Android Virtual Device Manager iletişim kutusu açılır.

  1. Seçebileceğiniz cihazların listesini açmak için Sanal Cihaz Oluştur...'u tıklayın.

2d44eada384f8b35.png

  1. Play Store sütununda Play d5722488d80cd6be.png simgesini içeren bir cihaz seçin ve Sonraki'yi tıklayın.

e0248f1c6e85ab7c.png

Yüklenebilecek bir dizi sistem resmi görürsünüz. Android 9.+ (Google Play)'i hedefleyen Q'nun yanında İndir kelimesi varsa İndir'i tıklayın.

316d0d1efabd9f24.png

  1. Sanal cihazınıza ad vermek için Sonraki'yi, ardından Bitir'i tıklayın.

Sanal Cihazlarınız listesine geri dönersiniz.

  1. Yeni cihazınızın yanındaki Başlat'ı ba8adffe56d3b678.png tıklayın:

7605864ed27f77ea.png

Birkaç saniye sonra emülatör açılır.

Emülatör talimatları: Google Play Hizmetleri'ni güncelleme

  1. Emülatör başlatıldıktan sonra, görünen gezinme çubuğunda ...'yı tıklayın.

2e1156e02643d018.png

Genişletilmiş kontroller iletişim kutusu açılır.

  1. Menüde Google Play'i tıklayın.

Güncelleme varsa Güncelle'yi tıklayın.

5afd2686c5cad0e5.png

  1. Google Hesabı ile emülatörde oturum açın.

Testlerinizi kişisel bilgilerinizden ayrı tutmak için kendi hesabınızı kullanabilir veya ücretsiz olarak yeni bir hesap oluşturabilirsiniz.

Google Play, Google Play Hizmetleri'nde açılır.

  1. Google Play Hizmetleri'nin en son sürümünü edinmek için Güncelle'yi tıklayın.

f4bc067e80630b9c.png

Hesap kurulumunuzu tamamlamanız ve ödeme seçeneği eklemeniz istenirse Atla'yı tıklayın.

Emülatörde konumu ayarlama

  1. Emülatör başlatıldıktan sonra ana ekrandaki arama çubuğuna "maps" yazarak Google Haritalar uygulama simgesini getirin.

2d996aadd53685a6.png

  1. Başlatmak için simgeyi tıklayın.

Varsayılan bir harita görürsünüz.

  1. Haritanın sağ alt kısmında Konumunuz 'u c5b4e2fda57a7e71.png tıklayın.

Telefona konumu kullanma izni vermeniz istenir.

f2b68044eabca151.png

  1. Genişletilmiş Kontroller menüsünü açmak için ... simgesini tıklayın.
  2. Konum sekmesini tıklayın.
  3. Enlem ve boylam girin.

Buraya istediğiniz şeyi girebilirsiniz ancak çok sayıda yerin bulunduğu bir bölge olduğundan emin olun.

(Bu kod laboratuvarındaki sonuçları kopyalamak için Hawaii'deki Maui'de bulunan Kihei kasabası için enlem olarak 20.7818, boylam olarak -156.4624 değerlerini kullanın.)

  1. Gönder'i tıkladığınızda harita bu konumla güncellenir.

f9576b35218f4187.png

Uygulamanızı çalıştırmaya ve konumla test etmeye hazırsınız.

Gerçek cihaz talimatları: Google Play Hizmetleri'ni güncelleme

Gerçek bir Android cihaz kullanıyorsanız şunları yapın:

  1. Ana ekrandaki arama çubuğunu kullanarak Google Play Hizmetleri'ni arayın ve açın.
  2. Daha fazla ayrıntı'yı tıklayın.

Mevcutsa Güncelle'yi tıklayın.

ad16cdb975b5c3f7.png baf0379ef8a9c88c.png

4. Google Haritalar etkinliğiyle uygulama kabuğu oluşturma

  1. Android Studio karşılama ekranında Start a new Android Studio project'i (Yeni bir Android Studio projesi başlat) seçin.
  2. Telefon ve Tablet sekmesinde Google Haritalar Etkinliği'ni seçin.

c9c80aa8211a8761.png

Projenizi yapılandırın iletişim kutusu açılır. Uygulamanızı burada adlandırır ve alanınıza göre paketi oluşturursunuz.

Paket adı com.google.codelab.currentplace olan Current Place adlı uygulamanın ayarları aşağıda verilmiştir.

37f5b93b94ee118c.png

  1. Dil olarak Java'yı seçin ve Use androidx. artifacts* seçeneğini belirleyin.

Diğer ayarların varsayılan değerlerini koruyun.

  1. Son'u tıklayın.

5. Google Hizmetleri bağımlılıklarını Gradle derleme dosyasına ekleme

Android'de konum izinlerine erişmek için Google Play Hizmetleri'nden Google Konum ve Aktivite Tanıma API'sini kullanmanız gerekir. Bu ve diğer Google Play Hizmetleri API'lerini ekleme hakkında daha fazla bilgi için Google Play Hizmetleri'ni ayarlama başlıklı makaleyi inceleyin.

Android Studio projelerinde genellikle iki build.gradle dosyası bulunur. Biri genel proje, diğeri ise uygulama içindir. Android Studio Proje Gezgini'ni Android görünümünde kullanıyorsanız her ikisini de Gradle Scripts klasöründe görürsünüz. Google hizmetlerini eklemek için build.gradle (Module: app) dosyasını düzenlemeniz gerekir.

f3043429cf719c47.png

  1. Konum için Google hizmetlerini ve Places API'yi eklemek üzere dependencies bölümüne iki satır ekleyin ( bağlamdaki örnek kod).

build.gradle (Module: app)

plugins {
  id 'com.android.application'
}

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.google.codelab.currentplace"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'com.google.android.gms:play-services-maps:16.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

    implementation 'com.google.android.gms:play-services-location:16.0.0'
    implementation 'com.google.android.libraries.places:places:1.1.0'
}

6. Google Haritalar Platformu API'lerini etkinleştirme ve API anahtarı alma

Aşağıdaki etkinleştirme adımı için Android için Haritalar SDK'sı ve Places API'yi etkinleştirmeniz gerekir.

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.

  1. Cloud Console'da proje açılır menüsünü tıklayın ve bu codelab için kullanmak istediğiniz projeyi seçin.

  1. 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.
  2. 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.

Az önce oluşturduğunuz API anahtarını kopyalayın. Android Studio'ya geri dönün ve google_maps_api.xml dosyasını Android > app > res > values altında bulun.

YOUR_KEY_HERE kısmını kopyaladığınız API anahtarıyla değiştirin.

aa576e551a7a1009.png

Uygulamanız yapılandırıldı.

7. Düzen dosyasını düzenleme

  1. Proje gezgininizde, Android > app > res > layout içindeki activity_maps.xml dosyasını açın.

4e0d986480c57efa.png

  1. Ekranın sağ tarafında temel kullanıcı arayüzü açılır. Alt kısımdaki sekmeler, düzeniniz için Tasarım veya Metin düzenleyiciyi seçmenize olanak tanır. Metin'i seçin ve düzen dosyasının tüm içeriğini aşağıdakiyle değiştirin:

activity_maps.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:minHeight="?attr/actionBarSize"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:titleTextColor="@android:color/white"
        android:background="@color/colorPrimary" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <fragment
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="349dp"
            tools:context=".MapsActivity" />

        <ListView
            android:id="@+id/listPlaces"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>

Bu işlem sonucunda aşağıdaki gibi bir kullanıcı arayüzü elde edersiniz:

1bf786808a4697ce.png

8. Uygulama çubuğunu ayarlama

Kullanıcıya mevcut yerini seçmek istediğinde tıklayabileceği bir düğme vermek için, kullanıcının mevcut yerini bulan ve yakındaki olası yerleri gösteren bir simge içeren bir uygulama çubuğu ekleyin. Bu arayüz şöyle görünür:

3a17c92b613a26c5.png

Telefonda yalnızca simge gösterilir. Daha fazla alan içeren bir tablette metin de eklenir.

Simge oluşturma

  1. Proje gezgininde Android > app'i tıklayın, ardından res klasörünü sağ tıklayıp New > Image Asset'i (Yeni > Resim Öğesi) seçin.

Asset Studio açılır.

  1. Simge Türü menüsünde İşlem Çubuğu ve Sekme Simgeleri'ni tıklayın.
  2. Öğenizi adlandırın ic_geolocate.
  3. Öğe türü olarak Clip Art'ı seçin.
  4. Clip Art'ın yanındaki grafiği tıklayın.

Simge Seç penceresi açılır.

  1. Simge seçin.

Amacınızla ilgili simgeleri bulmak için arama çubuğunu kullanabilirsiniz.

  1. location ifadesini arayın ve konumla ilgili bir simge seçin.

Konumum simgesi, kullanıcı kamerayı mevcut konumuna sabitlemek istediğinde Google Haritalar uygulamasında kullanılan simgeyle aynıdır.

  1. Tamam > İleri > Bitir'i tıklayın ve yeni simge dosyalarınızı içeren drawable adlı yeni bir klasörün olduğunu onaylayın.

b9e0196137ed18ae.png

Dize kaynakları ekleme

  1. Proje gezgininde Android > app > res > values'u tıklayın ve strings.xml dosyasını açın.
  2. <string name="title_activity_maps">Map</string> satırından sonra aşağıdaki satırları ekleyin:

strings.xml

    <string name="action_geolocate">Pick Place</string>
    <string name="default_info_title">Default Location</string>
    <string name="default_info_snippet">No places found, because location permission is disabled.</string>

İlk satır, simgenin yanına bir metin etiketi eklemek için yer olduğunda uygulama çubuğunuzda kullanılır. Diğerleri ise haritaya eklediğiniz işaretçiler için kullanılır.

Dosyadaki kod artık şu şekilde görünüyor:

<resources>
    <string name="app_name">Current Place</string>
    <string name="title_activity_maps">Map</string>
    <string name="action_geolocate">Pick Place</string>
    <string name="default_info_title">Default Location</string>
    <string name="default_info_snippet">No places found, because location permission is disabled.</string>
</resources>

Uygulama çubuğunu ekleme

  1. Proje Gezgini'nde Android > app'i tıklayın, ardından res klasörünü sağ tıklayın ve app/src/main/res altında yeni bir alt dizin oluşturmak için Yeni > Dizin'i seçin.
  2. Dizini menu olarak adlandırın.
  3. menu klasörünü sağ tıklayın ve Yeni > Dosya'yı seçin.
  4. Dosyaya ad verin menu.xml.
  5. Aşağıdaki kodu yapıştırın:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <!-- "Locate me", should appear as action button if possible -->
    <item
        android:id="@+id/action_geolocate"
        android:icon="@drawable/ic_geolocate"
        android:title="@string/action_geolocate"
        app:showAsAction="always|withText" />

</menu>

Uygulama çubuğu stilini güncelleme

  1. Proje gezgininde Android > app > res > values'i genişletin ve içindeki styles.xml dosyasını açın.
  2. <style> etiketinde üst öğe özelliğini "Theme.AppCompat.NoActionBar" olarak düzenleyin.
  3. Bir sonraki adımda kullanacağınız name özelliğini not edin.

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">

AndroidManifest.xml dosyasında uygulama temasını güncelleyin.

  1. Android > app > manifests'ı tıklayın ve AndroidManifest.xml dosyasını açın.
  2. android:theme satırını bulun ve değeri @style/AppTheme olarak düzenleyin veya onaylayın.

AndroidManifest.xml

   <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

Artık kodlamaya başlayabilirsiniz.

9. Uygulamayı başlatma

  1. Proje Gezgini'nde MapsActivity.java dosyasını bulun.

Bu dosya, 1. adımda uygulamanız için oluşturduğunuz pakete karşılık gelen klasörde bulunur.

8b0fa27d417f5f55.png

  1. Dosyayı açtığınızda Java kod düzenleyicisine yönlendirilirsiniz.

Yerler SDK'sını ve diğer bağımlılıkları içe aktarma

Bu satırları MapsActivity.java dosyasının en üstüne ekleyin ve mevcut içe aktarma ifadelerini değiştirin.

Bunlar, mevcut içe aktarmaları içerir ve bu codelab'deki kodda kullanılan daha birçok içe aktarma ekler.

MapsActivity.java

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.libraries.places.api.Places;
import com.google.android.libraries.places.api.model.Place;
import com.google.android.libraries.places.api.model.PlaceLikelihood;
import com.google.android.libraries.places.api.net.FindCurrentPlaceRequest;
import com.google.android.libraries.places.api.net.FindCurrentPlaceResponse;
import com.google.android.libraries.places.api.net.PlacesClient;

import java.util.Arrays;
import java.util.List;

Sınıf imzasını güncelleme

Places API, geriye dönük uyumlu destek için AndroidX bileşenlerini kullandığından AppCompatActivity kapsamını genişletmek için bunu tanımlamanız gerekir. Bu özellik, haritalar etkinliği için varsayılan olarak tanımlanan FragmentActivity uzantısının yerini alır.

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {

Sınıf değişkenleri ekleme

Ardından, farklı sınıf yöntemlerinde kullanılan çeşitli sınıf değişkenlerini bildirin. Kullanıcı arayüzü öğeleri ve durum kodları da buna dahildir. Bunlar, GoogleMap mMap için değişken bildiriminin hemen altında olmalıdır.

    // New variables for Current Place picker
    private static final String TAG = "MapsActivity";
    ListView lstPlaces;
    private PlacesClient mPlacesClient;
    private FusedLocationProviderClient mFusedLocationProviderClient;

    // The geographical location where the device is currently located. That is, the last-known
    // location retrieved by the Fused Location Provider.
    private Location mLastKnownLocation;

    // A default location (Sydney, Australia) and default zoom to use when location permission is
    // not granted.
    private final LatLng mDefaultLocation = new LatLng(-33.8523341, 151.2106085);
    private static final int DEFAULT_ZOOM = 15;
    private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
    private boolean mLocationPermissionGranted;

    // Used for selecting the Current Place.
    private static final int M_MAX_ENTRIES = 5;
    private String[] mLikelyPlaceNames;
    private String[] mLikelyPlaceAddresses;
    private String[] mLikelyPlaceAttributions;
    private LatLng[] mLikelyPlaceLatLngs;

onCreate yöntemini güncelleme

Konum hizmetleri için çalışma zamanı kullanıcı izinlerini işlemek, kullanıcı arayüzü öğelerini ayarlamak ve Places API istemcisini oluşturmak üzere onCreate yöntemini güncellemeniz gerekir.

İşlem araç çubuğu, görünüm kurulumu ve Places istemcisiyle ilgili aşağıdaki kod satırlarını mevcut onCreate() yönteminin sonuna ekleyin.

MapsActivity.java onCreate()

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        //
        // PASTE THE LINES BELOW THIS COMMENT
        //
        
        // Set up the action toolbar
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Set up the views
        lstPlaces = (ListView) findViewById(R.id.listPlaces);

        // Initialize the Places client
        String apiKey = getString(R.string.google_maps_key);
        Places.initialize(getApplicationContext(), apiKey);
        mPlacesClient = Places.createClient(this);
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
    }

Uygulama çubuğu menünüz için kod ekleme

Bu iki yöntem, uygulama çubuğu menüsünü (tek bir öğe olan Yer Seç simgesiyle) ekler ve kullanıcının simgeyi tıklamasını işler.

Bu iki yöntemi, onCreate yönteminden sonra dosyanıza kopyalayın.

MapsActivity.java onCreateOptionsMenu() ve onOptionsItemSelected()

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
           case R.id.action_geolocate:
                
                // COMMENTED OUT UNTIL WE DEFINE THE METHOD
                // Present the current place picker
                // pickCurrentPlace();
                return true;

            default:
                // If we got here, the user's action was not recognized.
                // Invoke the superclass to handle it.
                return super.onOptionsItemSelected(item);

        }
    }

Test edin

  1. Android Studio'da Run (Çalıştır) veya Run menu > Run ‘app' (Çalıştır menüsü > "app" uygulamasını çalıştır) seçeneğini tıklayın.

28bea91c68c36fb2.png

  1. Dağıtım hedefinizi seçmeniz istenir. Çalışan emülatör bu listede görünmelidir. Seçtiğinizde Android Studio, uygulamayı sizin için emülatöre dağıtır.

f44658ca91f6f41a.png

Birkaç saniye sonra uygulama başlatılır. Avustralya'nın Sidney şehrinde ortalanmış haritayı, tek düğmeyi ve boş yerler listesini görürsünüz.

68eb8c70f4748350.png

Cihazın konumuna erişim izni istemediğiniz sürece haritanın odağı kullanıcının konumuna taşınmaz.

10. Konum izinlerini isteme ve işleme

Harita hazır olduktan sonra konum izinleri iste

  1. Kullanıcı izinleri isteyen getLocationPermission adlı bir yöntem tanımlayın.

Bu kodu, az önce oluşturduğunuz onOptionsSelected yönteminin altına yapıştırın.

MapsActivity.java getLocationPermission()

    private void getLocationPermission() {
        /*
         * Request location permission, so that we can get the location of the
         * device. The result of the permission request is handled by a callback,
         * onRequestPermissionsResult.
         */
        mLocationPermissionGranted = false;
        if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
                android.Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            mLocationPermissionGranted = true;
        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                    PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
        }
    }
  1. Yakınlaştırma kontrollerini etkinleştirmek ve kullanıcıdan konum izinleri istemek için mevcut onMapReady yönteminin sonuna iki satır ekleyin.

MapsActivity.java onMapReady()

   @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));

        //
        // PASTE THE LINES BELOW THIS COMMENT
        //

        // Enable the zoom controls for the map
        mMap.getUiSettings().setZoomControlsEnabled(true);

        // Prompt the user for permission.
        getLocationPermission();

    }

İstenen izinlerin sonucunu ele alma

Kullanıcı izin isteği iletişim kutusuna yanıt verdiğinde bu geri çağırma Android tarafından çağrılır.

Bu kodu getLocationPermission() yönteminden sonra yapıştırın:

MapsActivity.java onRequestPermissionsResult()

   /**
     * Handles the result of the request for location permissions
     */
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String permissions[],
                                           @NonNull int[] grantResults) {
        mLocationPermissionGranted = false;
        switch (requestCode) {
            case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    mLocationPermissionGranted = true;
                }
            }
        }
    }

11. Mevcut konumu alma ve olası yerleri getirme

Kullanıcı uygulama çubuğunda Yer Seç'i tıkladığında uygulama, daha önce tanımladığınız getDeviceLocation() yöntemini çağıran pickCurrentPlace() yöntemini çağırır. getDeviceLocation yöntemi, en son cihaz konumunu aldıktan sonra başka bir yöntem olan getCurrentPlaceLikelihoods,'u çağırır.

findCurrentPlace API'yi çağırın ve yanıtı işleyin

getCurrentPlaceLikelihoods, findCurrentPlaceRequest oluşturur ve Places API findCurrentPlace görevini çağırır. Görev başarılı olursa findCurrentPlaceResponse döndürülür. Bu, placeLikelihood nesnelerinin listesini içerir. Bunların her birinin, yerin adı ve adresi ile o yerde olma olasılığınız (0 ile 1 arasında bir çift değer) gibi bir dizi özelliği vardır. Bu yöntem, placeLikelihoods öğesinden yer ayrıntıları listeleri oluşturarak yanıtı işler.

Bu kod, en olası beş yeri yineler ve olasılığı 0'dan büyük olanları, daha sonra oluşturacağı bir listeye ekler. Beşten fazla veya az göstermek istiyorsanız M_MAX_ENTRIES sabitini düzenleyin.

Bu kodu onMapReady yönteminden sonra yapıştırın.

MapsActivity.java getCurrentPlaceLikelihoods()

   private void getCurrentPlaceLikelihoods() {
        // Use fields to define the data types to return.
        List<Place.Field> placeFields = Arrays.asList(Place.Field.NAME, Place.Field.ADDRESS,
                Place.Field.LAT_LNG);

        // Get the likely places - that is, the businesses and other points of interest that
        // are the best match for the device's current location.
        @SuppressWarnings("MissingPermission") final FindCurrentPlaceRequest request =
                FindCurrentPlaceRequest.builder(placeFields).build();
        Task<FindCurrentPlaceResponse> placeResponse = mPlacesClient.findCurrentPlace(request);
        placeResponse.addOnCompleteListener(this,
                new OnCompleteListener<FindCurrentPlaceResponse>() {
                    @Override
                    public void onComplete(@NonNull Task<FindCurrentPlaceResponse> task) {
                        if (task.isSuccessful()) {
                            FindCurrentPlaceResponse response = task.getResult();
                            // Set the count, handling cases where less than 5 entries are returned.
                            int count;
                            if (response.getPlaceLikelihoods().size() < M_MAX_ENTRIES) {
                                count = response.getPlaceLikelihoods().size();
                            } else {
                                count = M_MAX_ENTRIES;
                            }

                            int i = 0;
                            mLikelyPlaceNames = new String[count];
                            mLikelyPlaceAddresses = new String[count];
                            mLikelyPlaceAttributions = new String[count];
                            mLikelyPlaceLatLngs = new LatLng[count];

                            for (PlaceLikelihood placeLikelihood : response.getPlaceLikelihoods()) {
                                Place currPlace = placeLikelihood.getPlace();
                                mLikelyPlaceNames[i] = currPlace.getName();
                                mLikelyPlaceAddresses[i] = currPlace.getAddress();
                                mLikelyPlaceAttributions[i] = (currPlace.getAttributions() == null) ?
                                        null : TextUtils.join(" ", currPlace.getAttributions());
                                mLikelyPlaceLatLngs[i] = currPlace.getLatLng();

                                String currLatLng = (mLikelyPlaceLatLngs[i] == null) ?
                                        "" : mLikelyPlaceLatLngs[i].toString();

                                Log.i(TAG, String.format("Place " + currPlace.getName()
                                        + " has likelihood: " + placeLikelihood.getLikelihood()
                                        + " at " + currLatLng));

                                i++;
                                if (i > (count - 1)) {
                                    break;
                                }
                            }


                            // COMMENTED OUT UNTIL WE DEFINE THE METHOD
                            // Populate the ListView
                            // fillPlacesList();
                        } else {
                            Exception exception = task.getException();
                            if (exception instanceof ApiException) {
                                ApiException apiException = (ApiException) exception;
                                Log.e(TAG, "Place not found: " + apiException.getStatusCode());
                            }
                        }
                    }
                });
    }

Harita kamerasını cihazın mevcut konumuna taşıma

Kullanıcı izin verirse uygulama, kullanıcının en son konumunu getirir ve kamerayı bu konumun etrafında ortalayacak şekilde hareket ettirir.

Kullanıcı izni reddederse uygulama, kamerayı bu sayfanın başındaki sabitler arasında tanımlanan varsayılan konuma (örnek kodda Sidney, Avustralya) taşır.

Bu kodu getPlaceLikelihoods() yönteminden sonra yapıştırın:

MapsActivity.java getDeviceLocation()

    private void getDeviceLocation() {
        /*
         * Get the best and most recent location of the device, which may be null in rare
         * cases when a location is not available.
         */
        try {
            if (mLocationPermissionGranted) {
                Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation();
                locationResult.addOnCompleteListener(this, new OnCompleteListener<Location>() {
                    @Override
                    public void onComplete(@NonNull Task<Location> task) {
                        if (task.isSuccessful()) {
                            // Set the map's camera position to the current location of the device.
                            mLastKnownLocation = task.getResult();
                            Log.d(TAG, "Latitude: " + mLastKnownLocation.getLatitude());
                            Log.d(TAG, "Longitude: " + mLastKnownLocation.getLongitude());
                            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
                                    new LatLng(mLastKnownLocation.getLatitude(),
                                            mLastKnownLocation.getLongitude()), DEFAULT_ZOOM));
                        } else {
                            Log.d(TAG, "Current location is null. Using defaults.");
                            Log.e(TAG, "Exception: %s", task.getException());
                            mMap.moveCamera(CameraUpdateFactory
                                    .newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
                        }

                       getCurrentPlaceLikelihoods();
                    }
                });
            }
        } catch (SecurityException e)  {
            Log.e("Exception: %s", e.getMessage());
        }
    }

Kullanıcı Yer Seç'i tıkladığında konum izinlerini kontrol etme

Kullanıcı Yer Seç'e dokunduğunda bu yöntem, konum izinlerini kontrol eder ve izin verilmemişse kullanıcıdan izin ister.

Kullanıcı izin verdiyse mevcut olası yerleri alma sürecini başlatmak için yöntem getDeviceLocation çağrıları yapar.

  1. Bu yöntemi getDeviceLocation() işleminden sonra ekleyin:

MapsActivity.java pickCurrentPlace()

   private void pickCurrentPlace() {
        if (mMap == null) {
            return;
        }

        if (mLocationPermissionGranted) {
            getDeviceLocation();
        } else {
            // The user has not granted permission.
            Log.i(TAG, "The user did not grant location permission.");

            // Add a default marker, because the user hasn't selected a place.
            mMap.addMarker(new MarkerOptions()
                    .title(getString(R.string.default_info_title))
                    .position(mDefaultLocation)
                    .snippet(getString(R.string.default_info_snippet)));

            // Prompt the user for permission.
            getLocationPermission();
        }
    }
  1. pickCurrentPlace tanımlandığına göre, onOptionsItemSelected() içinde pickCurrentPlace'yı çağıran satırı bulun ve satırın yorumunu kaldırın.

MapsActivity.java onOptionItemSelected()

           case R.id.action_geolocate:

                // COMMENTED OUT UNTIL WE DEFINE THE METHOD
                // Present the Current Place picker
                pickCurrentPlace();
                return true;

Test edin

Uygulamayı şimdi çalıştırıp Yer Seç'e dokunursanız konum izinleri istenmelidir.

  • İzin verirseniz bu tercih kaydedilir ve tekrar istem almazsınız. İzni reddederseniz düğmeye bir sonraki dokunuşunuzda izin istenir.
  • getPlaceLikelihoods, muhtemel mevcut yerleri getirmiş olsa da ListView bunları henüz göstermiyor. Android Studio'da, yeni yöntemlerinizin düzgün çalıştığını doğrulamak için ⌘6 tuşuna basarak Logcat'teki MapsActivity etiketli ifadelerin günlüklerini kontrol edebilirsiniz.
  • İzin verdiyseniz günlüklerde Latitude: ifadesi ve cihazın algılanan konumunu gösteren Longitude: ifadesi yer alır. Daha önce Google Haritalar'ı ve emülatörün genişletilmiş menüsünü kullanarak emülatör için bir konum belirlediyseniz bu ifadeler söz konusu konumu gösterir.
  • findCurrentPlace çağrısı başarılı olduysa günlükler, en olası beş yerin adlarını ve konumlarını yazdıran beş ifade içerir.

d9896a245b81bf3.png

12. Mevcut yer seçiciyi doldurma

Seçilen yerler için bir işleyici ayarlama

Kullanıcı ListView içindeki bir öğeyi tıkladığında ne olmasını istediğimizi düşünelim. Kullanıcının şu anda bulunduğu yeri onaylamak için haritaya o konumda bir işaretçi ekleyebilirsiniz. Kullanıcı bu işaretçiyi tıkladığında, yerin adını ve adresini gösteren bir bilgi penceresi açılır.

Bu tıklama işleyicisini pickCurrentPlace yönteminden sonra yapıştırın.

MapsActivity.java listClickedHandler

    private AdapterView.OnItemClickListener listClickedHandler = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView parent, View v, int position, long id) {
            // position will give us the index of which place was selected in the array
            LatLng markerLatLng = mLikelyPlaceLatLngs[position];
            String markerSnippet = mLikelyPlaceAddresses[position];
            if (mLikelyPlaceAttributions[position] != null) {
                markerSnippet = markerSnippet + "\n" + mLikelyPlaceAttributions[position];
            }

            // Add a marker for the selected place, with an info window
            // showing information about that place.
            mMap.addMarker(new MarkerOptions()
                    .title(mLikelyPlaceNames[position])
                    .position(markerLatLng)
                    .snippet(markerSnippet));

           // Position the map's camera at the location of the marker.
            mMap.moveCamera(CameraUpdateFactory.newLatLng(markerLatLng));
        }
    };

ListView'u doldurma

Kullanıcının şu anda ziyaret ettiği yerlerin listesini oluşturduktan sonra bu seçenekleri ListView içinde kullanıcıya sunabilirsiniz. Ayrıca, yeni tanımladığınız tıklama işleyicisini kullanmak için ListView tıklama işleyicisini de ayarlayabilirsiniz.

Bu yöntemi tıklama işleyicisinin arkasına yapıştırın:

MapsActivity.java fillPlacesList()

    private void fillPlacesList() {
        // Set up an ArrayAdapter to convert likely places into TextViews to populate the ListView
        ArrayAdapter<String> placesAdapter =
                new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mLikelyPlaceNames);
        lstPlaces.setAdapter(placesAdapter);
        lstPlaces.setOnItemClickListener(listClickedHandler);
    }

fillPlacesList tanımlandığına göre, findPlaceLikelihoods dosyasının sonuna doğru fillPlacesList işlevini çağıran satırı bulup yorumdan çıkarın.

MapsActivity.java fillPlaceLikelihoods()

               // COMMENTED OUT UNTIL WE DEFINE THE METHOD
                // Populate the ListView
                fillPlacesList();

Mevcut yer seçici için gereken kod bu kadar.

13. Uygulamayı çalıştırma

Yer seçme özelliğini test etme

  1. Uygulamayı tekrar çalıştırın.

Bu kez Yer Seç'e dokunduğunuzda uygulama, listeyi konuma yakın adlandırılmış yerlerle doldurur. Maui'deki bu konumun yakınında Ululani's Hawaiian Shave Ice ve Sugar Beach Bake Shop gibi yerler bulunur. Bu yerler, konum koordinatlarına çok yakın olduğundan bulunduğunuz yer olabilecek yerlerin listesini görüyorsunuz.

  1. ListView bölümünde bir yer adını tıklayın.

Haritaya bir işaretçi eklendiğini görürsünüz.

  1. İşaretçiye dokunun.

Yer ayrıntılarını görebilirsiniz.

e52303cc0de6a513.png 864c74342fb52a01.png

Farklı bir konumu test etme

Konumunuzu değiştirmek istiyorsanız ve emülatörü kullanıyorsanız emülatörün genişletilmiş menüsünde konum koordinatlarını güncellediğinizde cihaz konumu otomatik olarak güncellenmez.

Bu sorunu çözmek için aşağıdaki adımları uygulayarak yerel Google Haritalar uygulamasını kullanarak emülatörün konumunu güncellemeye zorlayın:

  1. Google Haritalar'ı açın.
  2. Enlem ve boylamı yeni koordinatlarla değiştirmek için ... > Konum'a, ardından Gönder'e dokunun.
  3. Örneğin, konumu Kanada'nın Vancouver şehir merkezine ayarlamak için enlem: 49.2768 ve boylam: -123.1142 değerlerini kullanabilirsiniz.
  4. Google Haritalar'ın yeni koordinatlarınızda yeniden ortalandığını doğrulayın. Yeniden ortalama isteğinde bulunmak için Google Haritalar uygulamasında Konumum düğmesine dokunmanız gerekebilir.
  5. Current Place uygulamasına dönün ve haritayı yeni koordinatlara getirmek için Pick Place'e (Yer Seç) dokunun. Böylece, olası mevcut yerlerin yeni bir listesini görürsünüz.

9adb99d1ce25c184.png

Hepsi bu kadar! Mevcut konumdaki yerleri kontrol eden ve hangi yerlerde olma ihtimalinizin yüksek olduğunu gösteren basit bir uygulama geliştirdiniz. Keyfini çıkarın!

Şimdi bu bonus adımını tamamlamak için uygulamayı yaptığınız değişikliklerle çalıştırın.

14. Sonraki adımlar

API anahtarınızın çalınmasını önlemek için anahtarın güvenliğini sağlamanız gerekir. Böylece anahtarı yalnızca Android uygulamanız kullanabilir. Kısıtlanmadığı takdirde, anahtarınıza sahip olan herkes Google Haritalar Platformu API'lerini çağırmak için anahtarınızı kullanabilir ve bu durum, faturalandırılmanıza neden olabilir.

SHA-1 sertifikanızı alma

API anahtarlarınızı kısıtlarken bu bilgiye ihtiyacınız olur. Aşağıda, hata ayıklama sertifikanızı alma talimatları verilmiştir.

Linux veya macOS için bir terminal penceresi açıp aşağıdakileri girin:

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

Windows Vista ve Windows 7 için aşağıdaki komutu çalıştırın:

keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android

Şuna benzer bir çıkış alırsınız:

Alias name: androiddebugkey
Creation date: Jan 01, 2013
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Android Debug, O=Android, C=US
Issuer: CN=Android Debug, O=Android, C=US
Serial number: 4aa9b300
Valid from: Mon Jan 01 08:04:04 UTC 2013 until: Mon Jan 01 18:04:04 PST 2033
Certificate fingerprints:
     MD5:  AE:9F:95:D0:A6:86:89:BC:A8:70:BA:34:FF:6A:AC:F9
     SHA1: BB:0D:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:75
     Signature algorithm name: SHA1withRSA
     Version: 3

SHA1 ile başlayan satır, sertifikanın SHA-1 parmak izini içerir. Parmak izi, iki nokta ile ayrılmış 20 çift haneli on altılı sayı dizisidir.

Bir uygulamayı yayınlamaya hazır olduğunuzda, yayın sertifikanızı almak için bu dokümandaki talimatları uygulayın.

API anahtarınıza kısıtlamalar ekleme

  1. Cloud Console'da API'ler ve Hizmetler > Kimlik Bilgileri'ne gidin.

Bu uygulama için kullandığınız anahtar, API Anahtarları altında listelenmelidir.

  1. Anahtar ayarlarını düzenlemek için 6454a04865d551e6.png simgesini tıklayın.

316b052c621ee91c.png

  1. API anahtarı sayfasında, Anahtar kısıtlamaları bölümünde Uygulama kısıtlamaları'nı ayarlamak için aşağıdakileri yapın:
  2. Android uygulamaları'nı seçip talimatları uygulayın.
  3. Öğe ekleyin'i tıklayın.
  4. Paketinizin adını ve SHA-1 sertifikası parmak izini (önceki bölümde alınmıştır) girin.

Örneğin:

com.google.codelab.currentplace
BB:0D:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:75s
  1. Daha fazla koruma için aşağıdaki adımları uygulayarak API kısıtlamalarını ayarlayın.
  2. API kısıtlamalarından sonra Anahtarı kısıtla'yı seçin.
  3. Android için Haritalar SDK'sı ve Places API'yi seçin.
  4. Bitti'yi ve Kaydet'i tıklayın.

15. Tebrikler

Mevcut konumdaki en olası yerleri kontrol eden ve kullanıcının seçtiği yer için haritaya işaretçi ekleyen basit bir uygulama oluşturdunuz.

Daha fazla bilgi