מעבדת קוד זו היא חלק מהקורס המתקדם של Android בקורס Kotlin. כדי להפיק את המקסימום מהקורס הזה, אם עובדים על מעבדות הקוד ברצף, לא חובה לעשות זאת. כל שיעורי הקוד של הקורסים מופיעים בדף הנחיתה המתקדם של Android ב-Kotlin codelabs.
יצירת אפליקציות באמצעות מפות Google מאפשרת לכם להוסיף תכונות לאפליקציה, כמו תמונות לוויין, פקדי ממשק משתמש חזקים למפות Google, מעקב אחר מיקום וסמני מיקום. ניתן להוסיף ערך למפות Google הרגילות על ידי הצגת מידע ממערך הנתונים שלכם, כמו מיקומים של אזורי דיג או טיפוס ידועים. יש גם אפשרות ליצור משחקים שבהם השחקן מגלה את העולם הפיזי, למשל חיפוש אחר אוצרות או משחקים של מציאות רבודה.
בשיעור הזה אתם יוצרים אפליקציה של מפות Google בשם Wander, שמציגה מפות מותאמות אישית ומציגה את המיקום של המשתמש.
דרישות מוקדמות
הידע הזה:
- איך ליצור אפליקציה בסיסית ל-Android ולהפעיל אותה באמצעות Android Studio.
- איך יוצרים ומנהלים משאבים כמו מחרוזות?
- איך להגדיר מחדש את הקוד ולשנות את השם של משתנים באמצעות Android Studio.
- איך להשתמש במפה של Google כמשתמש.
- איך להגדיר הרשאות בזמן ריצה.
מה תלמדו
- איך מקבלים מפתח API מ-Google API Console ורושמים את המפתח לאפליקציה
- איך לשלב את 'מפות Google' באפליקציה
- איך להציג סוגי מפות שונים
- איך לעצב את המפה של Google
- איך להוסיף סמנים למפה
- איך מאפשרים למשתמש להציב סמן בנקודת עניין (POI)
- איך מפעילים מעקב אחר מיקום?
- איך ליצור את האפליקציה
Wander
, שכוללת מפת Google מוטמעת - איך ליצור תכונות מותאמות אישית לאפליקציה, כמו סמנים וסגנון
- איך להפעיל מעקב אחר מיקום באפליקציה
ב-lab זה אתם יוצרים את האפליקציה Wander
, המציגה מפת Google עם סגנון מותאם אישית. אפליקציית וונדר מאפשרת לך להציב סמנים במיקומים שונים, להוסיף שכבות-על ולראות את המיקום שלך בזמן אמת.
ל-SDK של מפות Google ל-Android נדרש מפתח API. כדי לקבל את מפתח ה-API, רושמים את הפרויקט בדף API & שירותים. מפתח ה-API מקושר לאישור דיגיטלי המקשר את האפליקציה אל המחבר שלו. למידע נוסף על השימוש באישורים דיגיטליים ועל חתימת האפליקציה, יש לעיין במאמר חתימת האפליקציה שלך.
ב-codelab זה אתם משתמשים במפתח ה-API לאישור ניפוי הבאגים. אישור ניפוי הבאגים לא מאובטח בעיצוב, כפי שמתואר בחתימה על גרסת ה-build של ניפוי באגים. לאפליקציות Android שפורסמו שמשתמשות ב-Maps SDK ל-Android נדרש מפתח API שני: המפתח של אישור הגרסה. מידע נוסף על קבלת אישור גרסה זמין במאמר קבלת מפתח API.
Android Studio כולל תבנית פעילות של מפות Google, שיוצרת קוד תבנית מועיל. קוד התבנית כולל קובץ מסוג google_maps_api.xml שמכיל קישור שמפשט את קבלת מפתח API.
שלב 1: יצירת פרויקט Wander באמצעות התבנית של מפות Google
- יוצרים פרויקט חדש ב-Android Studio.
- בוחרים בתבנית פעילות במפות Google.
- נותנים שם לפרויקט
Wander
. - מגדירים את רמת ה-API המינימלית ל-API 19. מוודאים שהשפה היא Kotlin.
- לוחצים על סיום.
- לאחר סיום הבנייה של האפליקציה, כדאי לבדוק את הפרויקט שלכם ואת הקבצים הבאים של מפות Google שמערכת Android Studio יוצרת עבורכם:
google_maps_api.xml — קובץ התצורה הזה משמש אתכם כדי לשמור את מפתח ה-API. התבנית יוצרת שני קובצי google_maps_api.xml: אחד לניפוי באגים וקובץ אחד לגרסה. הקובץ של מפתח ה-API של אישור ניפוי הבאגים נמצא ב-src/debug/res/values. הקובץ של מפתח ה-API של אישור הגרסה נמצא ב-src/release/res/values. ב-codelab זה תשתמשו רק באישור ניפוי הבאגים.
activity_maps.xml – קובץ הפריסה הזה מכיל שבר יחיד שממלא את כל המסך. הכיתה SupportMapFragment
היא סיווג משנה של הכיתה Fragment
. SupportMapFragment
הוא הדרך הפשוטה ביותר למקם מפה באפליקציה. זוהי עיטוף מסביב לתצוגה של מפה שעונה על צורכי מחזור החיים הנדרשים באופן אוטומטי.
אפשר לכלול את SupportMapFragment
בקובץ פריסה באמצעות תג <fragment>
בכל ViewGroup
, עם מאפיין name
נוסף.
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.JavaScript – הקובץ MapsActivity.kt יוצר את SupportMapFragment
בשיטה onCreate()
ומשתמש במחלקה&339. getMapAsync
()
כדי לאתחל באופן אוטומטי את מערכת המפות ואת התצוגה. הפעילות שמכילה את SupportMapFragment
חייבת להטמיע את הממשק OnMapReadyCallback
ואת שיטת onMapReady()
הממשק הזה. מתבצעת קריאה לשיטת onMapReady()
כאשר המפה נטענת.
שלב 2: קבלת מפתח API
- פותחים את גרסת ניפוי הבאגים של הקובץ google_maps_api.xml.
- בקובץ, מחפשים הערה עם כתובת URL ארוכה. הפרמטרים של כתובת האתר כוללים מידע ספציפי על האפליקציה שלך.
- מעתיקים את כתובת ה-URL ומדביקים אותה בדפדפן.
- מבצעים את ההנחיות ליצירת פרויקט בדף ממשקי ה-API ושירותי AMP. בשל הפרמטרים בכתובת ה-URL שצוינה, הדף יודע להפעיל את ה-SDK של מפות Google ל-Android באופן אוטומטי.
- לוחצים על יצירת מפתח API.
- בדף הבא, עוברים לקטע 'מפתחות API' ולוחצים על המפתח שיצרתם.
- לוחצים על הגבלת מקש ובוחרים באפשרות SDK של מפות Google ל-Android כדי להגביל את השימוש במפתח למפתח לאפליקציות ל-Android.
- מעתיקים את מפתח ה-API שנוצר. הוא מתחיל ב-"
AIza"
. - בקובץ
google_maps_api.xml
, מדביקים את המפתח במחרוזתgoogle_maps_key
במקום שבו כתובYOUR_KEY_HERE
. - מריצים את האפליקציה. אמורה להופיע מפה מוטמעת בפעילות שלכם עם סמן שמוגדר בסידני, אוסטרליה. (הסמן בסידני הוא חלק מהתבנית ומשנים אותו מאוחר יותר).
שלב 3: שינוי שם המפה
לMapsActivity
יש lateinit
var
פרטי בשם mMap
, מסוג GoogleMap
. כדי לפעול בהתאם למוסכמות של Cotlin למתן שמות, יש לשנות את השם של mMap
ל-map
.
- ב-
MapsActivity
, לוחצים לחיצה ימנית עלmMap
ואז לוחצים על Refactor > שינוי שם...
- משנים את השם של המשתנה לשם
map
.
שימו לב איך כל ההפניות ל-mMap
בפונקציה onMapReady()
משתנות גם ל-map
.
במפות Google יש כמה סוגי מפות: רגיל, היברידי, לוויין, פני שטח ו-"ללא" (ללא מפה כלל).
מפה רגילה | מפת לוויין | מפה היברידית | מפת פני השטח |
כל סוג של מפה מספק מידע מסוגים שונים. לדוגמה, בעת שימוש במפות לניווט במכונית, מומלץ לראות את שמות הרחובות כדי להשתמש באפשרות הרגילה. כשאתם מטיילים, מפת פני השטח יכולה לעזור לכם להחליט כמה טיפוס אתם צריכים כדי להגיע לפסגה.
במשימה הזו:
- יש להוסיף סרגל אפליקציות עם תפריט אפשרויות שמאפשר למשתמש לשנות את סוג המפה.
- מזיזים את המפה כדי לפתוח את מיקום הבית שלכם.
- להוסיף תמיכה בסמנים שמציינים מיקומים יחידים במפה ויכולים לכלול תווית.
הוספת תפריט לסוגי מפות
בשלב זה מוסיפים סרגל אפליקציות עם תפריט אפשרויות שמאפשר למשתמש לשנות את סוג המפה.
- כדי ליצור קובץ XML חדש, לוחצים לחיצה ימנית על ספריית res ובוחרים באפשרות חדש > קובץ משאבים של Android.
- בתיבת הדו-שיח, נותנים לקובץ את השם
map_options
. - בוחרים באפשרות תפריט עבור סוג המשאב.
- לוחצים על אישור.
- בכרטיסייה קוד, מחליפים את הקוד בקובץ החדש בקוד הבא כדי ליצור את אפשרויות תפריט המפה. הסוג של &מירכאות;none" תנועה מושמטת כי &jpg;none" לא מתקבל בכלל מפה כלשהי. שלב זה גורם לשגיאה, אבל אתם פותרים אותו בשלב הבא.
<?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>
- ב-
strings.xml
, יש להוסיף משאבים למאפייןtitle
כדי לפתור את השגיאות.
<resources>
...
<string name="normal_map">Normal Map</string>
<string name="hybrid_map">Hybrid Map</string>
<string name="satellite_map">Satellite Map</string>
<string name="terrain_map">Terrain Map</string>
<string name="lat_long_snippet">Lat: %1$.5f, Long: %2$.5f</string>
<string name="dropped_pin">Dropped Pin</string>
<string name="poi">poi</string>
</resources>
- ב-
MapsActivity
, יש לעקוף את השיטהonCreateOptionsMenu()
ולנפח את התפריט מתוך קובץ המשאבmap_options
.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.map_options, menu)
return true
}
- ב
MapsActivity.kt
, יש לשנות את השיטהonOptionsItemSelected()
. משנים את סוג המפה באמצעות קבועים מסוג מפה כך שישקפו את בחירת המשתמש.
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
// Change the map type based on the user's selection.
R.id.normal_map -> {
map.mapType = GoogleMap.MAP_TYPE_NORMAL
true
}
R.id.hybrid_map -> {
map.mapType = GoogleMap.MAP_TYPE_HYBRID
true
}
R.id.satellite_map -> {
map.mapType = GoogleMap.MAP_TYPE_SATELLITE
true
}
R.id.terrain_map -> {
map.mapType = GoogleMap.MAP_TYPE_TERRAIN
true
}
else -> super.onOptionsItemSelected(item)
}
- מריצים את האפליקציה.
- כדי לשנות את סוג המפה צריך ללחוץ על . שימו לב איך המראה של המפה משתנה בין המצבים השונים.
כברירת מחדל, הקריאה החוזרת (onMapReady()
) בהתקשרות כוללת קוד שמציב סמן בסידני, אוסטרליה, שבו נוצר מפות Google. הקריאה החוזרת (callback) המוגדרת כברירת מחדל גם מוסיפה את המפה להזזה לסידני.
במשימה הזו, עליך להזיז את המצלמה של המפה לבית, לשנות את מרחק התצוגה עד לנקודה מסוימת שבחרת ולהציב שם סמן.
שלב 1: התקרבות לבית והוספת סמן
- בקובץ
MapsActivity.kt
, מאתרים את השיטהonMapReady()
. הסירו את הקוד שמציב את הסמן בסידני ומזיז את המצלמה. כך צריכה להיראות שיטה שלך עכשיו.
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
}
- מחפשים את קווי האורך והרוחב של הבית שלכם לפי ההוראות האלה.
- יוצרים ערך עבור קו הרוחב וערך עבור קו האורך, ומזינים את ערכי הצף שלהם.
val latitude = 37.422160
val longitude = -122.084270
- יצירת אובייקט
LatLng
חדש בשםhomeLatLng
. באובייקטhomeLatLng
, יש להעביר את הערכים שיצרתם עכשיו.
val homeLatLng = LatLng(latitude, longitude)
- אפשר ליצור
val
לציון המרחק מהתצוגה במפה. שינוי מרחק התצוגה 15f.
val zoomLevel = 15f
רמת המרחק מהתצוגה קובעת את המרחק מהתצוגה במפה. הרשימה הבאה מספקת מושג לגבי רמת הפירוט המוצגת לכל רמת זום:
1
: בעולם5
: יבשה/יבשת10
: עיר15
: רחובות20
: בניינים
- יש להעביר את המצלמה אל
homeLatLng
על ידי קריאה לפונקציהmoveCamera()
באובייקטmap
והעברה של אובייקטCameraUpdate
באמצעותCameraUpdateFactory.newLatLngZoom()
. יש להעביר את האובייקטhomeLatLng
ואתzoomLevel
.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
- הוספת סמן למפה ב-
homeLatLng
.
map.addMarker(MarkerOptions().position(homeLatLng))
השיטה הסופית אמורה להיראות כך:
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
//These coordinates represent the latitude and longitude of the Googleplex.
val latitude = 37.422160
val longitude = -122.084270
val zoomLevel = 15f
val homeLatLng = LatLng(latitude, longitude)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
map.addMarker(MarkerOptions().position(homeLatLng))
}
- מריצים את האפליקציה. המפה צריכה להזיז את הבית, לשנות את מרחק התצוגה לרמה הרצויה ולהציב סמן בבית.
שלב 2: מאפשרים למשתמשים להוסיף סמן בלחיצה ארוכה
בשלב זה מוסיפים סמן כשהמשתמש נוגע במיקום ומחזיק את המיקום שלו במפה.
- יוצרים גרש שיטה ב-
MapsActivity
, שמכונהsetMapLongClick()
ומגדיר אתGoogleMap
כארגומנט. - צירוף אובייקט מסוג
setOnMapLongClickListener
לאובייקט המפה.
private fun setMapLongClick(map:GoogleMap) {
map.setOnMapLongClickListener { }
}
- ב
setOnMapLongClickListener()
, יש להתקשר לשיטהaddMarker()
. יש להעביר אובייקטMarkerOptions
חדש עם המיקום המוגדר כ-LatLng
שהועבר.
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
map.addMarker(
MarkerOptions()
.position(latLng)
)
}
}
- בסוף השיטה
onMapReady()
צריך להתקשר אלsetMapLongClick()
עםmap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapLongClick(map)
}
- מפעילים את האפליקציה.
- לוחצים לחיצה ארוכה על המפה כדי למקם סמן במיקום מסוים.
- מקישים על הסמן, שהוא מרכז אותו במסך.
שלב 3: מוסיפים חלון מידע לסמן
בשלב זה מוסיפים InfoWindow
שמציג את הקואורדינטות של הסמן כאשר מקישים על הסמן.
- ב
setMapLongClick()setOnMapLongClickListener()
, יש ליצורval
עבורsnippet
. קטע טקסט הוא טקסט נוסף המוצג אחרי הכותרת. קטע הטקסט מציג את קווי האורך והרוחב של סמן.
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
// A snippet is additional text that's displayed after the title.
val snippet = String.format(
Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude
)
map.addMarker(
MarkerOptions()
.position(latLng)
)
}
}
- ב-
addMarker()
, צריך להגדיר אתtitle
של הסמן כסיכה שמוקמה באמצעות משאב מחרוזתR.string.
dropped_pin
. - מגדירים את הסמן's
snippet
כ-snippet
.
הפונקציה שבוצעה נראית כך:
private fun setMapLongClick(map: GoogleMap) {
map.setOnMapLongClickListener { latLng ->
// A Snippet is Additional text that's displayed below the title.
val snippet = String.format(
Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude
)
map.addMarker(
MarkerOptions()
.position(latLng)
.title(getString(R.string.dropped_pin))
.snippet(snippet)
)
}
}
- מפעילים את האפליקציה.
- לוחצים לחיצה ארוכה על המפה כדי לשחרר סמן של מיקום.
- מקישים על הסמן כדי להציג את חלון המידע.
שלב 4: הוספת event listener
כברירת מחדל, נקודות עניין מופיעות במפה יחד עם הסמלים שלהן. נקודות עניין כוללות פארקים, בתי ספר, בניינים ממשלתיים ועוד. כשסוג המפה מוגדר ל-normal
, יופיעו במפה גם נקודות עניין עסקיות. נקודות עניין עסקיות מייצגות עסקים, כמו חנויות, מסעדות ומלונות.
בשלב זה מוסיפים GoogleMap.OnPoiClickListener
למפה. event listener מסוג זה מציב סמן במפה באופן מיידי כשהמשתמש לוחץ על נקודת עניין. event listener מציג גם חלון מידע המכיל את שם נקודת העניין.
- יוצרים גרש שיטה ב-
MapsActivity
, שמכונהsetPoiClick()
ומגדיר אתGoogleMap
כארגומנט. - בשיטה
setPoiClick()
, יש להגדירOnPoiClickListener
במכשירGoogleMap
שיועבר.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
}
}
- ב
setOnPoiClickListener()
, יוצריםval poiMarker
לסמן . - יש להגדיר את הסמן כ-
map.addMarker()
באמצעותMarkerOptions
ולהגדיר אתtitle
כשם של נקודת העניין.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
}
}
- בפונקציה
setOnPoiClickListener()
, צריך להתקשר אלshowInfoWindow()
ב-poiMarker
כדי להציג מיד את חלון המידע.
poiMarker.showInfoWindow()
הקוד הסופי של הפונקציה setPoiClick()
אמור להיראות כך.
private fun setPoiClick(map: GoogleMap) {
map.setOnPoiClickListener { poi ->
val poiMarker = map.addMarker(
MarkerOptions()
.position(poi.latLng)
.title(poi.name)
)
poiMarker.showInfoWindow()
}
}
- בסוף יום
onMapReady()
, יש להתקשר אלsetPoiClick()
ולעבור אלmap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setPoiClick(map)
}
- אפשר להפעיל את האפליקציה ולמצוא נקודת עניין, כמו פארק או בית קפה.
- יש להקיש על נקודת העניין כדי להציב עליה סמן ולהציג את השם של נקודת העניין בחלון מידע.
ניתן להתאים אישית את מפות Google בדרכים רבות, וכך להעניק למפה מראה ותחושה ייחודיים.
ניתן להתאים אישית אובייקט MapFragment
באמצעות מאפייני ה-XML הזמינים, כפי שניתן להתאים אישית כל קטע אחר. עם זאת, בשלב זה מתאימים אישית את המראה והתחושה של התוכן של MapFragment
, ומשתמשים בשיטות באובייקט GoogleMap
.
כדי ליצור סגנון מותאם אישית במפה, אתם יוצרים קובץ JSON שמציין את אופן ההצגה של התכונות במפה. אין צורך ליצור את קובץ ה-JSON הזה באופן ידני. Google מספקת את האשף לעיצוב מפות ב'מפות', שיוצר עבורך את קובץ ה-JSON אחרי עיצוב הסגנון של המפה. במשימה הזו לסגנן את המפה בעיצוב של רטרו, והמשמעות היא שהמפה משתמשת בצבעי וינטג' ואתם מוסיפים כבישים צבעוניים.
שלב 1: יצירת סגנון למפה
- עוברים לכתובת https://mapstyle.withgoogle.com/ בדפדפן.
- בוחרים באפשרות יצירת סגנון.
- לוחצים על רטרו.
- לוחצים על אפשרויות נוספות.
- ברשימה סוג התכונה, בוחרים באפשרות כביש > מילוי.
- משנים את צבע הכביש לכל צבע שרוצים (למשל, ורוד).
- לוחצים על סיום.
- מעתיקים את קוד ה-JSON מתיבת הדו-שיח המתקבלת, ואם רוצים, מסתירים אותו בהערה בטקסט פשוט לשימוש בשלב הבא.
שלב 2: הוספת הסגנון למפה
- ב-Android Studio, בספרייה
res
, יוצרים ספריית משאבים וקוראים להraw
. נעשה שימוש במשאבים שבספרייהraw
, כמו קוד JSON. - יצירת קובץ ב-
res/raw
בשםmap_style.json
. - מדביקים את קוד ה-JSON שבמטמון בקובץ הקובץ החדש.
- ב-
MapsActivity
, יוצרים משתנהTAG
מעל לשיטהonCreate()
. הפרטים האלה משמשים למטרות רישום ביומן.
private val TAG = MapsActivity::class.java.simpleName
- גם ב-
MapsActivity
צריך ליצור פונקציה ב-setMapStyle()
שמקבלתGoogleMap
. - ב-
setMapStyle()
, יש להוסיף בלוק שלtry{}
. - בבלוק
try{}
, יוצריםval success
כדי ליהנות מסטיילינג. (אתם מוסיפים את בלוק ה-catch הבא.) - בבלוק
try{}
, מגדירים את סגנון ה-JSON למפה, קוראים ל-setMapStyle()
באובייקטGoogleMap
. יש להעביר אובייקטMapStyleOptions
שטוען את קובץ ה-JSON. - הקצאת התוצאה ל-
success
. השיטהsetMapStyle()
מחזירה בוליאני שמציין את סטטוס ההצלחה של ניתוח קובץ הסגנון והגדרת הסגנון.
private fun setMapStyle(map: GoogleMap) {
try {
// Customize the styling of the base map using a JSON object defined
// in a raw resource file.
val success = map.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this,
R.raw.map_style
)
)
}
}
- יש להוסיף הצהרת if עבור
success
. אם הסגנון לא הצליח, מדפיסים יומן שהניתוח נכשל.
private fun setMapStyle(map: GoogleMap) {
try {
...
if (!success) {
Log.e(TAG, "Style parsing failed.")
}
}
}
- יש להוסיף בלוק
catch{}
כדי לטפל במצב של קובץ סגנון חסר. בקטעcatch
, אם לא ניתן לטעון את הקובץ, יש להשליך את הקובץResources.NotFoundException
.
private fun setMapStyle(map: GoogleMap) {
try {
...
} catch (e: Resources.NotFoundException) {
Log.e(TAG, "Can't find style. Error: ", e)
}
}
השיטה הסופית צריכה להיראות כמו קטע הקוד הבא:
private fun setMapStyle(map: GoogleMap) {
try {
// Customize the styling of the base map using a JSON object defined
// in a raw resource file.
val success = map.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this,
R.raw.map_style
)
)
if (!success) {
Log.e(TAG, "Style parsing failed.")
}
} catch (e: Resources.NotFoundException) {
Log.e(TAG, "Can't find style. Error: ", e)
}
}
- לבסוף, יש להתקשר לשיטה
setMapStyle()
בשיטהonMapReady()
שעוברת באובייקטGoogleMap
.
override fun onMapReady(googleMap: GoogleMap) {
...
setMapStyle(map)
}
- מפעילים את האפליקציה.
- יש להגדיר את המפה למצב
normal
והסגנון החדש צריך להיות גלוי עם כבישים בסגנון רטרו וכבישים בצבע הרצוי.
שלב 3: עיצוב הסמן
אפשר להתאים אישית את המפה עוד יותר על ידי עיצוב הסמני המפה. בשלב זה אתה משנה את הסמנים האדומים המוגדרים כברירת מחדל למשהו בסגנון מגניב יותר.
- בשיטה
onMapLongClick()
, יש להוסיף את שורת הקוד הבאה ל-MarkerOptions()
של המבנה כדי להשתמש בסמן ברירת המחדל, אבל לשנות את הצבע לכחול.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
עכשיו נראה onMapLongClickListener()
כך:
map.setOnMapLongClickListener { latLng ->
// A snippet is additional text that's displayed after the title.
val snippet = String.format(
Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude
)
map.addMarker(
MarkerOptions()
.position(latLng)
.title(getString(R.string.dropped_pin))
.snippet(snippet)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
)
}
- מריצים את האפליקציה. הסימונים שמופיעים אחרי לחיצה ארוכה מופיעים עכשיו בכחול. לתשומת ליבך, סמנים של נקודות עניין צבעוניות עדיין אדומים כי לא הוספת סגנון לשיטה
onPoiClick()
.
אחת הדרכים להתאים אישית את מפת Google היא באמצעות ציור מעליה. ניתן להשתמש בשיטה זו כדי להדגיש סוג מסוים של מיקום, כגון אתרי דיג פופולריים.
- צורות: ניתן להוסיף למפה מצולעים, מצולעים ועיגולים.
GroundOverlay
אובייקטים: שכבת-על של קרקע היא תמונה הקבועה במפה. בניגוד לסמנים, שכבות-העל של הקרקע מיועדות לפני השטח של כדור הארץ ולא למסך. סיבוב, הטיה או זום של המפה משנים את הכיוון של התמונה. שכבות-על של קרקע הן שימושיות אם ברצונך לתקן תמונה אחת באזור אחד במפה.
שלב: הוספת שכבת-על של קרקע
במשימה הזו, מוסיפים שכבת-על של קרקע בצורת Android למיקום הבית.
- צריך להוריד את התמונה הזו מ-Android ולשמור אותה בתיקייה
res/drawable
. (צריך לוודא ששם הקובץ הואandroid.png
.)
- בעוד
onMapReady()
, אחרי השיחה כדי להעביר את המצלמה למיקום הבית, צריך ליצור אובייקטGroundOverlayOptions
. - מקצים את האובייקט למשתנה בשם
androidOverlay
.
val androidOverlay = GroundOverlayOptions()
- יש להשתמש בשיטה
BitmapDescriptorFactory.fromResource()
כדי ליצור אובייקטBitmapDescriptor
ממשאב התמונות שהורדתם. - יש להעביר את האובייקט
BitmapDescriptor
אל שיטתimage()
של האובייקטGroundOverlayOptions
.
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
- יוצרים
float overlaySize
עבור הרוחב במטרים של שכבת-העל הרצויה. בדוגמה הזו, הרוחב של100f
פועל היטב.
יש להגדיר את המאפיין position
עבור האובייקט GroundOverlayOptions
על ידי קריאה לשיטה position()
והעברתו באובייקט homeLatLng
וברכיב overlaySize
.
val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
.position(homeLatLng, overlaySize)
- התקשרות אל
addGroundOverlay()
באובייקטGoogleMap
והעבירה את האובייקט שלGroundOverlayOptions
.
map.addGroundOverlay(androidOverlay)
- מריצים את האפליקציה.
- שנה את הערך של
zoomLevel
ל-18f כדי לראות את תמונת Android כשכבת-על.
משתמשים משתמשים במפות Google לעיתים קרובות כדי לראות את המיקום הנוכחי שלהם. כדי להציג את מיקום המכשיר במפה, אפשר להשתמש בשכבת נתוני המיקום.
שכבת נתוני המיקום מוסיפה למפה את המיקום שלי. כשהמשתמש מקיש על הלחצן, המפה מתרכזת במיקום המכשיר. המיקום מוצג כנקודה כחולה אם המכשיר הוא נייח ושבר הצגה כחול אם המכשיר זז.
במשימה הזו מפעילים את שכבת נתוני המיקום.
שלב: בקשת הרשאות מיקום
הפעלה של מעקב אחר מיקום במפות Google מחייבת שורת קוד אחת. עם זאת, עליך לוודא שהמשתמש העניק הרשאות מיקום (באמצעות מודל ההרשאה לזמן ריצה).
בשלב זה, אתם מבקשים הרשאות מיקום ומפעילים את המעקב אחר המיקום.
- בקובץ
AndroidManifest.xml
יש לוודא שההרשאהFINE_LOCATION
כבר קיימת. ההרשאה הזו הופעלה על ידי Android Studio כשבחרת בתבנית של מפות Google.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- ב-
MapsActivity
, יוצרים משתנה כיתהREQUEST_LOCATION_PERMISSION
.
private val REQUEST_LOCATION_PERMISSION = 1
- כדי לבדוק אם הרשאות הוענקו, יש ליצור שיטה ב-
MapsActivity
שנקראתisPermissionGranted()
. בשיטה הזו, בודקים אם המשתמש נתן את ההרשאה.
private fun isPermissionGranted() : Boolean {
return ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
- כדי להפעיל מעקב אחר מיקום באפליקציה שלך, יש ליצור שיטה ב-
MapsActivity
שנקראתenableMyLocation()
שלא מקבלת ארגומנטים ולא מחזירה דבר. בתוכו, יש לבדוק אם יש לך הרשאה ב-ACCESS_FINE_LOCATION
. אם ההרשאה הוענקה, מפעילים את שכבת המיקום. אם לא, מבקשים את ההרשאה.
private fun enableMyLocation() {
if (isPermissionGranted()) {
map.isMyLocationEnabled = true
}
else {
ActivityCompat.requestPermissions(
this,
arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_LOCATION_PERMISSION
)
}
}
- יש להתקשר אל
enableMyLocation()
מהשיחה החוזרת ב-onMapReady()
כדי להפעיל את שכבת המיקום.
override fun onMapReady(googleMap: GoogleMap) {
...
enableMyLocation()
}
- שינוי השיטה
onRequestPermissionsResult()
. אם הפרמטרrequestCode
שווה ל-REQUEST_LOCATION_PERMISSION
, ואם המערךgrantResults
לא ריק עםPackageManager.PERMISSION_GRANTED
במשבצת הראשונה, יש להתקשר אלenableMyLocation()
.
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray) {
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
enableMyLocation()
}
}
}
- מפעילים את האפליקציה. אמורה להיות תיבת דו-שיח שמבקשת גישה למיקום של המכשיר. זה הזמן לתת את ההרשאה.
המפה מציגה עכשיו את המיקום הנוכחי של המכשיר באמצעות נקודה כחולה. שימו לב שיש לחצן מיקום. אם תזיזו את המפה מהמיקום שלכם ותלחצו על הלחצן הזה, היא תמרכז את המפה בחזרה למיקום המכשיר.
צריך להוריד את הקוד של מעבדת הקוד המלאה.
$ git clone https://github.com/googlecodelabs/android-kotlin-geo-maps
לחלופין, אפשר להוריד את המאגר כקובץ ZIP, לפתוח אותו ב-Android Studio ולפתוח אותו.
- כדי להשתמש ב-API של מפות Google, צריך מפתח API ממסוף Google API.
- ב-Android Studio, השימוש בתבנית של פעילות במפות Google יוצר
Activity
עםSupportMapFragment
יחיד בפריסת האפליקציה. התבנית גם מוסיפה אתACCESS_FINE_PERMISSION
למניפסט של האפליקציה, ומטמיעה את ה-OnMapReadyCallback
בפעילות שלך, ומבטלת את שיטת החובהonMapReady()
.
כדי לשנות את סוג המפה של GoogleMap
בזמן ריצה, יש להשתמש בשיטה GoogleMap.setMapType()
. ניתן לבחור באחד מסוגי המפה הבאים:
- רגילה: מפת דרכים אופיינית. הצגת כבישים, תכונות מסוימות שנבנו על ידי בני אדם ותכונות טבעיות חשובות כמו נהרות. תוויות גם של כבישים ותכונות.
- היברידי: נתוני תמונה מלוויין עם מפות כבישים. תוויות גם של כבישים ותכונות.
- לוויין: צילום תמונות. תוויות של כבישים ותכונות לא גלויות.
- פני השטח: נתונים טופוגרפיים. המפה כוללת צבעים, קווים ותוויות קווי מתאר והצללה של נקודת המבט. גם חלק מהכבישים והתוויות גלויים.
- ללא: אין אריחי מפה בסיסית.
מידע על מפות Google:
- סמן הוא אינדיקטור של מיקום גיאוגרפי ספציפי.
- עם הקשה, התנהגות ברירת המחדל של הסמן היא להציג חלון מידע עם מידע על המיקום.
- כברירת מחדל, נקודות עניין מופיעות במפת הבסיס יחד עם הסמלים שלהן. נקודות עניין כוללות פארקים, בתי ספר, בניינים ממשלתיים ועוד.
- בנוסף, נקודות העניין של העסק (חנויות, מסעדות, בתי מלון ועוד) מופיעות במפה כברירת מחדל כשסוג המפה הוא
normal
. - אפשר לתעד קליקים על נקודות עניין באמצעות
OnPoiClickListener
. - אתם יכולים לשנות את המראה החזותי של כמעט כל הרכיבים במפת Google באמצעות אשף העיצוב. אשף הסטיילינג יוצר קובץ JSON שאתם מעבירים למפה Google דרך השיטה
setMapStyle()
. - ניתן להתאים אישית את הסמנים על ידי שינוי צבע ברירת המחדל או החלפה של סמל ברירת המחדל בסמן בתמונה מותאמת אישית.
עוד מידע חשוב:
- להשתמש בשכבת-על של קרקע כדי לתקן תמונה למיקום גיאוגרפי.
- משתמשים באובייקט
GroundOverlayOptions
כדי לציין את התמונה, גודל התמונה במטרים ומיקום התמונה. יש להעביר את האובייקט הזה לשיטתGoogleMap.addGroundOverlay()
כדי להגדיר את שכבת-העל במפה. - אפשר להפעיל את המעקב אחר המיקום על ידי הגדרה של
map.isMyLocationEnabled = true
, בתנאי שלאפליקציה שלך יש הרשאהACCESS_FINE_LOCATION
. - הוא לא נכלל במעבד הקוד הזה, אבל אתם יכולים לספק מידע נוסף על מיקום באמצעות Google Street View, שהוא תמונת פנורמה של מיקום שניתן לנווט אליו.
התיעוד של מפתח Android:
מסמכי עזר:
קישורים למעבדות אחרות של הקוד בקורס הזה זמינים בדף הנחיתה המתקדם של Android ב-Kotlin codelabs.