Advanced Android 09.1: מפות Google

1. היי!

Codelab זה הוא חלק מקורס ההדרכה למתקדמים של פיתוח Android, שפותח על ידי צוות ההדרכה של Google Developers. אם תעבדו על הקוד של 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.

מפת Google מעוצבת

Google Street View באפליקציה ל-Android

3. משימה 1: הגדרת הפרויקט וקבלת מפתח API

ל-Google Maps API, כמו Places 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 באמצעות התבנית של מפות Google

  1. יוצרים פרויקט חדש של Android Studio.
  2. נותנים לאפליקציה החדשה את השם 'Wander'. מאשרים את הגדרות ברירת המחדל עד שמגיעים לדף הוספת פעילות.
  3. בוחרים את התבנית פעילות במפות Google.
  4. משאירים את ערכי ברירת המחדל של שם הפעילות ושם הפריסה.
  5. משנים את הכותרת ל"Wander". ולוחצים על Finish.

מערכת Android Studio יוצרת מספר קבצים נוספים שקשורים למפות:

google_maps_api**.xml**

אתם משתמשים בקובץ התצורה הזה כדי לשמור את מפתח ה-API שלכם. התבנית יוצרת שני קובצי google_maps_api.xml: אחד לניפוי באגים ואחד לגרסה. הקובץ של מפתח ה-API לאישור של ניפוי הבאגים נמצא ב-src/debug/res/values. הקובץ של מפתח ה-API לאישור ההפצה נמצא ב-src/release/res/values. במקרה הזה אנחנו משתמשים רק באישור לניפוי באגים.

activity_maps.xml

קובץ הפריסה הזה מכיל מקטע יחיד שממלא את כל המסך. המחלקה SupportMapFragment היא מחלקה משנית של המחלקה Fragment. אפשר לכלול את SupportMapFragment בקובץ פריסה באמצעות תג <fragment> בכל ViewGroup, עם מאפיין נוסף:

android:name="com.google.android.gms.maps.SupportMapFragment"

MapsActivity.java

הקובץ MapsActivity.java יוצר את המחלקה SupportMapFragment ומשתמש ב-method getMapAsync() של הכיתה כדי להכין את המפה של Google. הפעילות שמכילה את SupportMapFragment חייבת להטמיע את הממשק של OnMapReadyCallback ואת ה-method onMapReady() של הממשק הזה. ה-method getMapAsync() מחזירה אובייקט GoogleMap, שמציין שהמפה נטענה.

1.2 קבלת מפתח ה-API

  1. פותחים את גרסת ניפוי הבאגים של הקובץ google_maps_api.xml.

הקובץ כולל תגובה עם כתובת URL ארוכה. הפרמטרים של כתובת ה-URL כוללים מידע ספציפי על האפליקציה שלכם.

  1. להעתיק את כתובת ה-URL ולהדביק אותה בדפדפן.
  2. פועלים לפי ההנחיות ליצירת פרויקט במסוף Google API. בשל הפרמטרים בכתובת ה-URL שצוינה, מסוף ה-API יודע להפעיל באופן אוטומטי את ממשק ה-API ל-Android של מפות Google
  3. יוצרים מפתח API ולוחצים על Restrict Key (הגבלת מפתח) כדי להגביל את השימוש במפתח לאפליקציות ל-Android. מפתח ה-API שנוצר צריך להתחיל ב-AIza.
  4. בקובץ google_maps_api.xml, מדביקים את המפתח במחרוזת google_maps_key במקום שבו מופיע הכיתוב YOUR_KEY_HERE.
  5. מפעילים את האפליקציה. בפעילות שלך יש מפה מוטמעת, עם סמן המוגדר בסידני, אוסטרליה. (הסמן של סידני הוא חלק מהתבנית, ואפשר לשנות אותו בהמשך.)

4. משימה 2: הוספת סוגים וסמנים של מפה

מפות Google כוללות מספר סוגי מפות: רגילה, היברידית, לוויינית, פני שטח ו'ללא'. במשימה הזו מוסיפים סרגל אפליקציה עם תפריט אפשרויות שמאפשר למשתמש לשנות את סוג המפה. אתם מזיזים את המיקום ההתחלתי של המפה למיקום הבית שלכם. לאחר מכן מוסיפים תמיכה בסמנים, שמציינים מיקומים בודדים במפה ויכולים לכלול תווית.

2.1 הוספה של סוגי מפות

סוג המפה שהמשתמש רוצה תלוי בסוג המידע שהוא זקוק לה. כשמשתמשים במפות לצורך ניווט ברכב, כדאי לראות בבירור את שמות הרחובות. כשאתם יוצאים לטיול רגלי, כנראה יותר חשוב לכם לדעת כמה צריך לטפס כדי להגיע לפסגת ההר. בשלב הזה מוסיפים סרגל אפליקציה עם תפריט אפשרויות שמאפשר למשתמש לשנות את סוג המפה.

  1. כדי ליצור קובץ XML חדש של תפריט, לוחצים לחיצה ימנית על ספריית res ובוחרים חדש > קובץ משאב של Android.
  2. בתיבת הדו-שיח, נותנים לקובץ את השם map_options. בוחרים באפשרות תפריט כדי להציג את סוג המשאב. לוחצים על OK (אישור).
  3. כדי ליצור את אפשרויות המפה, צריך להחליף את הקוד שבקובץ החדש בקוד הבא. האפשרות "ללא" סוג המפה הושמט, מכיוון ש'ללא'. התוצאה תהיה היעדר מפה בכלל.
<?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>
  1. יצירת משאבי מחרוזת עבור המאפיינים title.
  2. בקובץ MapsActivity, משנים את המחלקה כדי להרחיב את המחלקה AppCompatActivity במקום להרחיב את המחלקה FragmentActivity. באמצעות AppCompatActivity יוצג סרגל האפליקציות, ולכן התפריט יוצג.
  3. ב-MapsActivity, מבטלים את השיטה onCreateOptionsMenu() ומנפחים את הקובץ map_options:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.map_options, menu);
   return true;
}
  1. כדי לשנות את סוג המפה, משתמשים בשיטה 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);
       }
    }
  1. מפעילים את האפליקציה. כדי לשנות את סוג המפה, משתמשים בתפריט שבסרגל האפליקציה. שימו לב איך מראה המפה משתנה.

2.2 הזזת מיקום ברירת המחדל במפה

כברירת מחדל, הקריאה החוזרת (callback) של onMapReady() כוללת קוד שמציב סמן בסידני, אוסטרליה, שבה נוצר מפות Google. הקריאה החוזרת שמוגדרת כברירת מחדל גם יוצרת אנימציה של המפה כדי להזיז אותה לסידני. בשלב זה, תזיזו את המפה אל מיקום הבית שלכם בלי להציב סמן, ולאחר מכן תתקרבו לרמה שציינתם.

  1. בשיטה onMapReady(), מסירים את הקוד שמציב את הסמן בסידני ומזיז את המצלמה.
  2. עוברים אל www.google.com/maps בדפדפן ומוצאים את כתובת הבית.
  3. לוחצים לחיצה ימנית על המיקום ובוחרים באפשרות מה יש כאן?

ליד תחתית המסך יקפוץ חלון קטן עם פרטי המיקום, כולל קו הרוחב וקו האורך.

  1. יוצרים אובייקט LatLng חדש בשם home. באובייקט LatLng, משתמשים בקואורדינטות שמצאתם במפות Google בדפדפן.
  2. יוצרים משתנה float בשם zoom ומגדירים אותו לפי רמת הזום הראשונית הרצויה. הרשימה הבאה מספקת מושג לגבי רמת הפירוט של כל רמת זום:
  • 1: עולם
  • 5: גודל יבשתי/יבשתי
  • 10: עיר
  • 15: רחובות
  • 20: מבנים
  1. יוצרים אובייקט CameraUpdate באמצעות CameraUpdateFactory.newLatLngZoom() ומעבירים את האובייקט LatLng ואת המשתנה zoom. הזזה ושינוי מרחק התצוגה של המצלמה על ידי קריאה ל-moveCamera() באובייקט GoogleMap, והעברת האובייקט CameraUpdate החדש:
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
  1. מפעילים את האפליקציה. המפה צריכה להזיז את המפה אל הבית ולהגדיל את התצוגה לרמה הרצויה.

2.3 הוספת סמני מפה

מפות Google יכול לסמן מיקום מסוים באמצעות סמן, שאתם יוצרים באמצעות הכיתה Marker. סמן ברירת המחדל משתמש בסמל הרגיל של מפות Google: סמן במפות Google

תוכל להרחיב סמנים כדי להציג מידע לפי הקשר בחלונות מידע.

בשלב הזה, מוסיפים סמן כשהמשתמש נוגע ומחזיק מיקום במפה. לאחר מכן מוסיפים InfoWindow שמציגה את הקואורדינטות של הסמן כשמקישים על הסמן.

חלון מידע לסיכה שמוקמה

  1. יוצרים stub של method ב-MapsActivity בשם setMapLongClick() שלוקח את final GoogleMap כארגומנט ומחזירה void:
private void setMapLongClick(final GoogleMap map) {}
  1. משתמשים בשיטה setOnMapLongClickListener() של האובייקט GoogleMap כדי למקם סמן במקום שבו המשתמש נוגע ומחזיק. מעבירים במופע חדש של OnMapLongClickListener שמחליף את ה-method onMapLongClick(). הארגומנט הנכנס הוא אובייקט LatLng שמכיל את הקואורדינטות של המיקום שהמשתמש לחץ עליו:
private void setMapLongClick(final GoogleMap map) {
   map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
       @Override
       public void onMapLongClick(LatLng latLng) {
       }
   });
}
  1. בתוך onMapLongClick(), קוראים ל-method addMarker(). מעבירים אובייקט MarkerOptions חדש עם המיקום המוגדר בתור LatLng שהועבר:
map.addMarker(new MarkerOptions().position(latLng));
  1. קוראים לפונקציה setMapLongClick() בסוף השיטה onMapReady(). מעבר בmMap.
  2. מפעילים את האפליקציה. לוחצים לחיצה ארוכה על המפה כדי להציב סמן במיקום מסוים.
  3. מקישים על הסמן, שמרכז אותו במסך.

לחצני הניווט מופיעים בצד ימין למטה של המסך, ומאפשרים למשתמש להשתמש באפליקציית מפות Google כדי לנווט למיקום המסומן.

כדי להוסיף חלון מידע לסמן:

  1. באובייקט MarkerOptions, מגדירים את השדה title ואת השדה snippet.
  2. בקובץ onMapLongClick(), מגדירים את השדה title בתור 'הצמדת סיכה'. מגדירים את השדה snippet לקואורדינטות של המיקום שבתוך ה-method 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));
   }
});
  1. מפעילים את האפליקציה. לוחצים לחיצה ארוכה על המפה כדי להציב סמן מיקום. מקישים על הסמן כדי להציג את חלון המידע.

2.4 הוספה של מזהה נקודת עניין

כברירת מחדל, נקודות עניין (POI) מופיעות במפה יחד עם הסמלים המתאימים שלהן. נקודות העניין כוללות פארקים, בתי ספר, בנייני ממשלה ועוד. אם סוג המפה מוגדר כnormal, נקודות עניין של העסק יופיעו במפה גם כן. נקודות עניין של עסקים מייצגות עסקים כמו חנויות, מסעדות ומלונות.

בשלב הזה מוסיפים GoogleMap.OnPoiClickListener למפה. מאזין קליקים זה מציב סמן במפה באופן מיידי, במקום להמתין למגע & לחיצה ארוכה. מאזין הקליקים מציג גם את חלון המידע שמכיל את שם נקודת העניין.

סמן של נקודת עניין

  1. יוצרים רכיב method ב-MapsActivity בשם setPoiClick() שלוקח את final GoogleMap כארגומנט ומחזירה void:
private void setPoiClick(final GoogleMap map) {}
  1. באמצעות method setPoiClick(), מגדירים OnPoiClickListener ב-GoogleMap שהועבר:
map.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
   @Override
   public void onPoiClick(PointOfInterest poi) {
   }
});
  1. בשיטה onPoiClick(), מציבים סמן במיקום של נקודת העניין. מגדירים את השם כשם של נקודת העניין. שומרים את התוצאה במשתנה שנקרא poiMarker.
public void onPoiClick(PointOfInterest poi) {
   Marker poiMarker = mMap.addMarker(new MarkerOptions()
       .position(poi.latLng)
       .title(poi.name);
}
  1. התקשרות אל showInfoWindow() ב-poiMarker כדי להציג את חלון המידע באופן מיידי.
poiMarker.showInfoWindow();
  1. התקשרות אל setPoiClick() בסוף onMapReady(). מעבר בmMap.
  2. מפעילים את האפליקציה ומוצאים נקודת עניין, כמו פארק. מקישים על נקודת העניין כדי למקם עליה סמן ולהציג את השם שלה בחלון מידע.

5. משימה 3: עיצוב המפה

אפשר להתאים אישית את מפות Google בדרכים רבות, ולהעניק למפה שלך מראה ותחושה ייחודיים.

אפשר להתאים אישית אובייקט MapFragment באמצעות מאפייני ה-XML הזמינים, כמו שאפשר להתאים אישית כל מקטע אחר. עם זאת, בשלב הזה מתאימים אישית את העיצוב והסגנון של התוכן של MapFragment, באמצעות methods באובייקט GoogleMap. ניתן להשתמש באשף העיצוב אונליין כדי להוסיף סגנון למפה ולהתאים אישית את הסמנים. אתם גם מוסיפים GroundOverlay למיקום הבית כדי לשנות את הגודל שלו ולסובב אותו עם המפה.

3.1 הוספת סגנון למפה

כדי ליצור סגנון מותאם אישית למפה, יוצרים קובץ JSON שמציין איך התכונות במפה מוצגות.אין צורך ליצור את קובץ ה-JSON באופן ידני: Google מספקת את אשף העיצוב, שיוצר בשבילכם את ה-JSON אחרי שמעצבים את המפה באופן חזותי. מבחינה מעשית, אפשר לעצב את המפה ל"מצב לילה", כלומר, במפה נעשה שימוש בצבעים מעומעמים ובניגודיות נמוכה לשימוש בלילה.

  1. מנווטים לכתובת https://mapstyle.withgoogle.com/ בדפדפן.
  2. בוחרים באפשרות יצירת סגנון.
  3. בוחרים בעיצוב לילה.
  4. לוחצים על אפשרויות נוספות בתחתית התפריט.
  5. בתחתית הרשימה סוג הישות, בוחרים באפשרות מים > מילוי. משנים את צבע המים לכחול כהה (לדוגמה, #160064).
  6. לוחצים על סיום. מעתיקים את קוד ה-JSON מהחלון הקופץ שמופיע.
  7. ב-Android Studio, יוצרים ספריית משאבים בשם raw בספרייה res. ליצור קובץ ב-res/raw בשם map_style.json.
  8. מדביקים את קוד ה-JSON בקובץ המשאבים החדש.
  9. כדי להגדיר את סגנון ה-JSON למפה, קוראים לפונקציה setMapStyle() באובייקט GoogleMap. מעבירים אובייקט MapStyleOptions שטוען את קובץ ה-JSON. ה-method setMapStyle() מחזירה ערך בוליאני שמציין את הצלחת הסגנון. אם אי אפשר לטעון את הקובץ, השיטה גורמת Resources.NotFoundException.

מעתיקים את הקוד הבא ל-method 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);
     }
  1. מפעילים את האפליקציה. הסגנון החדש אמור להיות גלוי כשהמפה נמצאת במצב normal.

מפת Google בסגנון מצב לילה

3.2 עיצוב הסמן

ניתן להתאים אישית את המפה עוד יותר על ידי עיצוב סמני המפה. בשלב הזה, משנים את הסמנים האדומים שמוגדרים כברירת מחדל כך שיתאימו לערכת הצבעים של מצב הלילה.

  1. בשיטה onMapLongClick(), מוסיפים את שורת הקוד הבאה ל-constructor של MarkerOptions() כדי להשתמש בסמן ברירת המחדל אבל לשנות את הצבע לכחול:
.icon(BitmapDescriptorFactory.defaultMarker
       (BitmapDescriptorFactory.HUE_BLUE))
  1. מפעילים את האפליקציה. הסמנים שתמקם צבועים עכשיו בכחול, באופן שתואם יותר לעיצוב מצב הלילה של האפליקציה.

לתשומת ליבך, הסמנים של נקודות העניין עדיין אדומים, כי לא הוספת עיצוב לשיטה onPoiClick().

3.3 הוספת שכבת-על

אחת מהדרכים להתאים אישית את מפת Google היא באמצעות שרטוט. השיטה הזו שימושית אם רוצים להדגיש מיקום מסוג מסוים, כמו אתרי דיג פופולריים. יש תמיכה בשלושה סוגים של שכבות-על:

  • צורות: ניתן להוסיף למפה קווים פוליגוניים, פוליגונים ומעגלים.
  • TileOverlay אובייקטים: שכבת-על של משבצת מגדירה קבוצה של תמונות שנוספים מעל קטעי המפה הבסיסית. שכבות-על של משבצות שימושיות כשרוצים להוסיף תמונות מקיפות למפה. שכבת-על אופיינית של משבצת מכסה אזור גיאוגרפי גדול.
  • GroundOverlay אובייקטים: שכבת-על של קרקע היא תמונה שקבועה למפה. בשונה מסמנים, שכבות-על של קרקע מכוונות לפני כדור הארץ ולא למסך. סיבוב, הטיה או שינוי מרחק התצוגה של המפה משנים את כיוון התמונה. שכבות-על של קרקע שימושיות כשרוצים לתקן תמונה יחידה באזור אחד במפה

בשלב הזה, מוסיפים שכבת-על של קרקע בצורת מכשיר Android למיקום הבית שלכם.

  1. מורידים את תמונת ה-Android הזו ושומרים אותה בתיקייה res/drawable.
  2. ב-onMapReady(), אחרי הקריאה להזיז את המצלמה לעמדת הבית, צריך ליצור אובייקט GroundOverlayOptions. מקצים את האובייקט למשתנה בשם homeOverlay:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions();
  1. משתמשים בשיטה BitmapDescriptorFactory.fromResource() כדי ליצור אובייקט BitmapDescriptor מהתמונה שלמעלה. מעבירים את האובייקט ל-method image() של האובייקט GroundOverlayOptions:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
    .image(BitmapDescriptorFactory.fromResource(R.drawable.android));
  1. מגדירים את המאפיין position של האובייקט GroundOverlayOptions באמצעות קריאה ל-method position(). מעבירים את האובייקט home LatLng ו-float בשביל הרוחב במטרים של שכבת-העל הרצויה. בדוגמה הזו, רוחב של 100 מ' הוא המתאים:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
     .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
       .position(home, 100);
  1. קוראים לפונקציה addGroundOverlay() באובייקט GoogleMap. מעבירים את האובייקט GroundOverlayOptions:
mMap.addGroundOverlay(homeOverlay);
  1. מפעילים את האפליקציה. אם מגדילים את התצוגה של מיקום הבית, התמונה של Android מוצגת כשכבת-על.

6. משימה 4: הפעלת מעקב אחר מיקום ו-Street View

משתמשים בדרך כלל משתמשים במפות Google כדי לראות את המיקום הנוכחי שלהם. אפשר לקבל את מיקום המכשיר באמצעות Location Services API. כדי להציג את מיקום המכשיר במפה ללא שימוש נוסף בנתוני Location, אפשר להשתמש בשכבת נתוני המיקום.

שכבת נתוני המיקום מוסיפה לחצן המיקום שלי לצד השמאלי העליון של המפה. כשהמשתמש מקיש על הלחצן, המפה מתמרכזת לפי מיקום המכשיר. המיקום מוצג כנקודה כחולה אם המכשיר נייח, ובתור סוגריים כחול אם המכשיר זז.

מפת Google מעוצבת עם מעקב אחר מיקום

באפשרותך לספק מידע נוסף על מיקום באמצעות Google Street View, תמונת פנורמה של מיקום נתון שניתן לנווט אליו.

במשימה הזאת אתם מפעילים את השכבה של נתוני המיקום ואת Street View, כך שכאשר המשתמש יקיש על חלון המידע של סמן נקודת העניין, המפה תעבור למצב Street View.

4.1 הפעלת מעקב אחר מיקום

כדי להפעיל מעקב אחר מיקום במפות Google יש שורת קוד אחת. עם זאת, צריך לוודא שהמשתמש העניק הרשאות מיקום (באמצעות המודל של הרשאת זמן ריצה).

בשלב הזה אתם מבקשים הרשאות מיקום ומפעילים את המעקב אחר המיקומים.

  1. בקובץ AndroidManifest.xml, מוודאים שההרשאה FINE_LOCATION כבר קיימת. ההרשאה הזו נוספה ל-Android Studio כשבחרת בתבנית של מפות Google.
  2. כדי להפעיל מעקב אחר מיקום באפליקציה שלך, עליך ליצור בMapsActivity שיטה שנקראת enableMyLocation() שלא מקבלת ארגומנטים ולא מחזירה שום דבר.
  3. מגדירים את השיטה 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);
   }
}
  1. צריך להפעיל את enableMyLocation() מהקריאה החוזרת (callback) של onMapReady() כדי להפעיל את שכבת המיקום.
  2. שינוי השיטה 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;
           }
   }
}
  1. מפעילים את האפליקציה. בפינה השמאלית העליונה מופיע עכשיו הלחצן המיקום שלי, שמציג את המיקום הנוכחי של המכשיר.

4.2 הפעלת Street View

אפליקציית מפות Google מספקת את Street View – זוהי תצוגה פנורמית של מיקום עם אמצעי בקרה לניווט בנתיב ייעודי. ל-Street View אין כיסוי גלובלי.

בשלב הזה, מפעילים תמונת פנורמה של Street View, שמופעלת כשהמשתמש מקיש על חלון המידע של נקודת עניין. צריך לעשות שני דברים:

  1. צריך להבדיל בין סמנים של נקודות עניין לבין סמנים אחרים, כי רוצים שהפונקציונליות של האפליקציה תפעל רק על סמנים של נקודות עניין. כך, אפשר להפעיל את Street View כשהמשתמש מקיש על חלון מידע של נקודת עניין, אבל לא כשהמשתמש מקיש על סמן מסוג אחר.

המחלקה Marker כוללת שיטה setTag() שמאפשרת לצרף נתונים. (הנתונים יכולים להיות כל דבר החל מ-Object). צריך להגדיר תג בסמנים שנוצרים כשמשתמשים לוחצים על נקודות עניין.

  1. כשהמשתמש יקיש על חלון מידע מתויג ב-OnInfoWindowClickListener, מחליפים את MapFragment בStreetViewPanoramaFragment. (הקוד שבהמשך משתמש ב-SupportMapFragment וב-SupportStreetViewPanoramaFragment כדי לתמוך בגרסאות Android שקודמות ל-API 12).

אם מקטעים כלשהם משתנים בזמן הריצה, יש להוסיף אותם במחלקה Activity המכילה, ולא באופן סטטי ב-XML.

תיוג של נקודת העניין

  1. בקריאה החוזרת של onPoiClick(), צריך להתקשר ל-setTag() במספר poiMarker. העברה בכל מחרוזת שרירותית:
poiMarker.setTag("poi");

החלפת הערך הסטטי של SupportMapFragment במופע של סביבת זמן ריצה

  1. פותחים את activity_maps.xml ומשנים את הרכיב לפריסת מסגרת שתשמש כמאגר למקטעים שלכם:
<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" />
  1. ב-onCreate() ב-MapsActivity, מסירים את הקוד שמוצא את SupportMapFragment לפי המזהה, כי כבר אין SupportMapFragment סטטי ב-XML. במקום זאת, צריך ליצור מופע חדש של סביבת זמן ריצה של SupportMapFragment באמצעות קריאה ל-SupportMapFragment.newInstance():
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
  1. מוסיפים את המקטע אל FrameLayout באמצעות עסקת מקטע עם FragmentManager:
getSupportFragmentManager().beginTransaction()
       .add(R.id.fragment_container, mapFragment).commit();
  1. שומרים את שורת הקוד שמפעילה את הטעינה האסינכרונית של המפה:
mapFragment.getMapAsync(this);

הגדרת OnInfoWindowClickListener ובדיקה של תג הסמן

  1. יוצרים stub של method ב-MapsActivity בשם setInfoWindowClickToPanorama() שלוקח את GoogleMap כארגומנט ומחזירה void:
private void setInfoWindowClickToPanorama(GoogleMap map) {}
  1. מגדירים OnInfoWindowClickListener ל-GoogleMap:
map.setOnInfoWindowClickListener(
       new GoogleMap.OnInfoWindowClickListener() {
           @Override
           public void onInfoWindowClick(Marker marker) {
           }
       });
  1. בשיטה onInfoWindowClick(), בודקים אם הסמן מכיל את תג המחרוזת שהגדרתם בשיטה onPoiClick():
if (marker.getTag() == "poi") {}

מחליפים את SupportMapFragment ב-SupportStreetViewPanoramaFragment

  1. במקרה שבו הסמן מכיל את התג, צריך לציין את המיקום בשביל הפנורמה של Street View באמצעות אובייקט StreetViewPanoramaOptions. מגדירים את המאפיין position של האובייקט למיקום הסמן שהועבר:
StreetViewPanoramaOptions options =
       new StreetViewPanoramaOptions().position(
               marker.getPosition());
  1. יוצרים מופע חדש של SupportStreetViewPanoramaFragment ומעבירים את האובייקט options שיצרתם:
SupportStreetViewPanoramaFragment streetViewFragment
       = SupportStreetViewPanoramaFragment
       .newInstance(options);
  1. התחלת טרנזקציה של מקטעים. החלפת התוכן של מאגר המקטעים במקטע החדש, streetViewFragment. מוסיפים את העסקה למקבץ האחורי כדי שלחיצה על 'חזרה' תנווט חזרה אל SupportMapFragment ולא תצא מהאפליקציה:
getSupportFragmentManager().beginTransaction()
       .replace(R.id.fragment_container,
               streetViewFragment)
       .addToBackStack(null).commit();
  1. התקשרות אל setInfoWindowClickToPanorama(mMap) בעוד onMapReady() אחרי השיחה אל setPoiClick().
  2. מפעילים את האפליקציה. מתקרבים לעיר שיש בה כיסוי של Street View, למשל Mountain View (משרדי המשרדים הראשיים של Google), ומחפשים נקודת עניין, כמו פארק. מקישים על נקודת העניין כדי למקם סמן ולהציג את חלון המידע. מקישים על חלון המידע כדי להיכנס למצב Street View לגבי מיקום הסמן. כדי לחזור למקטע במפה, לוחצים על לחצן 'הקודם'.

Google Street View באפליקציה ל-Android

7. קוד פתרון

Wander קוד פתרון.

8. אתגר תכנות

אתגר: אם תקישו על חלון המידע של נקודת עניין במיקום שבו אין כיסוי של Street View, יוצג מסך שחור.

9. סיכום

  • כדי להשתמש ב-API של מפות Google, אתם זקוקים למפתח API מ-Google API Console.
  • ב-Android Studio, השימוש בתבנית הפעילות במפות Google יוצר Activity עם SupportMapFragment יחיד בפריסה של האפליקציה. התבנית גם מוסיפה את ACCESS_FINE_PERMISSION לקובץ המניפסט של האפליקציה, מטמיעה את OnMapReadyCallback בפעילות שלך ומחליפה את ה-method הנדרש onMapReady().

כדי לשנות את סוג המפה של GoogleMap בזמן ריצה, צריך להשתמש בשיטה GoogleMap.setMapType(). מפת Google יכולה להיות אחת מסוגי המפות הבאים:

  • רגילה: מפת דרכים אופיינית. מוצגים בו כבישים, חלקם שנבנו על ידי בני אדם, ותכונות טבעיות חשובות כמו נהרות. אפשר לראות גם את התוויות של הדרכים והתכונות.
  • היברידי: נתוני צילומי לוויין שנוספו עם מפות הכבישים. אפשר לראות גם את התוויות של הדרכים והתכונות.
  • לוויין: נתוני צילום. התוויות של הדרכים והתכונות לא גלויות.
  • פני השטח: נתונים טופוגרפיים. המפה כוללת צבעים, תוויות וקווים של קווי מתאר והצללה של נקודות מבט. גם חלק מהכבישים והתוויות מוצגים.
  • ללא**:** אין מפה.

מידע על מפות Google:

  • סמן הוא מדד של מיקום גיאוגרפי ספציפי.
  • כשמקישים עליו, התנהגות ברירת המחדל של הסמן היא להציג חלון מידע עם מידע על המיקום.
  • כברירת מחדל, נקודות עניין (POI) מופיעות במפה הבסיסית עם הסמלים המתאימים שלהן. נקודות העניין כוללות פארקים, בתי ספר, בנייני ממשלה ועוד.
  • כמו כן, נקודות עניין של עסקים (חנויות, מסעדות, מלונות ועוד) מופיעות במפה כברירת מחדל כאשר סוג המפה הוא normal.
  • ניתן לתעד קליקים על נקודות עניין באמצעות OnPoiClickListener.
  • ניתן לשנות את המראה החזותי של כמעט כל הרכיבים במפת Google באמצעות אשף העיצוב. אשף העיצוב יוצר קובץ JSON שמעבירים למפה של Google באמצעות השיטה setMapStyle().
  • תוכל להתאים אישית את הסמנים על ידי שינוי צבע ברירת המחדל או החלפת סמל ברירת המחדל של הסמן בתמונה מותאמת אישית.

עוד מידע חשוב:

  • אפשר להשתמש בשכבת-על של קרקע כדי לתקן תמונה במיקום גיאוגרפי.
  • משתמשים באובייקט GroundOverlayOptions כדי לציין את התמונה, את גודל התמונה במטרים ואת מיקום התמונה. מעבירים את האובייקט הזה לשיטה GoogleMap.addGroundOverlay() כדי להגדיר את שכבת-העל למפה.
  • אם לאפליקציה שלך יש את ההרשאה ACCESS_FINE_LOCATION, אפשר להפעיל מעקב אחר מיקום באמצעות השיטה mMap.setMyLocationEnabled(true).
  • Google Street View מספק תצוגות פנורמיות של 360 מעלות מכבישים ייעודיים ברחבי אזור הכיסוי.
  • אפשר להשתמש בשיטה StreetViewPanoramaFragment.newInstance() כדי ליצור מקטע חדש ב-Street View.
  • כדי לציין אפשרויות לתצוגה, משתמשים באובייקט StreetViewPanoramaOptions. מעבירים את האובייקט ל-method newInstance().

10. מידע נוסף

מסמכי התיעוד הקשורים למושגים זמינים במאמר 9.1: Google Maps API.

מסמכי תיעוד למפתחים של Android:

מסמכי עזר:

11. שיעורי בית

בקטע הזה מפורטות מטלות אפשריות לשיעורי הבית לתלמידים שעובדים על Codelab הזה כחלק מקורס שמעביר מורה. המדריך אחראי לבצע את הפעולות הבאות:

  • אם צריך, אפשר להקצות שיעורי בית.
  • להסביר לתלמידים איך להגיש מטלות של שיעורי הבית.
  • לתת ציונים למטלות של שיעורי הבית.

מורים יכולים להשתמש בהצעות האלה לפי מה שהם רוצים, והם יכולים לתת להם שיעורי בית מתאימים אם הם מרגישים שהם מתאימים.

אם אתם עובדים בעצמכם באמצעות ה-Codelab הזה, אתם מוזמנים להשתמש במטלות של שיעורי הבית האלה כדי לבחון את הידע שלכם.

יצירה והפעלה של אפליקציה

  1. ליצור אפליקציה חדשה שמשתמשת בתבנית 'פעילות במפות Google', שטוענת את מפות Google כשהאפליקציה מופעלת.
  2. אחרי שאפליקציית מפות Google נטענת, מזיזים את המצלמה למיקום של בית הספר, למיקום של הבית או למיקום אחר שיש לו משמעות עבורכם.
  3. אפשר להוסיף שני סמנים למפה, אחד במיקום של בית הספר והשני בבית או במיקום משמעותי אחר.
  4. ניתן להתאים אישית את סמלי הסמנים על ידי שינוי צבע ברירת המחדל או החלפת סמל ברירת המחדל של הסמן בתמונה מותאמת אישית.

רמז: עיינו במסמכי התיעוד של onMapReady (GoogleMap googleMap).

אפשר להשיב על השאלות הבאות

שאלה 1

לאיזו שיטה מתבצעת הקריאה כשהמפה נטענת ומוכנה לשימוש באפליקציה?

שאלה 2

באילו רכיבי Android אפשר להשתמש כדי לכלול את מפות Google באפליקציה?

  • MapView וגם MapFragment
  • MapFragment וגם MapActivity
  • MapView וגם MapActivity
  • רק MapFragment

שאלה 3

אילו סוגי מפות זמינים ב-Google Maps Android API?

  • רגילה, היברידית, פני שטח, לוויין ומפת דרכים
  • רגילה, היברידית, פני שטח, לוויין או ללא
  • היברידי, פני שטח, לוויין, מפת דרכים וגם ללא
  • רגילה, פני שטח, לוויין, מפת תמונה או ללא

שאלה 4

איזה ממשק אתם מיישמים כדי להוסיף פונקציונליות בלחיצה על נקודת עניין (POI)?

  • GoogleMap.OnPoiListener
  • GoogleMap.OnPoiClickListener
  • GoogleMap.OnPoiClick
  • GoogleMap.OnPoiClicked

שליחת האפליקציה למתן ציונים

הדרכה לתלמידי הכיתה

צריך לבדוק שהאפליקציה כוללת את התכונות הבאות:

  • כשהאפליקציה מופעלת, מפת Google מוצגת כמו שצריך, כדי לציין שמפתח API נוצר בצורה תקינה.
  • אחרי שמפת Google נטענת, המצלמה עוברת לבית או לבית הספר של התלמיד. בקוד, השלב הזה צריך להתרחש בשיטת הקריאה החוזרת (callback) של onMapReady (GoogleMap googleMap).
  • הסמנים מוצגים במיקום של בית הספר ובמיקום אחר, למשל הבית של התלמיד.
  • שני הסמנים מותאמים אישית. לדוגמה, הסמנים משתמשים בצבע שונה מהצבע האדום שמוגדר כברירת מחדל, או שהם משתמשים בסמל מותאם אישית.

12. ה-Codelab הבא

כדי לראות את כל שיעורי ה-codelab בקורס ההדרכה בנושא פיתוח מתקדם של Android, אפשר לבקר בדף הנחיתה של Advanced Android Development codelabs.