درباره این codelab
1. قبل از اینکه شروع کنی
با نحوه استفاده از Google Maps Platform و Places SDK برای Android برای ارائه لیستی از مکان ها برای شناسایی مکان های فعلی به کاربران خود آشنا شوید.
پیش نیازها
- مهارت های پایه جاوا
کاری که خواهی کرد
- یک نقشه به برنامه اندروید اضافه کنید.
- از مجوزهای موقعیت مکانی برای تعیین موقعیت جغرافیایی کاربر استفاده کنید.
- مکانهای نزدیک به مکان فعلی کاربر را واکشی کنید.
- مکانهای احتمالی را برای شناسایی مکان فعلی کاربر به کاربر ارائه دهید.
چیزی که خواهی ساخت
شما برنامه اندروید خود را از ابتدا می سازید، اما می توانید کد نمونه را برای مقایسه در هنگام اشکال زدایی دانلود کنید. کد نمونه را از GitHub دانلود کنید، یا اگر Git را برای استفاده از خط فرمان تنظیم کرده اید، موارد زیر را وارد کنید:
git clone https://github.com/googlecodelabs/current-place-picker-android.git
اگر در حین کار با این کد با مشکلاتی (اشکالات کد، خطاهای دستوری، عبارت نامشخص یا چیز دیگری) مواجه شدید، لطفاً مشکل را از طریق پیوند گزارش یک اشتباه در گوشه سمت چپ پایین صفحه کد گزارش دهید.
2. شروع کنید
قبل از شروع این کد لبه، باید موارد زیر را تنظیم کنید:
اندروید استودیو
اندروید استودیو را از https://developer.android.com/studio دانلود کنید.
اگر قبلاً Android Studio دارید، با کلیک روی Android Studio > Check for Updates... مطمئن شوید که آخرین نسخه را دارید.
این آزمایشگاه با استفاده از اندروید استودیو 3.4 نوشته شده است.
Android SDK
در اندروید استودیو، می توانید SDK های مورد نظر خود را با استفاده از SDK Manager پیکربندی کنید. این آزمایشگاه از Android Q SDK استفاده می کند.
- از صفحه خوش آمدگویی Android Studio، روی Configure > SDK Manager کلیک کنید.
- کادر انتخاب SDK مورد نظر خود را انتخاب کنید، سپس روی Apply کلیک کنید.
اگر هنوز SDK را ندارید، با این کار دانلود SDK در دستگاه شما آغاز می شود.
خدمات گوگل پلی
از مدیر SDK، همچنین باید خدمات Google Play را نصب کنید.
- روی برگه ابزار SDK کلیک کنید و کادر خدمات Google Play را انتخاب کنید.
در صورت خواندن وضعیت بهروزرسانی موجود ، بهروزرسانی کنید.
3. شبیه ساز را آماده کنید
برای اجرای برنامه، می توانید دستگاه خود را متصل کنید یا از شبیه ساز اندروید استفاده کنید.
اگر از دستگاه خود استفاده میکنید، به دستورالعملهای دستگاه واقعی بروید: خدمات Google Play را در انتهای این صفحه بهروزرسانی کنید.
یک شبیه ساز اضافه کنید
- از صفحه خوش آمدگویی Android Studio، روی Configure > AVD Manager کلیک کنید.
با این کار کادر گفتگوی مدیریت دستگاه مجازی اندروید باز می شود.
- روی Create Virtual Device... کلیک کنید تا لیستی از دستگاه هایی که می توانید انتخاب کنید باز شود.
- دستگاهی را با Play انتخاب کنید
در ستون Play Store کلیک کنید و روی Next کلیک کنید.
مجموعه ای از تصاویر سیستم را می بینید که می توانید نصب کنید. اگر Q که Android 9.+ (Google Play) را هدف قرار می دهد کلمه Download را در کنار خود دارد، روی دانلود کلیک کنید.
- روی Next کلیک کنید تا به دستگاه مجازی خود یک نام بدهید، سپس روی Finish کلیک کنید.
شما به لیست دستگاه های مجازی خود باز می گردید.
- روی Start کلیک کنید
در کنار دستگاه جدید شما:
پس از چند لحظه، شبیه ساز باز می شود.
دستورالعملهای شبیهساز — خدمات Google Play را بهروزرسانی کنید
- پس از راه اندازی شبیه ساز، روی ... در نوار پیمایش که ظاهر می شود کلیک کنید **.**
با این کار کادر گفتگوی Extended Controls باز می شود.
- در منو روی Google Play کلیک کنید.
اگر بهروزرسانی در دسترس است، روی بهروزرسانی کلیک کنید.
- با یک حساب Google وارد شبیه ساز شوید.
می توانید از حساب کاربری خود استفاده کنید یا یک حساب کاربری جدید به صورت رایگان ایجاد کنید تا آزمایش خود را جدا از اطلاعات شخصی خود نگه دارید.
سپس Google Play به خدمات Google Play باز می شود.
- برای دریافت آخرین نسخه خدمات Google Play روی Update کلیک کنید.
اگر از شما خواسته شد راهاندازی حساب خود را تکمیل کنید و یک گزینه پرداخت اضافه کنید، روی Skip کلیک کنید.
مکان را در شبیه ساز تنظیم کنید
- هنگامی که شبیه ساز راه اندازی شد، "maps" را در نوار جستجو در صفحه اصلی تایپ کنید تا نماد برنامه Google Maps را بالا بکشید.
- برای راه اندازی روی نماد کلیک کنید.
یک نقشه پیش فرض می بینید.
- در سمت راست پایین نقشه، روی مکان شما کلیک کنید
.
از شما خواسته می شود به تلفن اجازه استفاده از موقعیت مکانی را بدهید.
- روی ... کلیک کنید تا منوی Extended Controls باز شود.
- روی تب Location کلیک کنید.
- طول و عرض جغرافیایی را وارد کنید.
هر چیزی را که دوست دارید اینجا وارد کنید، اما مطمئن شوید که در منطقهای با مکانهای زیاد است.
(از Latitude 20.7818 و Longitude -156.4624 برای شهر Kihei در Maui در هاوایی استفاده کنید تا نتایج این آزمایشگاه کد را تکرار کنید.)
- روی ارسال کلیک کنید و نقشه با این مکان به روز می شود.
شما آماده اجرای برنامه خود و آزمایش آن با مکان هستید.
دستورالعملهای واقعی دستگاه - خدمات Google Play را بهروزرسانی کنید
اگر از یک دستگاه اندروید واقعی استفاده میکنید، موارد زیر را انجام دهید:
- از نوار جستجو در صفحه اصلی برای جستجو و باز کردن خدمات Google Play استفاده کنید.
- روی جزئیات بیشتر کلیک کنید.
در صورت موجود بودن، روی Update کلیک کنید.
4. پوسته برنامه را با یک فعالیت Google Maps ایجاد کنید
- در صفحه خوش آمدگویی Android Studio، شروع یک پروژه جدید Android Studio را انتخاب کنید.
- در تب Phone and Tablet ، Google Maps Activity را انتخاب کنید.
کادر گفتگوی Configure your project باز می شود. اینجا جایی است که نام برنامه خود را می گذارید و بسته را بر اساس دامنه خود ایجاد می کنید.
در اینجا تنظیمات برنامه ای به نام Current Place است که با بسته com.google.codelab.currentplace
مطابقت دارد.
- جاوا را به عنوان زبان انتخاب کرده و Use androidx را انتخاب کنید. مصنوعات *.
تنظیمات پیش فرض را برای بقیه تنظیمات حفظ کنید.
- روی Finish کلیک کنید.
5. وابستگی های Google Services را به فایل ساخت Gradle اضافه کنید
برای دسترسی به مجوزهای مکان در Android، به API مکان Google و Activity Recognition از سرویسهای Google Play نیاز دارید. برای اطلاعات بیشتر در مورد افزودن این و سایر APIهای خدمات Google Play، به تنظیم خدمات Google Play مراجعه کنید.
پروژه های Android Studio معمولا دارای دو فایل build.gradle
هستند. یکی برای پروژه کلی و یکی برای برنامه است. اگر Android Studio Project Explorer را در نمای اندروید دارید، هر دوی آنها را در پوشه Gradle Scripts
می بینید. برای افزودن خدمات Google باید فایل build.gradle (Module: app)
را ویرایش کنید.
- دو خط به بخش
dependencies
اضافه کنید تا سرویسهای Google برای مکان و Places API ( کد نمونه در زمینه ) اضافه شود.
build.gradle (ماژول: برنامه)
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. API های پلتفرم نقشه های گوگل را فعال کنید و یک کلید API دریافت کنید
برای مرحله فعال سازی زیر، باید Maps SDK for Android و Places API را فعال کنید.
پلتفرم نقشه های گوگل را راه اندازی کنید
اگر قبلاً حساب Google Cloud Platform و پروژهای با صورتحساب فعال ندارید، لطفاً راهنمای شروع به کار با Google Maps Platform را برای ایجاد یک حساب صورتحساب و یک پروژه ببینید.
- در Cloud Console ، روی منوی کشویی پروژه کلیک کنید و پروژه ای را که می خواهید برای این کد لبه استفاده کنید انتخاب کنید.
- APIها و SDKهای پلتفرم Google Maps مورد نیاز برای این لبه کد را در Google Cloud Marketplace فعال کنید. برای انجام این کار، مراحل این ویدئو یا این مستند را دنبال کنید.
- یک کلید API در صفحه Credentials در Cloud Console ایجاد کنید. می توانید مراحل این ویدئو یا این مستند را دنبال کنید. همه درخواستها به پلتفرم نقشههای Google به یک کلید API نیاز دارند.
کلید API را که ایجاد کردید کپی کنید. به Android Studio برگردید و فایل google_maps_api.xml
را در زیر Android > app > res > value s پیدا کنید.
YOUR_KEY_HERE
را با کلید API که کپی کردید جایگزین کنید.
اکنون برنامه شما پیکربندی شده است.
7. فایل طرح بندی را ویرایش کنید
- در کاوشگر پروژه خود، فایل
activity_maps.xml
را در Android >app
>res
>layout
باز کنید.
- رابط کاربری اصلی را در سمت راست صفحه باز میبینید، با زبانههایی در پایین که به شما امکان میدهد ویرایشگر طراحی یا متن را برای طرحبندی خود انتخاب کنید. Text را انتخاب کنید و کل محتوای فایل layout را با این جایگزین کنید:
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>
این یک رابط کاربری به شما می دهد که به شکل زیر است:
8. نوار برنامه را تنظیم کنید
برای اینکه به کاربر دکمهای بدهید تا وقتی میخواهد مکان فعلی خود را انتخاب کند، یک نوار برنامه با نمادی اضافه کنید که مکان فعلی کاربر را پیدا کرده و مکانهای احتمالی نزدیک را نشان میدهد. شبیه این خواهد شد:
در تلفن، فقط نماد نشان داده می شود. در تبلت با فضای بیشتر، متن نیز گنجانده شده است.
نماد را ایجاد کنید
- در کاوشگر پروژه، روی Android > app کلیک کنید، سپس روی پوشه res راست کلیک کرده و New > Image Asset را انتخاب کنید.
Asset Studio باز می شود.
- در منوی Icon Type ، روی Action Bar and Tab Icons کلیک کنید.
- دارایی خود را
ic_geolocate
کنید. - Clip Art را به عنوان نوع دارایی انتخاب کنید**.**
- روی گرافیک کنار Clip Art کلیک کنید.
با این کار پنجره Select Icon باز می شود.
- یک تصویر انتخاب کن.
می توانید از نوار جستجو برای یافتن نمادهای مرتبط با هدف خود استفاده کنید.
- مکان را جستجو کنید و نماد مربوط به
location
را انتخاب کنید.
نماد موقعیت مکانی من همان نمادی است که در برنامه Google Maps زمانی که کاربر می خواهد دوربین را به مکان فعلی خود ببرد استفاده می شود.
- روی OK > Next > Finish کلیک کنید و تأیید کنید که پوشه جدیدی به نام
drawable
وجود دارد که حاوی فایلهای نماد جدید شما است.
منابع رشته را اضافه کنید
- در کاوشگر پروژه، روی Android > app > res > values کلیک کنید و فایل
strings.xml
را باز کنید. - خطوط زیر را بعد از
<string name="title_activity_maps">Map</string>
اضافه کنید:
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>
هنگامی که فضایی برای اضافه کردن یک برچسب متنی در کنار نماد وجود دارد، از خط اول در نوار برنامه استفاده میشود. بقیه برای نشانگرهایی که به نقشه اضافه می کنید استفاده می شود.
حالا کد داخل فایل به شکل زیر است:
<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>
نوار برنامه را اضافه کنید
- در کاوشگر پروژه، روی Android > app کلیک کنید، سپس روی پوشه
res
کلیک راست کرده و New > Directory را انتخاب کنید تا یک زیر شاخه جدید درapp/src/main/res
ایجاد کنید. -
menu
فهرست را نامگذاری کنید. - روی پوشه
menu
کلیک راست کرده و New > File را انتخاب کنید. - نام فایل را
menu.xml
. - در این کد قرار دهید:
menu.xml
<?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>
سبک نوار برنامه را به روز کنید
- در کاوشگر پروژه، Android >
app
>res
>values
گسترش دهید و فایلstyles.xml
را در داخل باز کنید. - در تگ
<style>
، ویژگی والد را به عنوان"Theme.AppCompat.NoActionBar"
ویرایش کنید. - به ویژگی
name
که در مرحله بعد از آن استفاده می کنید توجه کنید.
styles.xml
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
تم برنامه را در AndroidManifest.xml به روز کنید
- روی Android >
app
>manifests
کلیک کنید و فایلAndroidManifest.xml
را باز کنید. - خط
android:theme
را پیدا کنید و مقدار را به@style/AppTheme
ویرایش یا تأیید کنید.
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">
اکنون آماده شروع کدنویسی هستید!
9. برنامه را راه اندازی کنید
- در کاوشگر پروژه خود، فایل
MapsActivity.java
را پیدا کنید.
این در پوشه مربوط به بسته ای است که برای برنامه خود در مرحله 1 ایجاد کرده اید.
- فایل را باز کنید و در ویرایشگر کد جاوا هستید.
Places SDK و سایر وابستگی ها را وارد کنید
این خطوط را در بالای MapsActivity.java
کنید، و جایگزین دستورات واردات موجود شوید.
آنها واردات موجود را در بر می گیرند و بسیاری از موارد مورد استفاده در کدهای این کد را اضافه می کنند.
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;
امضای کلاس را به روز کنید
Places API از اجزای AndroidX برای پشتیبانی سازگار با عقب استفاده می کند، بنابراین باید آن را برای گسترش AppCompatActivity
تعریف کنید. جایگزین پسوند FragmentActivity
می شود که به طور پیش فرض برای یک فعالیت نقشه تعریف شده است.
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
اضافه کردن متغیرهای کلاس
سپس، متغیرهای کلاس مختلف مورد استفاده در متدهای کلاس مختلف را اعلام کنید. اینها شامل عناصر UI و کدهای وضعیت هستند. اینها باید درست زیر اعلان متغیر برای GoogleMap mMap
باشند.
// 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 را به روز کنید
باید روش onCreate
را بهروزرسانی کنید تا مجوزهای کاربر در زمان اجرا برای سرویسهای مکان، راهاندازی عناصر UI و ایجاد کلاینت Places API را مدیریت کنید.
خطوط کد زیر را در رابطه با نوار ابزار اقدام، تنظیمات views و سرویس گیرنده Places به انتهای onCreate()
موجود اضافه کنید.
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);
}
کد را برای منوی نوار برنامه خود اضافه کنید
این دو روش منوی نوار برنامه را اضافه میکنند (با یک آیتم، نماد Pick Place) و کلیک کاربر روی نماد را کنترل میکنند.
این دو روش را بعد از onCreate
در فایل خود کپی کنید.
MapsActivity.java onCreateOptionsMenu() و 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);
}
}
امتحانش کن
- از Android Studio، روی Run یا Run menu > Run 'app' کلیک کنید.
- از شما خواسته می شود که هدف استقرار خود را انتخاب کنید. شبیه ساز در حال اجرا باید در این لیست ظاهر شود. آن را انتخاب کنید و Android Studio برنامه را برای شما در شبیه ساز مستقر می کند.
پس از چند لحظه، برنامه راه اندازی می شود. نقشه را در مرکز سیدنی، استرالیا، با دکمه واحد و لیست مکانهای خالی مشاهده میکنید.
تمرکز نقشه به مکان کاربر منتقل نمی شود مگر اینکه برای دسترسی به مکان دستگاه درخواست مجوز کنید.
10. درخواست و رسیدگی به مجوزهای مکان
پس از آماده شدن نقشه، مجوزهای مکان را درخواست کنید
- روشی به نام
getLocationPermission
تعریف کنید که مجوزهای کاربر را درخواست می کند.
این کد را در زیر متد onOptionsSelected
که ایجاد کرده اید قرار دهید.
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);
}
}
- برای فعال کردن کنترلهای بزرگنمایی و درخواست مجوزهای مکان از کاربر، دو خط به انتهای روش موجود
onMapReady
اضافه کنید.
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();
}
نتیجه مجوزهای درخواستی را مدیریت کنید
هنگامی که کاربر به گفتگوی مجوز درخواست پاسخ می دهد، این تماس توسط Android فراخوانی می شود.
این کد را بعد از متد getLocationPermission()
قرار دهید:
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. مکان فعلی را دریافت کنید و مکانهای احتمالی را واکشی کنید
هنگامی که کاربر بر روی Pick Place در نوار برنامه کلیک می کند، برنامه متد pickCurrentPlace() را فراخوانی می کند که متد pickCurrentPlace()
getDeviceLocation()
که قبلاً تعریف کرده اید فراخوانی می کند. متد getDeviceLocation
پس از بازیابی آخرین مکان دستگاه، روش دیگری به نام getCurrentPlaceLikelihoods,
را فراخوانی می کند.
با findCurrentPlace API تماس بگیرید و پاسخ را مدیریت کنید
getCurrentPlaceLikelihoods
یک findCurrentPlaceRequest
می سازد و Places API را findCurrentPlace
می کند. اگر کار موفقیت آمیز باشد، findCurrentPlaceResponse
را برمی گرداند که حاوی لیستی از اشیاء placeLikelihood
است. هر کدام از اینها تعدادی ویژگی دارند، از جمله نام و آدرس مکان، و احتمال اینکه شما در آن مکان هستید (مقدار دو برابر از 0 تا 1). این روش پاسخ را با ساخت لیستی از جزئیات مکان از placeLikelihoods
می کند.
این کد در پنج مکان محتملتر تکرار میشود و مواردی که احتمال رنده آنها بیشتر از 0 است را به فهرستی اضافه میکند که سپس نمایش داده میشود. اگر می خواهید بیشتر یا کمتر از پنج نمایش داده شود، ثابت M_MAX_ENTRIES
را ویرایش کنید.
این کد را بعد از متد onMapReady
قرار دهید.
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());
}
}
}
});
}
دوربین نقشه را به مکان فعلی دستگاه منتقل کنید
اگر کاربر اجازه دهد، برنامه آخرین مکان کاربر را واکشی میکند و دوربین را به مرکز آن مکان میبرد.
اگر کاربر اجازه را رد کند، برنامه به سادگی دوربین را به مکان پیش فرض تعریف شده در بین ثابت های ابتدای این صفحه (در کد نمونه، سیدنی، استرالیا) منتقل می کند.
این کد را بعد از getPlaceLikelihoods()
:
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());
}
}
هنگامی که کاربر بر روی انتخاب مکان کلیک می کند، مجوزهای مکان را بررسی کنید
هنگامی که کاربر بر روی " انتخاب مکان " ضربه میزند، این روش مجوزهای مکان را بررسی میکند و در صورت عدم اعطای مجوز از کاربر درخواست میکند.
اگر کاربر اجازه داده باشد، متد getDeviceLocation
را فراخوانی میکند تا فرآیند دریافت مکانهای احتمالی فعلی را آغاز کند.
- این متد را بعد از
getDeviceLocation()
اضافه کنید:
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();
}
}
- اکنون که
pickCurrentPlace
تعریف شده است، خطی را درonOptionsItemSelected()
بیابید کهpickCurrentPlace
را فراخوانی می کند و آن را از نظر خارج کنید.
MapsActivity.java onOptionItemSelected()
case R.id.action_geolocate:
// COMMENTED OUT UNTIL WE DEFINE THE METHOD
// Present the Current Place picker
pickCurrentPlace();
return true;
امتحانش کن
اگر اکنون برنامه را اجرا کنید و روی « انتخاب مکان » ضربه بزنید، باید مجوزهای مکان را درخواست کند.
- اگر اجازه دهید، آن اولویت ذخیره میشود و از شما خواسته نمیشود. اگر مجوز را رد کنید، دفعه بعد که روی دکمه ضربه می زنید از شما خواسته می شود.
- اگرچه
getPlaceLikelihoods
مکان های احتمالی فعلی را دریافت کرده است،ListView
هنوز آنها را نمایش نمی دهد. در Android Studio، میتوانید روی ⌘6 کلیک کنید تا گزارشهای Logcat را برای عباراتی که دارای برچسب MapsActivity هستند بررسی کنید تا مطمئن شوید که روشهای جدید شما به درستی کار میکنند. - اگر مجوز داده اید، گزارش ها شامل یک عبارت برای
Latitude:
و یک بیانیه برایLongitude:
مکان شناسایی شده دستگاه را نشان می دهد. اگر قبلاً از Google Maps و منوی توسعهیافته شبیهساز برای تعیین مکانی برای شبیهساز استفاده کردهاید، این عبارات آن مکان را نشان میدهند. - اگر فراخوانی برای
findCurrentPlace
موفقیت آمیز بود، گزارش ها شامل پنج عبارت است که نام و مکان پنج مکان محتمل را چاپ می کند.
12. انتخابگر مکان فعلی را پر کنید
یک کنترل کننده برای مکان های انتخاب شده تنظیم کنید
بیایید به این فکر کنیم که وقتی کاربر روی یک مورد در ListView
کلیک میکند، میخواهیم چه اتفاقی بیفتد. برای تأیید انتخاب کاربر در مورد مکانی که در حال حاضر در آن قرار دارد، می توانید یک نشانگر به نقشه آن مکان اضافه کنید. اگر کاربر روی آن نشانگر کلیک کند، یک پنجره اطلاعاتی ظاهر می شود که نام مکان و آدرس را نشان می دهد.
این کنترل کننده کلیک را بعد از متد pickCurrentPlace
قرار دهید.
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 را پر کنید
اکنون که فهرست محتملترین مکانهایی را دارید که کاربر در حال حاضر از آنها بازدید میکند، میتوانید آن گزینهها را در ListView
به کاربر ارائه دهید. همچنین می توانید شنونده کلیک ListView
را برای استفاده از کنترل کننده کلیکی که به تازگی تعریف کرده اید تنظیم کنید.
این روش را بعد از کنترل کننده کلیک قرار دهید:
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
تعریف شده است، خط انتهای findPlaceLikelihoods
را پیدا کنید که fillPlacesList
را فراخوانی می کند و آن را از نظر خارج کنید.
MapsActivity.java fillPlaceLikelihoods()
// COMMENTED OUT UNTIL WE DEFINE THE METHOD
// Populate the ListView
fillPlacesList();
این تمام کد مورد نیاز برای انتخاب کننده مکان فعلی است!
13. برنامه را اجرا کنید
تست انتخاب مکان
- دوباره برنامه را اجرا کنید.
این بار وقتی روی « انتخاب مکان » ضربه میزنید، برنامه فهرست را با مکانهای نامگذاری شده نزدیک به مکان پر میکند. در نزدیکی این مکان در مائوئی، مکانهایی مانند یخهای هاوایی Shave Ice و Sugar Beach Bake Shop Ululani وجود دارد. از آنجایی که چندین مکان به مختصات مکان بسیار نزدیک هستند، این لیستی از مکانهای احتمالی است که ممکن است در آن باشید.
- روی نام مکان در
ListView
.
شما باید یک نشانگر اضافه شده به نقشه را ببینید.
- روی نشانگر ضربه بزنید.
می توانید جزئیات مکان را ببینید.
مکان دیگری را تست کنید
اگر میخواهید مکان خود را تغییر دهید و از شبیهساز استفاده میکنید، وقتی مختصات مکان را در منوی توسعهیافته شبیهساز بهروزرسانی میکنید، مکان دستگاه بهطور خودکار بهروزرسانی نمیشود.
برای رفع این مشکل، این مراحل را دنبال کنید تا از برنامه بومی Google Maps برای بهروزرسانیهای مکان شبیهساز استفاده کنید:
- Google Maps را باز کنید.
- برای تغییر طول و عرض جغرافیایی به مختصات جدید روی ... > مکان ضربه بزنید، سپس روی ارسال ضربه بزنید.
- به عنوان مثال، می توانید از Latitude: 49.2768 و Longitude: -123.1142 برای تنظیم مکان در مرکز شهر ونکوور، کانادا استفاده کنید.
- بررسی کنید که Google Maps مختصات جدید شما را تازهسازی کرده است. ممکن است لازم باشد روی دکمه موقعیت مکانی من در برنامه Google Maps ضربه بزنید تا دوباره درخواست کنید.
- به برنامه مکان فعلی خود برگردید و روی انتخاب مکان ضربه بزنید تا نقشه را روی مختصات جدید دریافت کنید و لیست جدیدی از مکانهای احتمالی فعلی را ببینید.
و بس! شما یک برنامه ساده ساخته اید که مکان های موجود در مکان فعلی را بررسی می کند و به شما امکان می دهد در کدام مکان هستید. لذت بردن!
حالا پیش بروید و برنامه را با تغییراتی که برای تکمیل این مرحله جایزه انجام دادید اجرا کنید!
14. مراحل بعدی
برای جلوگیری از سرقت کلید API خود، باید آن را ایمن کنید تا فقط برنامه اندروید شما بتواند از کلید استفاده کند. اگر بدون محدودیت باقی بماند، هر کسی که کلید شما را داشته باشد میتواند از آن برای تماس با APIهای پلتفرم Google Maps استفاده کند و باعث شود صورتحساب دریافت کنید.
گواهی SHA-1 خود را دریافت کنید
بعداً وقتی کلیدهای API خود را محدود می کنید به این نیاز خواهید داشت. در زیر مجموعه ای از دستورالعمل ها برای دریافت گواهی اشکال زدایی آمده است.
برای لینوکس یا macOS، یک پنجره ترمینال را باز کنید و موارد زیر را وارد کنید:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
برای ویندوز ویستا و ویندوز 7، دستور زیر را اجرا کنید:
keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
شما باید خروجی مشابه این را ببینید:
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 شروع می شود حاوی اثر انگشت SHA-1 گواهی است. اثر انگشت دنباله ای از 20 عدد هگزادسیمال دو رقمی است که با دو نقطه از هم جدا شده اند.
هنگامی که آماده انتشار یک برنامه هستید، از دستورالعمل های این اسناد برای بازیابی گواهی انتشار خود استفاده کنید.
محدودیت هایی را به کلید API خود اضافه کنید
- در Cloud Console، به APIs & Services > Credentials بروید.
کلیدی که برای این برنامه استفاده کردید باید در زیر کلیدهای API فهرست شود.
- کلیک
برای ویرایش تنظیمات کلیدی
- در صفحه کلید API، پس از کلید محدودیت ها ، محدودیت های برنامه را با انجام موارد زیر تنظیم کنید:
- برنامه های اندروید را انتخاب کنید و دستورالعمل ها را دنبال کنید.
- روی افزودن یک مورد کلیک کنید.
- نام بسته و اثر انگشت گواهی SHA-1 خود را وارد کنید (بازیابی شده در بخش قبلی).
مثلا:
com.google.codelab.currentplace
BB:0D:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:75s
- برای محافظت بیشتر، محدودیت های API را با انجام موارد زیر تنظیم کنید.
- پس از محدودیتهای API، Restrict key را انتخاب کنید.
- Maps SDK for Android and Places API را انتخاب کنید.
- روی Done و Save کلیک کنید.
15. تبریک می گویم
شما یک برنامه ساده ساختهاید که محتملترین مکانها را در مکان فعلی بررسی میکند و نشانگر مکانی را که کاربر انتخاب میکند به نقشه اضافه میکند.
بیشتر بدانید
- برای تسریع در توسعه، از Maps SDK for Android Utility Library استفاده کنید. این ابزارها وظایف سنگینی را برای برخی از محبوبترین وظایف برنامهها با استفاده از پلتفرم نقشههای Google انجام میدهند.
- برای نمونه کدهای بیشتر که بیشتر ویژگیهای SDKهای پلتفرم Google Maps برای Android را نشان میدهند، مخازن را برای Maps SDK برای نمونههای Android و Places SDK برای نسخههای نمایشی Android شبیهسازی کنید.
- برای یادگیری نحوه مدیریت مجوزهای موقعیت مکانی سه حالته در Android Q، بهروزرسانیهای موقعیت مکانی را در Android با Codelab Kotlin دریافت کنید.