מידע על Codelab זה
1. לפני שמתחילים
ניתן ללמוד איך להשתמש ב-SDK של מפות Google וב-SDK ל-Android כדי להציג למשתמשים רשימה של מקומות כדי לזהות את המיקומים הנוכחיים שלהם.
דרישות מוקדמות
- מיומנויות Java בסיסיות
הפעולות שתבצעו:
- הוספת מפה לאפליקציה ל-Android.
- השתמשו בהרשאות המיקום כדי למקם את המשתמש במיקום גיאוגרפי.
- אחזור מקומות ליד המיקום הנוכחי של המשתמש.
- להציג למשתמש כנראה את 'מקומות' כדי לזהות את המיקום הנוכחי שלו.
מה תפתחו
אתם בונים את אפליקציית Android מההתחלה, אבל אפשר להוריד את הקוד לדוגמה להשוואה במהלך ניפוי באגים. מורידים את הקוד לדוגמה מ-GitHub. אם GitHub מוגדר לשימוש בשורת הפקודה, מזינים את הפרטים הבאים:
git clone https://github.com/googlecodelabs/current-place-picker-android.git
אם תיתקלו בבעיות (באגים בקוד, שגיאות דקדוק, ניסוח לא ברור או משהו אחר) כשתתבצעו באמצעות קוד Lab זה, דווחו על הבעיה באמצעות הקישור דיווח על שגיאה בפינה הימנית התחתונה של שיעור הקוד.
2. שנתחיל?
לפני שמתחילים במעבדה זו, צריך להגדיר את הדברים הבאים:
Android Studio
מורידים את Android Studio מהכתובת https://developer.android.com/studio.
אם כבר יש לכם Android Studio, מוודאים שיש לכם את הגרסה העדכנית ביותר. לשם כך, לוחצים על Android Studio > בודקים אם יש עדכונים....
שיעור ה-Lab הזה נכתב באמצעות Android Studio 3.4.
Android SDK
ב-Android Studio, אפשר להגדיר את ערכות ה-SDK הרצויות באמצעות מנהל ה-SDK. בשיעור Lab זה נעשה שימוש ב-Android Q SDK.
- במסך הפתיחה של Android Studio, לוחצים על הגדרה > מנהל SDK.
- מסמנים את תיבת הסימון הרצויה ל-SDK ולוחצים על אישור.
אם עדיין אין לכם את ה-SDK, הפעולה הזו תתחיל להוריד את ה-SDK למכשיר.
שירותי Google Play
מתוך מנהל ה-SDK, צריך גם להתקין את שירותי Google Play.
- לוחצים על הכרטיסייה SDK SDK ובוחרים בתיבת הסימון Google Play Services.
מעדכנים אם הסטטוס הוא עדכון זמין.
3. הכנת האמולטור
כדי להפעיל את האפליקציה, יש לך אפשרות לחבר מכשיר משלך או להשתמש באמולטור של Android.
אם אתם משתמשים במכשיר משלכם, דלגו אל הוראות למכשיר המציאותי: מעדכנים את שירותי Google Play בסוף הדף הזה.
הוספת אמולטור
- במסך הפתיחה של Android Studio, לוחצים על הגדרה &ניהול AVD.
פעולה זו תפתח את תיבת הדו-שיח של ניהול מכשיר וירטואלי של Android.
- לוחצים על יצירת מכשיר וירטואלי... כדי לפתוח רשימה של מכשירים לבחירה.
- בוחרים מכשיר עם סמל Play
בעמודה חנות Play ולוחצים על הבא.
תופיע קבוצה של תמונות מערכת שניתן להתקין. אם המילה Q מטרגטת ל-Android 9.+ (Google Play) ולצידה יש המילה הורדה, לוחצים על הורדה.
- לוחצים על הבא כדי לתת שם למכשיר הווירטואלי, ולאחר מכן לוחצים על סיום.
חוזרים לרשימה של המכשירים הווירטואליים.
- לוחצים על 'התחלה'
לצד המכשיר החדש:
אחרי כמה דקות, האמולטור ייפתח.
הוראות אמולטור – עדכון שירותי Google Play
- לאחר האמולטור מופעל, לוחצים על ... בסרגל הניווט שמופיע**.**
תיפתח תיבת דו-שיח של פקדים מורחבים.
- לוחצים על Google Play בתפריט.
אם יש עדכון זמין, לוחצים על עדכון.
- יש להיכנס לאמולטור באמצעות חשבון Google.
אתם יכולים להשתמש בחשבון משלכם או ליצור חשבון חדש בחינם כדי להפריד בין הבדיקות שלכם לבין המידע האישי.
לאחר מכן Google Play נפתחת לשירותי Google Play.
- לוחצים על עדכון כדי להוריד את הגרסה האחרונה של שירותי Google Play.
אם מתבקשים להשלים את הגדרת החשבון ולהוסיף אפשרות תשלום, לוחצים על דילוג.
הגדרת מיקום באמולטור
- אחרי האמולטור, מקלידים "maps" בסרגל החיפוש שבמסך הבית כדי להציג את הסמל של אפליקציית מפות Google.
- יש ללחוץ על הסמל כדי להפעיל.
תופיע מפת ברירת המחדל.
- בפינה השמאלית התחתונה של המפה, לוחצים על המיקום שלך
.
עליך להעניק לטלפון הרשאות לשימוש במיקום.
- לוחצים על ... כדי לפתוח את תפריט פקדים מורחבים.
- לחץ על הכרטיסייה מיקום.
- מזינים קו אורך וקו רוחב.
כאן מזינים את כל מה שרוצים, אבל כדאי להקפיד למקם אותו באזור שיש בו הרבה מקומות.
(השתמשו ב-Latitude 20.7818 ובקו האורך -156.4624 עבור העיר Kihei במאוואי בהוואי כדי לשכפל את התוצאות ממעבדה זו.)
- לוחצים על שליחה והמפה מתעדכנת עם המיקום הזה.
אתם מוכנים להריץ את האפליקציה ולבדוק אותה עם מיקום.
הוראות למכשירים אמיתיים – עדכון השירותים של Google Play
אם אתם משתמשים במכשיר Android אמיתי, יש לבצע את הפעולות הבאות:
- בסרגל החיפוש שבמסך הבית, מחפשים את שירותי Google Play ופותחים אותם.
- לוחצים על פרטים נוספים.
אם האפשרות זמינה, לוחצים על עדכון.
4. יצירת מעטפת אפליקציה באמצעות פעילות במפות Google
- במסך הפתיחה של Android Studio בוחרים באפשרות התחלת פרויקט חדש ב-Android Studio.
- בכרטיסייה טלפון וטאבלט, בוחרים באפשרות פעילות במפות Google.
תיבת הדו-שיח הגדרת הפרויקט שלך תיפתח. כאן נותנים שם לאפליקציה ויוצרים את החבילה על סמך הדומיין שלכם.
אלה ההגדרות של אפליקציה בשם 'מקום נוכחי', שתואמת לחבילה com.google.codelab.currentplace
.
- בוחרים באפשרות Java בתור השפה ובוחרים באפשרות שימוש באובייקטים מסוג androidx.*
להשאיר את ברירות המחדל בשאר ההגדרות.
- לוחצים על סיום.
5. הוספת יחסי תלות של שירותי Google לקובץ ה-build של Gradle
כדי לגשת להרשאות מיקום ב-Android, צריך ממשק API של Google לזיהוי מיקום ופעילות ב-Google Play. מידע נוסף על הוספת ה-API הזה ועוד ממשקי API של שירותי Google Play זמין במאמר הגדרת Google Play Services.
פרויקטים ב-Android Studio כוללים בדרך כלל שני קובצי build.gradle
. אחד מהם מיועד לפרויקט בסך הכול ואחד מיועד לאפליקציה. אם כלי המחקר של Android Studio מוצג בתצוגת Android, שניהם יוצגו בתיקייה Gradle Scripts
. כדי להוסיף את שירותי Google צריך לערוך את הקובץ build.gradle (Module: app)
.
- מוסיפים שתי שורות לקטע
dependencies
כדי להוסיף את שירותי Google למיקום ואת ממשק ה-API של 'מקומות' (בקוד לדוגמה בהקשר).
build.gradle (מודול: 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. הפעלת ממשקי API של מפות Google וקבלת מפתח API
לשלב ההפעלה הבא , יש להפעיל את Maps SDK ל-Android ואת Place API.
הגדרת מפות Google
אם עדיין אין לכם חשבון Google Cloud Platform ופרויקט שבו מופעל חיוב, כדאי לעיין במדריך תחילת העבודה עם הפלטפורמה של מפות Google ליצירת חשבון לחיוב ופרויקט.
- ב-Cloud Console, לוחצים על התפריט הנפתח של הפרויקט ובוחרים את הפרויקט שבו רוצים להשתמש ב-Codelab הזה.
- מפעילים את ממשקי ה-API ואת ערכות ה-SDK של מפות Google הנדרשים למעבדת קוד זו ב-Google Cloud Marketplace. כדי לעשות זאת, יש לבצע את השלבים המפורטים בסרטון הזה או בתיעוד הזה.
- יוצרים מפתח API בדף פרטי הכניסה ב-Cloud Console. ניתן לבצע את השלבים המפורטים בסרטון הזה או בתיעוד הזה. לכל הבקשות שנשלחות לפלטפורמה של מפות Google נדרש מפתח API.
מעתיקים את מפתח ה-API שיצרתם. חוזרים אל Android Studio ומחפשים את הקובץ google_maps_api.xml
בקטע Android > app > re; g;
יש להחליף את YOUR_KEY_HERE
במפתח ה-API שהעתקת.
האפליקציה שלך מוגדרת עכשיו.
7. עריכה של קובץ הפריסה
- בסייר הפרויקטים שלך, פתח את הקובץ
activity_maps.xml
ב-Android & gt;app
>res
>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 >. אפליקציה, לוחצים לחיצה ימנית על התיקייה res ובוחרים באפשרות חדש >. נכס תמונה.
Studio Studio ייפתח.
- בתפריט סוג סמל, לוחצים על סמלים של סרגל הפעולות והכרטיסיות.
- נותנים שם לנכס
ic_geolocate
. - בוחרים באפשרות קליפ ארט כסוג הנכס**.**
- לוחצים על הגרפיקה לצד קליפ ארט.
פעולה זו תפתח את החלון Select Icon.
- בוחרים סמל.
אתם יכולים להשתמש בסרגל החיפוש כדי למצוא סמלים הקשורים לכוונה שלכם.
- חפשו את
location
ובחרו סמל הקשור למיקום.
הסמל המיקום שלי זהה לסמל שבו נעשה שימוש באפליקציית מפות Google כשמשתמש רוצה להצמיד את המצלמה למיקום הנוכחי שלו.
- לוחצים על אישור > הבא > סיום ומוודאים שיש תיקייה חדשה בשם
drawable
שמכילה את קובצי הסמל החדשים.
הוספה של משאבי מחרוזת
- בסייר הפרויקטים, לוחצים על Android > app > res > ערכים ופותחים את הקובץ
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 > אפליקציה, לוחצים לחיצה ימנית על התיקייה
res
ובוחרים באפשרות חדש >. ספרייה כדי ליצור ספריית משנה חדשה בקטעapp/src/main/res
. - יש לתת שם לספרייה
menu
. - לחץ לחיצה ימנית על התיקייה
menu
ובחר חדש > קובץ. - שם הקובץ
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.
- פותחים את הקובץ &בעורך הקוד של Java.
ייבוא של SDK ותלויים אחרים של מקומות
יש להוסיף את השורות האלה בחלק העליון של MapsActivity.java
, ולהחליף את הצהרות הייבוא הקיימות.
הם כוללים את הייבוא הקיים ומוסיפים עוד הרבה קוד בקוד במעבדה זו.
MapsActivity.JavaScript
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;
עדכון חתימת הכיתה
ממשק ה-API של 'מקומות' משתמש ברכיבי AndroidX עבור תמיכה תואמת, כך שצריך להגדיר אותו כדי להרחיב את AppCompatActivity
. הוא מחליף את התוסף FragmentActivity
המוגדר כברירת מחדל לפעילות במפות.
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
הוספת משתנים של הכיתה
בשלב הבא, יש להצהיר על משתני הכיתה השונים המשמשים בשיטות כיתה שונות. רכיבים אלה כוללים את רכיבי ממשק המשתמש ואת קודי הסטטוס. הערכים האלה צריכים להיות מתחת להצהרת המשתנה של 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
כדי לטפל בהרשאות המשתמש בזמן ריצה עבור שירותי מיקום, להגדיר את רכיבי ממשק המשתמש וליצור לקוח API של מקומות.
מוסיפים את שורות הקוד הבאות לגבי סרגל הכלים של הפעולה, הגדרת הצפיות והלקוח של מקומות עד סוף השיטה הקיימת של onCreate()
.
MapsActivity.JavaScript 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);
}
הוספת קוד לתפריט סרגל האפליקציות
שתי השיטות האלה מוסיפות את תפריט סרגל האפליקציות (עם פריט אחד, הסמל של בחירת מקום) ומטפלות בלחיצה על הסמל של המשתמש.
מעתיקים את שתי השיטות האלה לקובץ אחרי השיטה onCreate
.
MapsActivity.JavaScript ב-CreateOptionsMenu() ו-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, לוחצים על הפעלה או על הפעלת התפריט > הפעלת 'app'.
- אתם מתבקשים לבחור את יעד הפריסה. האמולטור הפעיל אמור להופיע ברשימה הזו. בוחרים אותו, ו-Android Studio יפרס עבורכם את האפליקציה לאמולטור.
אחרי כמה דקות האפליקציה תושק. אתם רואים את המפה שבמרכזה סידני, אוסטרליה, עם לחצן יחיד ורשימת מקומות שאינם מאוכלסים.
המיקוד של המפה לא עובר למיקום של המשתמש אלא אם ביקשת הרשאת גישה למיקום של המכשיר.
10. בקשת הרשאות מיקום וטיפול בהן
בקשת הרשאות מיקום אחרי שהמפה מוכנה
- יש להגדיר שיטה בשם
getLocationPermission
שמבקשת הרשאות משתמש.
יש להדביק את הקוד הזה מתחת לשיטה onOptionsSelected
שיצרת עכשיו.
MapsActivity.JavaScript 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.JavaScript ב-MapReady()
@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.JavaScript onRequestRequestResult()
/**
* 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. קבלת המיקום הנוכחי ואחזור של מקומות משוערים
כשהמשתמש לוחץ על האפשרות בחירת מקום בסרגל האפליקציות, האפליקציה מפעילה את השיטה pickCurrentPlace()
שנקראת השיטה getDeviceLocation()
. השיטה getDeviceLocation
מתקשרת לשיטה אחרת, getCurrentPlaceLikelihoods,
אחרי אחזור של מיקום המכשיר האחרון.
התקשרו ל-FindCurrentPlace API וטיפול בתגובה
האפליקציה getCurrentPlaceLikelihoods
יוצרת את findCurrentPlaceRequest
ומגדירה את משימת API של מקומות findCurrentPlace
. אם המשימה מצליחה, היא מחזירה findCurrentPlaceResponse
, שמכיל רשימה של אובייקטים מסוג placeLikelihood
. לכל אחד מהם יש מספר מאפיינים, כולל השם והכתובת של המקום, והסבירות שאתם נמצאים באותו מקום (ערך כפול מ-0 עד 1). שיטה זו מטפלת בתגובה על ידי יצירת רשימות של פרטי מקומות מה-placeLikelihoods
.
קוד זה חוזר על פני חמשת המקומות בעלי הסבירות הגבוהה ביותר ומוסיף מקומות עם סבירות גבוהה המגרדת מ-0 לרשימה שלאחר מכן מתבצע רינדור. אם ברצונך להציג יותר או פחות מ-5, עליך לערוך את הקבוע של M_MAX_ENTRIES
.
יש להדביק את הקוד הזה אחרי השיטה onMapReady
.
MapsActivity.JavaScript getCurrentPlaceLikeliities()
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.JavaScript 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.JavaScript selectCurrentPlace()
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.JavaScript 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 עבור דוחות שתויגו במפות פעילות כדי לוודא שהשיטות החדשות פועלות כראוי. - אם הענקת הרשאה, היומנים כוללים הצהרה עבור
Latitude:
והצהרה עבורLongitude:
שבה מופיע המיקום של המכשיר. אם השתמשתם במפות Google ובאמולטור המורחב של התפריט לאמולטור כדי לציין מיקום לאמולטור, הביטויים האלה מציגים את המיקום. - אם הקריאה אל
findCurrentPlace
בוצעה בהצלחה, היומנים מכילים חמישה הצהרות מודפסות עם השמות והמיקומים של חמשת המקומות בעלי הסיכוי הגבוה ביותר.
12. אכלס את בוחר המקום הנוכחי
הגדרת handler של מקומות נבחרים
יש לנו שאלה לגבי מה שאנחנו רוצים לעשות כשהמשתמש לוחץ על פריט ב-ListView
. כדי לאשר את בחירת המשתמש לגבי המקום שבו הוא נמצא כעת, ניתן להוסיף סמן למפה במקום זה. אם המשתמש לוחץ על הסמן הזה, ייפתח חלון מידע שמציג את שם הכתובת ואת הכתובת.
יש להדביק את ה-handler של הקליק אחרי השיטה pickCurrentPlace
.
MapsActivity.JavaScript 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
. אפשר גם להגדיר את event listener של ListView
לשימוש ב-handler של הקליקים שהגדרת עכשיו.
יש להדביק את השיטה הזו אחרי רכיב ה-handler של קליקים:
MapsActivity.JavaScriptfillplacesList()
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.JavaScript
// COMMENTED OUT UNTIL WE DEFINE THE METHOD
// Populate the ListView
fillPlacesList();
זה כל הקוד הדרוש לבוחר המקום הנוכחי!
13. הפעלת האפליקציה
בדיקה של בחירת מקום
- מפעילים שוב את האפליקציה.
הפעם כשמקישים על בחירת מקום, האפליקציה מאכלסת את הרשימה במקומות קרובים בשם המיקום. בקרבת מקום זה במאווי, שוכנים מקומות כמו אולאני' קרחון הוואי וחנות מאפים בחוף הסוכר. מכיוון שמספר המקומות קרובים מאוד לקואורדינטות של המיקום, זו רשימה של מקומות שסביר להניח שתהיה בהם.
- יש ללחוץ על שם של מקום ב
ListView
.
אמור להופיע סמן שנוסף למפה.
- מקישים על הסמן.
ניתן לראות פרטי מקום.
בדיקת מיקום אחר
אם ברצונך לשנות את המיקום שלך ולהשתמש באמולטור, מיקום המכשיר לא מתעדכן באופן אוטומטי כאשר מעדכנים את קואורדינטות המיקום בתפריט המורחב של האמולטור.
כדי לעקוף את הבעיה, צריך לבצע את השלבים הבאים כדי להשתמש באפליקציית 'מפות Google' המקורית כדי לאלץ עדכונים במיקום של האמולטור:
- פתח את 'מפות Google'.
- מקישים על ... > מיקום כדי לשנות את קווי הרוחב והאורך לקואורדינטות חדשות, ואז מקישים על שליחה.
- לדוגמה, ניתן להשתמש בקווי רוחב: 49.2768 וקו אורך: -123.1142 כדי להגדיר את המיקום בדאונטאון של ונקובר, קנדה.
- מוודאים שהאפליקציה מפות Google עברה לאחרונה את הקואורדינטות החדשות שלכם. ייתכן שיהיה צורך להקיש על הלחצן המיקום שלי באפליקציה מפות Google כדי לבקש מרכוז.
- חוזרים לאפליקציה 'מקום נוכחי' ומקישים על בחירת מקום כדי לקבל את המפה בקואורדינטות החדשות ולהציג רשימה חדשה של מקומות שקרובים כרגע.
זהו, סיימתם. יצרתם אפליקציה פשוטה שבודקת את המקומות במיקום הנוכחי שלכם. כך אתם יכולים לדעת באילו מהם אתם נמצאים. צפייה מהנה!
עכשיו הגיע הזמן להפעיל את אפליקציית ההרצה עם השינויים שביצעת כדי להשלים את שלב הבונוס הזה!
14. השלבים הבאים
כדי למנוע גניבה של מפתח ה-API, צריך לאבטח אותו כך שרק האפליקציה ל-Android תוכל להשתמש במפתח הזה. אם המפתח לא מוגבל, כל מי שיש לו את המפתח יכול להשתמש בו כדי להתקשר לממשקי ה-API של מפות Google ולגרום לחיובים.
קבלת אישור SHA-1
הפעולה נדרשת מאוחר יותר כשמגבילים את מפתחות ה-API. בהמשך מפורטות הוראות לקבלת אישור ניפוי הבאגים.
ב-Linux או ב-macOS, פותחים חלון מסוף ומזינים את הפרטים הבאים:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
ל-Windows Vista ו-Windows 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, אחרי המגבלות העיקריות, מגדירים את ההגבלות על האפליקציות כך:
- בוחרים באפשרות אפליקציות ל-Android ופועלים לפי ההוראות.
- לוחצים על הוספת פריט.
- יש להזין את שם החבילה ואת טביעת האצבע של אישור 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, בוחרים באפשרות הגבלת מפתח.
- בוחרים ב-SDK של מפות Google ל-Android ול-places API.
- לוחצים על סיום ועל שמירה.
15. מזל טוב
בניית אפליקציה פשוטה שבודקת את המקומות בעלי הסיכוי הגבוה ביותר להופיע במיקום הנוכחי ומוסיפה מפה למיקום שבו המשתמש בוחר.
מידע נוסף
- כדי להאיץ את ההתפתחות שלכם, השתמשו ב-Maps SDK for Android Utility Directory. הכלים האלה משרתים את חלק מהמשימות הפופולריות ביותר באפליקציות שמשתמשות בפלטפורמה של מפות Google.
- לקבלת דוגמאות נוספות לקוד שממחישות את רוב התכונות של ערכות ה-SDK של מפות Google ל-Android, מאגרי עותקים של דוגמאות ל-SDK של מפות Google ל-Android והדגמות של ערכות SDK ל-Android.
- כדי ללמוד איך לטפל בהרשאות מיקום תלת-מצביות ב-Android Q, משלימים את שיעור הקוד של קבלת עדכוני מיקום ב-Android עם Kotlin.