1. היי!
ה-codelab הזה הוא חלק מקורס ההדרכה Advanced Android Development שפותח על ידי צוות Google Developers Training. כדי להפיק את המרב מהקורס הזה, מומלץ לעבוד על ה-Codelabs לפי הסדר.
פרטים מלאים על הקורס זמינים במאמר סקירה כללית על פיתוח מתקדם ל-Android.
מבוא
פיתוח אפליקציות באמצעות מפות Google מאפשר לכם להוסיף לאפליקציה תכונות כמו תמונות לוויין, אמצעי בקרה חזקים בממשק המשתמש, מעקב אחר מיקום וסמני מיקום. אתם יכולים להוסיף ערך למפות Google הרגילות על ידי הצגת מידע ממערך הנתונים שלכם, כמו מיקומים של אזורים מוכרים לדיג או לטיפוס. אפשר גם ליצור משחקים שקשורים לעולם האמיתי, כמו Pokemon Go.
בשיעור המעשי הזה, תיצרו אפליקציה למפות Google בשם Wander.
מה שכדאי לדעת
חשוב שתכירו את:
- פונקציונליות בסיסית של מפות Google.
- הרשאות בזמן ריצה.
- יצירה, בנייה והרצה של אפליקציות ב-Android Studio.
- כולל ספריות חיצוניות בקובץ
build.gradle.
מה תלמדו
- שילוב של מפת Google באפליקציה.
- הצגת סוגים שונים של מפות.
- הגדרת סגנון למפת Google.
- מוסיפים סמנים למפה.
- מאפשרים למשתמש למקם סמן בנקודת עניין (POI).
- מפעילים את המעקב אחר המיקום.
- מפעילים את Google Street View.
הפעולות שתבצעו:
- מקבלים מפתח API מ-Google API Console ורושמים את המפתח באפליקציה.
- יוצרים את אפליקציית
Wander, שכוללת מפה מוטמעת של Google. - להוסיף לאפליקציה תכונות בהתאמה אישית, כמו סמנים, סגנון ומעקב מיקום.
- מפעילים את מעקב המיקום ואת Street View באפליקציה.
2. סקירה כללית של האפליקציה
בשיעור המעשי הזה תיצרו את אפליקציית Wander, שהיא מפה של Google עם סגנון. באפליקציית Wander אפשר להציב סמנים במיקומים, לראות את המיקום בזמן אמת ולצפות בתמונות פנורמיות של Street View.
|
|
3. משימה 1: הגדרת הפרויקט וקבלת מפתח API
כמו Places API, גם Google Maps API דורש מפתח API. כדי לקבל את מפתח ה-API, צריך לרשום את הפרויקט ב-Google API Console. מפתח ה-API קשור לאישור דיגיטלי שמקשר את האפליקציה ליוצר שלה. מידע נוסף על שימוש באישורים דיגיטליים ועל חתימה על האפליקציה זמין במאמר בנושא חתימה על האפליקציה.
בשלב המעשי הזה, משתמשים במפתח ה-API לאישור הניפוי באגים. אישור הניפוי באגים לא מאובטח מעצם הגדרתו, כפי שמתואר במאמר בנושא חתימה על גרסת build לניפוי באגים. אפליקציות ל-Android שפורסמו ומשתמשות ב-Google Maps API דורשות מפתח API שני: המפתח של אישור הפרסום. מידע נוסף על קבלת אישור הפצה זמין במאמר בנושא קבלת מפתח API.
Android Studio כולל תבנית של פעילות במפות Google, שמייצרת קוד תבנית שימושי. קוד התבנית כולל קובץ google_maps_api.xml שמכיל קישור שמפשט את קבלת מפתח API.
1.1 יצירת פרויקט Wander באמצעות תבנית של מפות
- יוצרים פרויקט חדש ב-Android Studio.
- נותנים לאפליקציה החדשה את השם Wander. מאשרים את הגדרות ברירת המחדל עד שמגיעים לדף הוספת פעילות.
- בוחרים בתבנית פעילות במפות Google.
- משאירים את שם הפעילות ושם הפריסה שמוגדרים כברירת מחדל.
- משנים את השם ל-Wander ולוחצים על סיום.
Android Studio יוצר כמה קבצים נוספים שקשורים למפות:
google_maps_api**.xml**
קובץ התצורה הזה משמש לאחסון מפתח ה-API. התבנית יוצרת שני קובצי google_maps_api.xml: אחד לניפוי באגים ואחד לפרסום. הקובץ של מפתח ה-API לאישור הניפוי באגים נמצא ב-src/debug/res/values. הקובץ של מפתח ה-API לאישור הגרסה נמצא בנתיב src/release/res/values. בשיעור המעשי הזה אנחנו משתמשים רק באישור לניפוי באגים.
activity_maps.xml
קובץ הפריסה הזה מכיל רכיב fragment יחיד שממלא את כל המסך. הסיווג SupportMapFragment הוא סיווג משנה של הסיווג Fragment. אפשר לכלול את SupportMapFragment בקובץ פריסה באמצעות תג <fragment> בכל ViewGroup, עם מאפיין נוסף:
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.java
קובץ MapsActivity.java יוצר מופע של המחלקה SupportMapFragment ומשתמש בשיטה getMapAsync() של המחלקה כדי להכין את מפת Google. הפעילות שמכילה את SupportMapFragment חייבת להטמיע את הממשק OnMapReadyCallback ואת השיטה onMapReady() של הממשק הזה. השיטה getMapAsync() מחזירה אובייקט GoogleMap, שמציין שהמפה נטענה.
1.2 קבלת מפתח ה-API
- פותחים את גרסת הניפוי של קובץ
google_maps_api.xml.
הקובץ כולל תגובה עם כתובת URL ארוכה. הפרמטרים של כתובת ה-URL כוללים מידע ספציפי על האפליקציה.
- מעתיקים את כתובת ה-URL ומדביקים אותה בדפדפן.
- פועלים לפי ההנחיות כדי ליצור פרויקט ב-Google API Console. בגלל הפרמטרים בכתובת ה-URL שצוינה, קונסולה לממשקי API יודעת להפעיל באופן אוטומטי את Google Maps Android API
- יוצרים מפתח API ולוחצים על Restrict Key כדי להגביל את השימוש במפתח לאפליקציות ל-Android. מפתח ה-API שנוצר צריך להתחיל ב-
AIza. - בקובץ
google_maps_api.xml, מדביקים את המפתח במחרוזתgoogle_maps_keyבמקום שבו מופיע הכיתובYOUR_KEY_HERE. - מריצים את האפליקציה. במפה שמוטמעת בפעילות מוגדר סמן בסידני, אוסטרליה. (הסמן של סידני הוא חלק מהתבנית, ואפשר לשנות אותו בהמשך).
4. משימה 2: הוספה של סוגי מפות וסמנים
במפות Google יש כמה סוגי מפות: רגילה, היברידית, לוויין, טופוגרפית ו'ללא'. במשימה הזו מוסיפים סרגל אפליקציות עם תפריט אפשרויות שמאפשר למשתמש לשנות את סוג המפה. אתם מזיזים את מיקום ההתחלה במפה למיקום הבית שלכם. לאחר מכן מוסיפים תמיכה בסמנים, שמציינים מיקומים בודדים במפה ויכולים לכלול תווית.
2.1 הוספת סוגי מפות
סוג המפה שהמשתמש רוצה תלוי בסוג המידע שהוא צריך. כשמשתמשים במפות לניווט ברכב, חשוב לראות את שמות הרחובות בצורה ברורה. כשאתם יוצאים לטיול רגלי, כנראה שחשוב לכם יותר לדעת כמה תצטרכו לטפס כדי להגיע לפסגת ההר. בשלב הזה מוסיפים סרגל אפליקציות עם תפריט אפשרויות שמאפשר למשתמש לשנות את סוג המפה.
- כדי ליצור קובץ XML חדש של תפריט, לוחצים לחיצה ימנית על ספריית
resובוחרים באפשרות New > Android Resource File (חדש > קובץ משאבים של Android). - בתיבת הדו-שיח, נותנים שם לקובץ
map_options. בוחרים באפשרות תפריט בשדה 'סוג המשאב'. לוחצים על אישור. - כדי ליצור את אפשרויות המפה, מחליפים את הקוד בקובץ החדש בקוד הבא. סוג המפה 'ללא' מושמט, כי התוצאה של 'ללא' היא היעדר מפה.
<?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">
<item android:id="@+id/normal_map"
android:title="@string/normal_map"
app:showAsAction="never"/>
<item android:id="@+id/hybrid_map"
android:title="@string/hybrid_map"
app:showAsAction="never"/>
<item android:id="@+id/satellite_map"
android:title="@string/satellite_map"
app:showAsAction="never"/>
<item android:id="@+id/terrain_map"
android:title="@string/terrain_map"
app:showAsAction="never"/>
</menu>
- יוצרים משאבי מחרוזות למאפייני
title. - בקובץ
MapsActivity, משנים את המחלקה כך שהיא תרחיב את המחלקהAppCompatActivityבמקום להרחיב את המחלקהFragmentActivity. שימוש ב-AppCompatActivityיציג את סרגל האפליקציות, ולכן יציג את התפריט. - ב-
MapsActivity, מבטלים את השיטהonCreateOptionsMenu()ויוצרים אוביקט תצוגה (inflate) של הקובץmap_options:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.map_options, menu);
return true;
}
- כדי לשנות את סוג המפה, משתמשים בשיטה
setMapType() באובייקטGoogleMapומעבירים את אחת הקבועים של סוג המפה.
מבטלים את השיטה onOptionsItemSelected(). מדביקים את הקוד הבא כדי לשנות את סוג המפה כשהמשתמש בוחר באחת מאפשרויות התפריט:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Change the map type based on the user's selection.
switch (item.getItemId()) {
case R.id.normal_map:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
case R.id.hybrid_map:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
return true;
case R.id.satellite_map:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
case R.id.terrain_map:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
- מריצים את האפליקציה ומשתמשים בתפריט בסרגל האפליקציות כדי לשנות את סוג המפה. שימו לב איך המראה של המפה משתנה.
2.2 הזזה של מיקום ברירת המחדל במפה
כברירת מחדל, הקריאה החוזרת onMapReady() כוללת קוד שמציב סמן בסידני שבאוסטרליה, המקום שבו נוצרו מפות Google. פונקציית הקריאה החוזרת שמוגדרת כברירת מחדל גם מפעילה אנימציה של המפה כדי להזיז אותה לסידני. בשלב הזה, המפה תזוז למיקום הבית שלכם בלי להציב סמן, ואז תתבצע הגדלה לרמה שתציינו.
- בשיטה
onMapReady(), מסירים את הקוד שמציב את הסמן בסידני ומזיז את המצלמה. - נכנסים לכתובת www.google.com/maps בדפדפן ומחפשים את הבית.
- לוחצים לחיצה ימנית על המיקום ובוחרים באפשרות מה יש כאן?
קרוב לחלק התחתון של המסך, יופיע חלון קטן עם פרטי המיקום, כולל קו הרוחב וקו האורך.
- יוצרים אובייקט
LatLngחדש בשםhome. באובייקטLatLng, משתמשים בקואורדינטות שמצאתם במפות Google בדפדפן. - יוצרים משתנה
floatבשםzoomומגדירים את המשתנה לרמת הזום ההתחלתית הרצויה. הרשימה הבאה נותנת לכם מושג לגבי רמת הפירוט שמוצגת בכל רמת זום:
-
1: עולם -
5: מסת יבשה/יבשת 10: עיר-
15: רחובות -
20: מבנים
- יוצרים אובייקט
CameraUpdateבאמצעותCameraUpdateFactory.newLatLngZoom(), ומעבירים את האובייקטLatLngואת המשתנהzoom. כדי להזיז את המצלמה ולשנות את מרחק התצוגה, קוראים ל-moveCamera()באובייקטGoogleMapומעבירים את האובייקט החדשCameraUpdate:
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
- מריצים את האפליקציה. המפה אמורה להזיז את התצוגה לבית שלכם ולהגדיל את התצוגה לרמה הרצויה.
2.3 הוספת סמני מפה
אפשר להשתמש בסמן כדי להבליט מיקום מסוים במפות Google. כדי ליצור סמן, משתמשים במחלקה Marker. סמן ברירת המחדל משתמש בסמל הרגיל של מפות Google: 
אפשר להרחיב את הסמנים כדי להציג מידע הקשרי בחלונות מידע.
בשלב הזה, מוסיפים סמן כשהמשתמש לוחץ לחיצה ארוכה על מיקום במפה. אחר כך מוסיפים InfoWindow שמציג את הקואורדינטות של הסמן כשמקישים על הסמן.

- יוצרים stub של method ב-
MapsActivityבשםsetMapLongClick()שמקבלfinalGoogleMapכארגומנט ומחזירvoid:
private void setMapLongClick(final GoogleMap map) {}
- משתמשים בשיטה
setOnMapLongClickListener()של האובייקטGoogleMapכדי למקם סמן במקום שבו המשתמש נוגע ומחזיק. מעבירים מופע חדש שלOnMapLongClickListenerשמבטל את השיטהonMapLongClick(). הארגומנט הנכנס הוא אובייקטLatLngשמכיל את הקואורדינטות של המיקום שהמשתמש לחץ עליו:
private void setMapLongClick(final GoogleMap map) {
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
}
});
}
- בתוך
onMapLongClick(), מבצעים קריאה ל-methodaddMarker(). מעבירים אובייקט חדש שלMarkerOptionsעם המיקום שמוגדר ל-LatLngשהועבר:
map.addMarker(new MarkerOptions().position(latLng));
- מבצעים קריאה ל-
setMapLongClick()בסוף השיטהonMapReady(). כרטיסmMap. - מריצים את האפליקציה. לוחצים לחיצה ארוכה על המפה כדי למקם סמן במיקום מסוים.
- מקישים על הסמן כדי למרכז אותו במסך.
לחצני הניווט מופיעים בצד ימין למטה של המסך, ומאפשרים למשתמש להשתמש באפליקציית מפות Google כדי לנווט למיקום המסומן.
כדי להוסיף חלון מידע לסמן:
- באובייקט
MarkerOptions, מגדירים את השדהtitleואת השדהsnippet. - ב-
onMapLongClick(), מגדירים את השדהtitleלערך 'סיכה שהוצבה'. מגדירים את השדהsnippetלקואורדינטות של המיקום בתוך השיטהaddMarker().
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
String snippet = String.format(Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude);
map.addMarker(new MarkerOptions()
.position(latLng)
.title(getString(R.string.dropped_pin))
.snippet(snippet));
}
});
- מפעילים את האפליקציה. לוחצים לחיצה ארוכה על המפה כדי להציב סמן מיקום. מקישים על הסמן כדי להציג את חלון המידע.
2.4 הוספת מאזין לנקודות עניין
כברירת מחדל, נקודות עניין מופיעות במפה עם הסמלים שלהן. נקודות העניין כוללות פארקים, בתי ספר, בנייני ממשלה ועוד. כשסוג המפה מוגדר לnormal, גם נקודות עניין עסקיות מופיעות במפה. נקודות עניין עסקיות מייצגות עסקים כמו חנויות, מסעדות ומלונות.
בשלב הזה מוסיפים GoogleMap.OnPoiClickListener למפה. המאזין הזה ללחיצות מציב סמן במפה באופן מיידי, במקום להמתין ללחיצה ארוכה. ה-listener של הקליק מציג גם את חלון המידע שמכיל את שם נקודת העניין.

- תצור מחזיק מקום (stub) של שיטה ב-
MapsActivityבשםsetPoiClick()שמקבלתfinalGoogleMapכארגומנט ומחזירהvoid:
private void setPoiClick(final GoogleMap map) {}
- בשיטה
setPoiClick(), מגדיריםOnPoiClickListenerב-GoogleMapשמועבר:
map.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
@Override
public void onPoiClick(PointOfInterest poi) {
}
});
- בשיטה
onPoiClick(), ממקמים סמן במיקום של נקודת העניין. מגדירים את הכותרת לשם של נקודת העניין. שומרים את התוצאה במשתנה שנקראpoiMarker.
public void onPoiClick(PointOfInterest poi) {
Marker poiMarker = mMap.addMarker(new MarkerOptions()
.position(poi.latLng)
.title(poi.name);
}
- מתקשרים אל
showInfoWindow()בטלפוןpoiMarkerכדי להציג מיד את חלון המידע.
poiMarker.showInfoWindow();
- התקשרת אל
setPoiClick()בסוףonMapReady(). כרטיסmMap. - מריצים את האפליקציה ומחפשים נקודת עניין כמו פארק. מקישים על נקודת העניין כדי להציב עליה סמן ולהציג את השם שלה בחלון מידע.
5. משימה 3: עיצוב המפה
יש הרבה דרכים להתאים אישית את מפות Google, כך שהמפה תיראה ותורגש ייחודית.
אפשר להתאים אישית אובייקט MapFragment באמצעות מאפייני ה-XML שזמינים, כמו שמתאימים אישית כל מקטע אחר. עם זאת, בשלב הזה מתאימים אישית את המראה והתחושה של התוכן של MapFragment, באמצעות שיטות באובייקט GoogleMap. אתם משתמשים באשף הסגנונות באינטרנט כדי להוסיף סגנון למפה ולהתאים אישית את הסמנים. אפשר גם להוסיף GroundOverlay למיקום הבית, שמשנה את הגודל שלו ומסתובב בהתאם למפה.
3.1 הוספת סגנון למפה
כדי ליצור סגנון מותאם אישית למפה, יוצרים קובץ JSON שמציין איך יוצגו הרכיבים במפה.לא צריך ליצור את קובץ ה-JSON הזה באופן ידני: Google מספקת את אשף הסגנונות, שיוצר את ה-JSON בשבילכם אחרי שאתם מעצבים את המפה באופן חזותי. בשיעור המעשי הזה, תעצבו את המפה ל'מצב לילה', כלומר המפה תשתמש בצבעים עמומים ובניגודיות נמוכה לשימוש בלילה.
- בדפדפן, עוברים אל https://mapstyle.withgoogle.com/.
- בוחרים באפשרות יצירת סגנון.
- בוחרים בעיצוב לילה.
- בתחתית התפריט, לוחצים על אפשרויות נוספות.
- בתחתית הרשימה סוג התכונה, בוחרים באפשרות מים > מילוי. משנים את צבע המים לכחול כהה (לדוגמה, #160064).
- לוחצים על סיום. מעתיקים את קוד ה-JSON מהחלון הקופץ שמופיע.
- ב-Android Studio, יוצרים ספריית משאבים בשם
rawבספרייהres. יוצרים קובץ ב-res/rawבשםmap_style.json. - מדביקים את קוד ה-JSON בקובץ המשאבים החדש.
- כדי להגדיר את הסגנון של ה-JSON במפה, קוראים ל-
setMapStyle()באובייקטGoogleMap. מעבירים אובייקטMapStyleOptions, שמעלה את קובץ ה-JSON. השיטהsetMapStyle()מחזירה ערך בוליאני שמציין אם העיצוב הצליח. אם אי אפשר לטעון את הקובץ, הפונקציה מחזירהResources.NotFoundException.
מעתיקים את הקוד הבא לשיטה onMapReady() כדי להגדיר את הסגנון של המפה. יכול להיות שתצטרכו ליצור TAG מחרוזת בשביל הצהרות היומן:
try {
// Customize the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this, R.raw.map_style));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style. Error: ", e);
}
- מריצים את האפליקציה. הסגנון החדש אמור להיות גלוי כשהמפה במצב
normal.

3.2 עיצוב הסמן
אפשר להתאים אישית את המפה עוד יותר על ידי שינוי הסגנון של סמני המפה. בשלב הזה משנים את הסמנים האדומים שמוגדרים כברירת מחדל כך שיתאימו לערכת הצבעים של מצב הלילה.
- בשיטה
onMapLongClick(), מוסיפים את שורת הקוד הבאה לבונהMarkerOptions()כדי להשתמש בסמן ברירת המחדל אבל לשנות את הצבע לכחול:
.icon(BitmapDescriptorFactory.defaultMarker
(BitmapDescriptorFactory.HUE_BLUE))
- מריצים את האפליקציה. הסמנים שמיקמתם מוצגים עכשיו בצבע כחול מוצלל, שמתאים יותר לעיצוב של מצב הלילה באפליקציה.
שימו לב שסמני הנקודות של העניין עדיין אדומים, כי לא הוספתם סגנון לשיטה onPoiClick().
3.3 הוספת שכבת-על
אחת הדרכים להתאים אישית את מפת Google היא לצייר מעליה. הטכניקה הזו שימושית אם רוצים להדגיש סוג מסוים של מיקום, כמו מקומות פופולריים לדיג. יש תמיכה בשלושה סוגים של שכבות-על:
- צורות: אפשר להוסיף למפה קווי פוליגון, פוליגונים ומעגלים.
TileOverlayאובייקטים: שכבה מעל קטעי המפה מגדירה קבוצה של תמונות שנוספות מעל קטעי המפה הבסיסיים. שכבות-על של משבצות שימושיות כשרוצים להוסיף למפה תמונות רבות. שכבה מעל קטעי המפה טיפוסית מכסה אזור גיאוגרפי גדול.- אובייקטים מסוג
GroundOverlay: שכבת-על של קרקע היא תמונה שמוצמדת למפה. שלא כמו סמנים, שכבות-על של הקרקע מכוונות לפני השטח של כדור הארץ ולא למסך. סיבוב, הטיה או שינוי הזום של המפה משנים את הכיוון של התמונה. שכבות על של קרקע שימושיות כשרוצים להצמיד תמונה אחת לאזור מסוים במפה
בשלב הזה מוסיפים שכבת-על של קרקע בצורת Android למיקום הבית.
- מורידים את התמונה הזו של Android ושומרים אותה בתיקייה
res/drawable. - ב-
onMapReady(), אחרי הקריאה להזזת המצלמה למיקום הבית, יוצרים אובייקטGroundOverlayOptions. הקצאת האובייקט למשתנה שנקראhomeOverlay:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions();
- משתמשים ב- method
BitmapDescriptorFactory.fromResource()כדי ליצור אובייקטBitmapDescriptorמהתמונה שלמעלה. מעבירים את האובייקט לשיטהimage()של האובייקטGroundOverlayOptions:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android));
- מגדירים את המאפיין
positionלאובייקטGroundOverlayOptionsעל ידי קריאה לשיטהposition(). מעבירים את האובייקטhomeLatLngואת הערךfloatלרוחב במטרים של שכבת העל הרצויה. בדוגמה הזו, רוחב של 100 מ' מתאים:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
.position(home, 100);
- שיחה למספר
addGroundOverlay()באובייקטGoogleMap. מעבירים את אובייקטGroundOverlayOptions:
mMap.addGroundOverlay(homeOverlay);
- מריצים את האפליקציה. מתקרבים למיקום הבית, ותמונת Android מוצגת כשכבת-על.
6. משימה 4: הפעלת מעקב אחר המיקום ו-Street View
משתמשים לרוב משתמשים במפות Google כדי לראות את המיקום הנוכחי שלהם, ואפשר לקבל את מיקום המכשיר באמצעות Location Services API. כדי להציג את מיקום המכשיר במפה בלי להשתמש בנתוני Location, אפשר להשתמש בשכבת נתוני המיקום.
שכבת נתוני המיקום מוסיפה לחלק העליון של המפה, בצד שמאל, את הלחצן המיקום שלי. כשהמשתמש מקיש על הכפתור, המפה מתמקדת במיקום המכשיר. המיקום מוצג כנקודה כחולה אם המכשיר נייח, וכשברון כחול אם המכשיר בתנועה.

אפשר לספק מידע נוסף על מיקום באמצעות Google Street View, שכולל תמונה פנורמית עם אפשרות ניווט של מיקום נתון.
במשימה הזו מפעילים את שכבת נתוני המיקום ואת Street View, כך שכשהמשתמש יקיש על חלון המידע של סמן נקודת העניין, המפה תעבור למצב Street View.
4.1 הפעלת מעקב אחר מיקום
כדי להפעיל את מעקב המיקום במפות Google, צריך להוסיף שורת קוד אחת. עם זאת, אתם צריכים לוודא שהמשתמש העניק הרשאות מיקום (באמצעות מודל ההרשאות בזמן הריצה).
בשלב הזה, שולחים בקשה להרשאות מיקום ומפעילים את מעקב המיקום.
- בקובץ
AndroidManifest.xml, מוודאים שההרשאהFINE_LOCATIONכבר קיימת. ההרשאה הזו נוספה על ידי Android Studio כשבחרתם בתבנית של מפות Google. - כדי להפעיל את מעקב המיקום באפליקציה, צריך ליצור שיטה ב-
MapsActivityבשםenableMyLocation()שלא מקבלת ארגומנטים ולא מחזירה כלום. - מגדירים את השיטה
enableMyLocation(). בודקים אם יש לכם הרשאה לACCESS_FINE_LOCATION. אם ההרשאה ניתנה, מפעילים את שכבת המיקום. אחרת, צריך לבקש את ההרשאה:
private void enableMyLocation() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION_PERMISSION);
}
}
- מתקשרים אל
enableMyLocation()מהקריאה החוזרתonMapReady()כדי להפעיל את שכבת המיקום. - מבטלים את השיטה
onRequestPermissionsResult(). אם ההרשאה ניתנה, מתקשרים אלenableMyLocation():
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
// Check if location permissions are granted and if so enable the
// location data layer.
switch (requestCode) {
case REQUEST_LOCATION_PERMISSION:
if (grantResults.length > 0
&& grantResults[0]
== PackageManager.PERMISSION_GRANTED) {
enableMyLocation();
break;
}
}
}
- מריצים את האפליקציה. בפינה השמאלית העליונה מופיע עכשיו הלחצן המיקום שלי, שבו מוצג המיקום הנוכחי של המכשיר.
4.2 הפעלת Street View
מפות Google מספקת את Street View, תצוגה פנורמית של מיקום עם אמצעי בקרה לניווט לאורך נתיב ייעודי. אין כיסוי גלובלי של Street View.
בשלב הזה מפעילים פנורמה ב-Street View שמופעלת כשהמשתמש מקיש על חלון המידע של נקודת העניין. יש שני דברים שצריך לעשות:
- להבחין בין סמני נקודות עניין לבין סמנים אחרים, כי רוצים שהפונקציונליות של האפליקציה תפעל רק על סמני נקודות עניין. כך תוכלו להפעיל את Street View כשהמשתמש מקיש על חלון מידע של נקודת עניין, אבל לא כשהמשתמש מקיש על סוג אחר של סמן.
המחלקות Marker כוללות את השיטה setTag() שמאפשרת לצרף נתונים. (הנתונים יכולים להיות כל דבר שמתחיל מ-Object). תגדירו תג על הסמנים שנוצרים כשמשתמשים לוחצים על נקודות עניין.
- כשמשתמש מקיש על חלון מידע מתויג ב-
OnInfoWindowClickListener, מחליפים אתMapFragmentב-StreetViewPanoramaFragment. (הקוד שלמטה משתמש ב-SupportMapFragmentוב-SupportStreetViewPanoramaFragmentכדי לתמוך בגרסאות Android מתחת ל-API 12).
אם יש שינויים באחד מהקטעים בזמן הריצה, צריך להוסיף אותם בכיתת Activity שמכילה אותם, ולא באופן סטטי ב-XML.
תיוג הסמן של נקודת העניין
- בשיחה החוזרת
onPoiClick(), התקשר אלsetTag()בכתובתpoiMarker. מעבירים מחרוזת שרירותית כלשהי:
poiMarker.setTag("poi");
החלפת SupportMapFragment סטטי במופע בזמן ריצה
- פותחים את
activity_maps.xmlומשנים את הרכיב לפריסת מסגרת שתשמש כמאגר לרכיבי ה-Fragment:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- ב-
onCreate()ב-MapsActivity, מסירים את הקוד שמאתר אתSupportMapFragmentלפי מזהה, כי כבר איןSupportMapFragmentסטטי ב-XML. במקום זאת, יוצרים מופע חדש של זמן הריצה שלSupportMapFragmentעל ידי קריאה ל-SupportMapFragment.newInstance():
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
- מוסיפים את הפראגמנט ל-
FrameLayoutבאמצעות טרנזקציית פראגמנט עםFragmentManager:
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, mapFragment).commit();
- משאירים את שורת הקוד שמפעילה את הטעינה האסינכרונית של המפה:
mapFragment.getMapAsync(this);
הגדרת OnInfoWindowClickListener ובדיקת תג הסמן
- תצור מחזיק מקום לשיטה ב-
MapsActivityבשםsetInfoWindowClickToPanorama()שמקבלתGoogleMapכארגומנט ומחזירהvoid:
private void setInfoWindowClickToPanorama(GoogleMap map) {}
- הגדרת
OnInfoWindowClickListenerל-GoogleMap:
map.setOnInfoWindowClickListener(
new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
}
});
- בשיטה
onInfoWindowClick(), בודקים אם הסמן מכיל את מחרוזת התג שהגדרתם בשיטהonPoiClick():
if (marker.getTag() == "poi") {}
החלפת SupportMapFragment ב-SupportStreetViewPanoramaFragment
- אם הסמן מכיל את התג, מציינים את המיקום של פנורמה ב-Street View באמצעות אובייקט
StreetViewPanoramaOptions. מגדירים את המאפייןpositionשל האובייקט למיקום של הסמן שהועבר:
StreetViewPanoramaOptions options =
new StreetViewPanoramaOptions().position(
marker.getPosition());
- יוצרים מופע חדש של
SupportStreetViewPanoramaFragmentומעבירים את אובייקטoptionsשיצרתם:
SupportStreetViewPanoramaFragment streetViewFragment
= SupportStreetViewPanoramaFragment
.newInstance(options);
- מתחילים טרנזקציה של מקטע. מחליפים את התוכן של מאגר הפרגמנט בפרגמנט החדש,
streetViewFragment. מוסיפים את העסקה למקבץ הפעילויות הקודמות (back stack), כך שלחיצה על 'חזרה' תחזיר את המשתמש אלSupportMapFragmentולא תוציא אותו מהאפליקציה:
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container,
streetViewFragment)
.addToBackStack(null).commit();
- התקשר אל
setInfoWindowClickToPanorama(mMap)בonMapReady()אחרי השיחה אלsetPoiClick(). - מפעילים את האפליקציה. מתקרבים לעיר שיש בה כיסוי של Street View, כמו מאונטיין ויו (שבה נמצא המטה של Google), ומחפשים נקודת עניין, כמו פארק. מקישים על נקודת העניין כדי להציב סמן ולהציג את חלון המידע. מקישים על חלון המידע כדי להיכנס למצב Street View של מיקום הסמן. לוחצים על הכפתור "הקודם" כדי לחזור למקטע המפה.

7. קוד הפתרון
קוד הפתרון Wander.
8. אתגר תכנות
בעיה: אם מקישים על חלון המידע של נקודת עניין במיקום שאין בו כיסוי של Street View, מופיע מסך שחור.
- כדי לבדוק אם Street View זמין באזור מסוים, מטמיעים את פונקציית הקריאה החוזרת
OnStreetViewPanomaraReadyבשילוב עםStreetViewPanorama.OnStreetViewPanoramaChangeListener. - אם Street View לא זמין באזור שנבחר, צריך לחזור לקטע המפה ולהציג שגיאה.
9. סיכום
- כדי להשתמש ב-Maps API, צריך מפתח API מ-Google API Console.
- ב-Android Studio, שימוש בתבנית Google Maps Activity יוצר
ActivityעםSupportMapFragmentאחד בפריסת האפליקציה. בנוסף, התבנית מוסיפה אתACCESS_FINE_PERMISSIONלקובץ מניפסט של אפליקציה, מטמיעה אתOnMapReadyCallbackבפעילות ומבטלת את השיטה הנדרשתonMapReady().
כדי לשנות את סוג המפה של GoogleMap בזמן ריצה, משתמשים בשיטה GoogleMap.setMapType(). מפת Google יכולה להיות אחד מסוגי המפות הבאים:
- רגילה: מפת דרכים רגילה. מציגה כבישים, חלק מהמאפיינים שנבנו על ידי בני אדם ומאפיינים טבעיים חשובים כמו נהרות. אפשר לראות גם תוויות של כבישים ומאפיינים.
- היברידית: נתונים של צילומי לוויין עם מפות דרכים. אפשר לראות גם תוויות של כבישים ומאפיינים.
- לוויין: נתוני תמונה. לא רואים את התוויות של הכבישים והתכונות.
- פני השטח: נתונים טופוגרפיים. המפה כוללת צבעים, קווי מתאר ותוויות, והצללה פרספקטיבית. אפשר לראות גם חלק מהכבישים והתוויות.
- ללא**:** ללא מפה.
מידע על מפות Google:
- סמן הוא אינדיקטור למיקום גיאוגרפי ספציפי.
- כשמקישים על הסמן, התנהגות ברירת המחדל שלו היא להציג חלון מידע עם פרטים על המיקום.
- כברירת מחדל, נקודות עניין מופיעות במפת הבסיס עם הסמלים המתאימים שלהן. נקודות העניין כוללות פארקים, בתי ספר, בנייני ממשלה ועוד.
- בנוסף, נקודות עניין עסקיות (חנויות, מסעדות, מלונות ועוד) מופיעות כברירת מחדל במפה כשסוג המפה הוא
normal. - אפשר לתעד קליקים על נקודות עניין באמצעות
OnPoiClickListener. - אפשר לשנות את המראה של כמעט כל הרכיבים במפת Google באמצעות אשף הסגנונות. אשף הסגנונות יוצר קובץ JSON שמעבירים למפה של Google באמצעות השיטה
setMapStyle(). - אתם יכולים לשנות את צבע ברירת המחדל של הסמנים או להחליף את סמל ברירת המחדל של הסמן בתמונה בהתאמה אישית.
עוד מידע חשוב:
- כדי להצמיד תמונה למיקום גיאוגרפי, משתמשים בשכבת-על של הקרקע.
- משתמשים באובייקט
GroundOverlayOptionsכדי לציין את התמונה, את הגודל שלה במטרים ואת המיקום שלה. מעבירים את האובייקט הזה אל השיטהGoogleMap.addGroundOverlay()כדי להגדיר את שכבת העל במפה. - אם לאפליקציה שלכם יש הרשאה
ACCESS_FINE_LOCATION, אתם יכולים להפעיל את מעקב המיקום באמצעות השיטהmMap.setMyLocationEnabled(true). - Google Street View מספק תצוגות פנורמיות של 360 מעלות מכבישים ייעודיים בכל היקף גיאוגרפי.
- משתמשים בשיטה
StreetViewPanoramaFragment.newInstance()כדי ליצור קטע חדש של Street View. - כדי לציין את האפשרויות של התצוגה, משתמשים באובייקט
StreetViewPanoramaOptions. מעבירים את האובייקט לשיטהnewInstance().
10. מידע נוסף
מסמכי התיעוד בנושא המושג הזה זמינים במאמר 9.1: Google Maps API.
מסמכי התיעוד למפתחים בנושא Android:
- תחילת העבודה עם Google Maps Android API
- הוספת מפה עם סמן
- אובייקטים של מפה
- הוספת מפה מסוגננת
- Street View
- שכבות-על של קרקע
מסמכי עזר:
11. שיעורי בית
בקטע הזה מפורטות משימות אפשריות לשיעורי בית לתלמידים שעובדים על ה-Codelab הזה כחלק מקורס בהנחיית מדריך. המורה צריך:
- אם צריך, מקצים שיעורי בית.
- להסביר לתלמידים איך להגיש שיעורי בית.
- בודקים את שיעורי הבית.
המדריכים יכולים להשתמש בהצעות האלה כמה שרוצים, ומומלץ להם להקצות כל שיעורי בית אחרים שהם חושבים שמתאימים.
אם אתם עובדים על ה-Codelab הזה לבד, אתם יכולים להשתמש בשיעורי הבית האלה כדי לבדוק את הידע שלכם.
פיתוח והרצה של אפליקציה
- יוצרים אפליקציה חדשה שמשתמשת בתבנית הפעילות של מפות Google, שנטענת כשמפעילים את האפליקציה.
- אחרי שמפת Google נטענת, מעבירים את המצלמה למיקום בית הספר, למיקום הבית או למיקום אחר שחשוב לכם.
- מוסיפים שני סמנים למפה, אחד במיקום בית הספר ואחד בבית או במיקום משמעותי אחר.
- אתם יכולים לשנות את צבע ברירת המחדל של סמלי הסמנים או להחליף את סמל ברירת המחדל בתמונה בהתאמה אישית.
הערה: אפשר לעיין במסמכי התיעוד של onMapReady (GoogleMap googleMap).
עונים על השאלות הבאות
שאלה 1
איזו שיטה מופעלת כשהמפה נטענת ומוכנה לשימוש באפליקציה?
onMapReady (GoogleMapgoogleMap)onMapLoaded (GoogleMapgoogleMap)onMapCreate (GoogleMapgoogleMap)onMapInitialize (GoogleMapgoogleMap)
שאלה 2
אילו רכיבי Android אפשר להשתמש בהם כדי לכלול את מפות Google באפליקציה?
MapViewוגםMapFragmentMapFragmentוגםMapActivityMapViewוגםMapActivity- רק
MapFragment
שאלה 3
אילו סוגי מפות מוצעים בממשק ה-API של מפות Google ל-Android?
- רגילה, היברידית, טופוגרפית, לווינית ומפת דרכים
- רגיל, היברידי, טופוגרפי, לוויין ו'ללא'
- היברידית, פני השטח, לוויין, מפת דרכים ו'ללא'
- רגיל, פני שטח, לוויין, מפת תמונות ו'ללא'
שאלה 4
איזה ממשק מטמיעים כדי להוסיף פונקציונליות של לחיצה על נקודת עניין (POI)?
GoogleMap.OnPoiListenerGoogleMap.OnPoiClickListenerGoogleMap.OnPoiClickGoogleMap.OnPoiClicked
שליחת האפליקציה למתן ציונים
הנחיות למעריכים
בודקים אם האפליקציה כוללת את התכונות הבאות:
- כשמפעילים את האפליקציה, מפת Google מוצגת בצורה תקינה, מה שמצביע על כך שמפתח ה-API נוצר בצורה תקינה.
- אחרי שהמפה של Google נטענת, המצלמה עוברת למיקום הבית או בית הספר של התלמיד/ה. בקוד, השלב הזה צריך להתרחש בשיטת הקריאה החוזרת
onMapReady (GoogleMap googleMap). - סמנים מוצגים במיקום בית הספר של התלמיד/ה ובמיקום אחר, כמו הבית של התלמיד/ה.
- שני הסמנים מותאמים אישית. לדוגמה, הסמנים משתמשים בצבע שונה מצבע ברירת המחדל האדום, או שהם משתמשים בסמל בהתאמה אישית.
12. ה-Codelab הבא
כדי לראות את כל ה-codelabs בקורס Advanced Android Development (פיתוח מתקדם ל-Android), אפשר להיכנס אל דף הנחיתה של Advanced Android Development codelabs.