ניתן להשתמש ב-SDK לצרכנים כדי ליצור ולהפעיל אפליקציה בסיסית משולבת עם שירותים לקצה העורפי של פתרונות לנסיעות ולמשלוחים על פי דרישה. אפשר ליצור אפליקציה מסוג 'התקדמות והזמנה' שיכולה להציג נסיעה פעילה, להגיב לעדכוני נסיעה ולטפל בשגיאות בנסיעה.
מאחר של- Consumer SDK יש ארכיטקטורה מודולרית, אפשר להשתמש בחלקים של ה-API שבו רוצים להשתמש באפליקציה הספציפית ולשלב אותם עם ממשקי API משלכם, שירותים לקצה העורפי שמסופקים על ידי Fleet Engine, ולהוסיף את ממשקי ה-API של הפלטפורמה של מפות Google.
דרישות מערכת מינימליות
במכשיר הנייד צריכה לפעול מערכת Android 6.0 (API ברמה 23) ואילך.
הגדרת build ויחסי תלות
גרסאות 1.99.0 ואילך של SDK לצרכנים זמינות באמצעות Google Maven של מאגר הנתונים. ערוץ המאגר הפרטי שהיה בשימוש בעבר הוצא משימוש.
Gradle
מוסיפים לקובץ build.gradle
את הנתונים הבאים:
repositories {
...
google()
}
Maven
מוסיפים לקובץ pom.xml
את הנתונים הבאים:
<project>
...
<repositories>
<repository>
<id>google-maven-repository</id>
<url>https://maven.google.com</url>
</repository>
</repositories>
...
</project>
הגדרות הפרויקט
כדי להשתמש ב-SDK לצרכן עבור Android, האפליקציה שלך צריכה לטרגט
minSdkVersion
מגרסה 23 ואילך.
כדי להריץ אפליקציה שנוצרה באמצעות ה-SDK לצרכנים, ערכת ה-Android המכשיר חייב Google Play Services מותקנת.
הגדרת פרויקט פיתוח
הגדרת פרויקט פיתוח וקבלת מפתח API של הפרויקט במסוף Google Cloud:
יוצרים פרויקט חדש במסוף Google Cloud או בוחרים פרויקט קיים לשימוש לצרכנים ב-SDK. צריך לחכות כמה דקות עד שהפרויקט החדש יופיע במסוף Google Cloud.
כדי להפעיל את אפליקציית ההדגמה, לפרויקט שלך צריכה להיות גישה ל-SDK של מפות Google ל-Android. במסוף Google Cloud, ממשקי API שירותים > לספרייה ולאחר מכן לחפש ולהפעיל את ה-SDK של מפות Google עבור Android.
כדי לקבל מפתח API לפרויקט, בוחרים באפשרות ממשקי API שירותים > פרטי כניסה > יצירת פרטי כניסה > מפתח API. מידע נוסף על קבלת מפתח API זמין במאמר קבלת מפתח API
הוספת ה-SDK לצרכנים לאפליקציה
ערכת ה-SDK לצרכנים זמינה דרך מאגר Maven פרטי. מאגר כולל את קובצי Project Object Model (.pom) ואת Javadocs של ה-SDK. כדי להוסיף לאפליקציה את ערכת ה-SDK לצרכנים:
מגדירים את הסביבה כדי לגשת למאגר Maven המארח, כפי שמתואר ב בקטע הקודם.
אם הצהרת על הגדרה מרוכזת של ניהול תלות ב-
settings.gradle
, אפשר להשבית אותה לפי ההוראות שבהמשך.מסירים את בלוק הקוד הבא ב-
settings.gradle
:import org.gradle.api.initialization.resolve.RepositoriesMode dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
מוסיפים את התלות הבאה להגדרות של Gradle או Maven, ומחליפים את placeholder מסוג
VERSION_NUMBER
לגרסת ה-SDK הרצויה של הצרכן.Gradle
צריך להוסיף את הפרטים הבאים ל
build.gradle
:dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-consumer:VERSION_NUMBER' }
Maven
צריך להוסיף את הפרטים הבאים ל
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-consumer</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
ערכת ה-SDK לצרכן תלויה ב-SDK של מפות Google. התלות הזאת מוגדרת אם גרסת ה-SDK של מפות Google לא מוגדרת במפורש את קובץ תצורת build כמו בדוגמה הבאה, כשגרסה חדשה של מפות Google ההשקה של ה-SDK, ערכת ה-SDK לצרכנים תמשיך להשתמש במינימום הנתמכת של גרסת ה-SDK של מפות Google.
Gradle
צריך להוסיף את הפרטים הבאים ל
build.gradle
:dependencies { ... implementation 'com.google.android.gms:play-services-maps:18.1.0' }
Maven
צריך להוסיף את הפרטים הבאים ל
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.gms</groupId> <artifactId>play-services-maps</artifactId> <version>18.1.0</version> </dependency> </dependencies>
הוספה של מפתח ה-API לאפליקציה
אחרי שמוסיפים לאפליקציה את ה-SDK לצרכן, יש להוסיף את מפתח ה-API לאפליקציה. עליך להשתמש במפתח ה-API של הפרויקט שקיבלת כאשר להגדיר פרויקט פיתוח.
בקטע הזה מוסבר איך לאחסן את מפתח ה-API כדי שיהיה מאובטח יותר
שהאפליקציה שלך מפנה אליו. לא כדאי לבדוק את הגרסה של מפתח ה-API
במערכת הבקרה. צריך לאחסן אותו בקובץ local.properties
,
שנמצא בתיקיית השורש של הפרויקט. לקבלת מידע נוסף על
קובץ אחד (local.properties
), לעיון
קובצי מאפייני Gradle.
כדי לייעל את המשימה הזו, אפשר פלאגין של Secrets Gradle ל-Android.
כדי להתקין את הפלאגין ולאחסן את מפתח ה-API:
פותחים את קובץ
build.gradle
ברמה הבסיסית (root) ומוסיפים את הקוד הבא אל רכיבdependencies
מתחת ל-buildscript
.מגניב
buildscript { dependencies { // ... classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0" } }
Kotlin
buildscript { dependencies { // ... classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0") } }
עליך לפתוח את הקובץ
build.gradle
ברמת האפליקציה ולהוסיף את הקוד הבא אל רכיבplugins
.מגניב
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
אם משתמשים ב-Android Studio, לסנכרן את הפרויקט עם Gradle
פותחים את
local.properties
בספרייה ברמת הפרויקט ומוסיפים את באמצעות הקוד הבא. מחליפים אתYOUR_API_KEY
במפתח ה-API שלכם.MAPS_API_KEY=YOUR_API_KEY
בקובץ
AndroidManifest.xml
, עוברים אלcom.google.android.geo.API_KEY
ולעדכן את המאפייןandroid:value
באופן הבא:<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
בדוגמה הבאה מוצג מניפסט מלא של אפליקציה לדוגמה:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.consumerapidemo">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/_AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
לכלול את הייחוסים הנדרשים באפליקציה
אם באפליקציה שלך נעשה שימוש ב-SDK לצרכנים, עליך לכלול טקסט ייחוס ורישיונות קוד פתוח כחלק מההודעות המשפטיות של האפליקציה . מומלץ לכלול את הקרדיטים האלה כאפשרות עצמאית בתפריט, או חלק מהאפשרות מידע כללי בתפריט.
ניתן למצוא את פרטי הרישיונות בקובץ 'third_party_ Licenses.txt' קובץ ב- את קובץ ה-AAR שאוחזר מהארכיון.
מידע נוסף זמין בכתובת https://developers.google.com/android/guides/opensource שמסבירה איך לכלול הודעות בקוד פתוח.
אימות SDK של צרכן
ה-SDK לצרכן מספק אימות באמצעות אסימוני אינטרנט JSON. אסימון אינטרנט מסוג JSON (JWT) הוא אסימון גישה מבוסס-JSON שמספק אסימון או יותר תלונות על שירות מסוים. לדוגמה, שרת יכול ליצור אסימון עם ההצהרה 'מחובר כאדמין' ונספק ללקוח. לאחר מכן הלקוח יכול להשתמש באסימון הזה כדי להוכיח הוא מחובר כאדמין.
Consumer SDK משתמש ב-JSON Web Token שסופק על ידי האפליקציה כדי לתקשר עם Fleet Engine. למידע נוסף, ראו אימות והרשאה של מנוע חיפוש.
אסימון ההרשאה חייב לכלול הצהרת tripid:TRIP_ID
באסימון
הכותרת authorization
, כאשר TRIP_ID
הוא מזהה הנסיעה. כך הצרכן
גישת SDK לפרטי הנסיעה, כולל מיקום הרכב, מסלול וזמן ההגעה המשוער.
קריאה חוזרת (callback) של אסימון אינטרנט מסוג JSON
ה-SDK של הצרכן רושם קריאה חוזרת (callback) של אסימון הרשאה עם האפליקציה במהלך האתחול. ה-SDK קורא לאפליקציה כדי לקבל אסימון לכל בקשות הרשת המחייבות הרשאה.
מומלץ מאוד לבצע אימות באמצעות המטמון של הטמעת הקריאה החוזרת (callback)
ולרענן אותם רק אחרי השעה expiry
. האסימונים צריכים
יוענקו עם תפוגה של שעה אחת.
הקריאה החוזרת של אסימון ההרשאה מציינת איזה אסימון שירות נדרש
לשירות TripService
. הוא מספק גם את הtripId
הנדרשים
לצורך ההקשר.
הקוד לדוגמה הבא מדגים איך מטמיעים הרשאה קריאה חוזרת (callback) של אסימון.
Java
class JsonAuthTokenFactory implements AuthTokenFactory {
private static final String TOKEN_URL =
"https://yourauthserver.example/token";
private static class CachedToken {
String tokenValue;
long expiryTimeMs;
String tripId;
}
private CachedToken token;
/*
* This method is called on a background thread. Blocking is OK. However, be
* aware that no information can be obtained from Fleet Engine until this
* method returns.
*/
@Override
public String getToken(AuthTokenContext context) {
// If there is no existing token or token has expired, go get a new one.
String tripId = context.getTripId();
if (tripId == null) {
throw new RuntimeException("Trip ID is missing from AuthTokenContext");
}
if (token == null || System.currentTimeMillis() > token.expiryTimeMs ||
!tripId.equals(token.tripId)) {
token = fetchNewToken(tripId);
}
return token.tokenValue;
}
private static CachedToken fetchNewToken(String tripId) {
String url = TOKEN_URL + "/" + tripId;
CachedToken token = new CachedToken();
try (Reader r = new InputStreamReader(new URL(url).openStream())) {
com.google.gson.JsonObject obj
= com.google.gson.JsonParser.parseReader(r).getAsJsonObject();
token.tokenValue = obj.get("ServiceToken").getAsString();
token.expiryTimeMs = obj.get("TokenExpiryMs").getAsLong();
/*
* The expiry time could be an hour from now, but just to try and avoid
* passing expired tokens, we subtract 5 minutes from that time.
*/
token.expiryTimeMs -= 5 * 60 * 1000;
} catch (IOException e) {
/*
* It's OK to throw exceptions here. The error listeners will receive the
* error thrown here.
*/
throw new RuntimeException("Could not get auth token", e);
}
token.tripId = tripId;
return token;
}
}
Kotlin
class JsonAuthTokenFactory : AuthTokenFactory() {
private var token: CachedToken? = null
/*
* This method is called on a background thread. Blocking is OK. However, be
* aware that no information can be obtained from Fleet Engine until this
* method returns.
*/
override fun getToken(context: AuthTokenContext): String {
// If there is no existing token or token has expired, go get a new one.
val tripId =
context.getTripId() ?:
throw RuntimeException("Trip ID is missing from AuthTokenContext")
if (token == null || System.currentTimeMillis() > token.expiryTimeMs ||
tripId != token.tripId) {
token = fetchNewToken(tripId)
}
return token.tokenValue
}
class CachedToken(
var tokenValue: String? = "",
var expiryTimeMs: Long = 0,
var tripId: String? = "",
)
private companion object {
const val TOKEN_URL = "https://yourauthserver.example/token"
fun fetchNewToken(tripId: String) {
val url = "$TOKEN_URL/$tripId"
val token = CachedToken()
try {
val reader = InputStreamReader(URL(url).openStream())
reader.use {
val obj = com.google.gson.JsonParser.parseReader(r).getAsJsonObject()
token.tokenValue = obj.get("ServiceToken").getAsString()
token.expiryTimeMs = obj.get("TokenExpiryMs").getAsLong()
/*
* The expiry time could be an hour from now, but just to try and avoid
* passing expired tokens, we subtract 5 minutes from that time.
*/
token.expiryTimeMs -= 5 * 60 * 1000
}
} catch (e: IOException) {
/*
* It's OK to throw exceptions here. The error listeners will receive the
* error thrown here.
*/
throw RuntimeException("Could not get auth token", e)
}
token.tripId = tripId
return token
}
}
}
אתחול ה-API
לפני ביצוע ההליכים האלה, ההנחה היא שהפעלתם את השירותים המתאימים וה-SDK לצרכן.
אחזור של המופע ConsumerApi
כדי להשתמש ב-SDK לצרכנים, האפליקציה שלך צריכה לאתחל
ConsumerApi
באופן אסינכרוני. ה-API הוא סינגלטון.
שיטת האתחול לוקחת AuthTokenFactory
. המפעל מייצר
אסימוני JWT למשתמש במקרה הצורך.
providerId
הוא מזהה הפרויקט של הפרויקט ב-Google Cloud. לצפייה
מדריך למשתמש בנושא כלל המכשירים בארגון
לקבלת מידע נוסף על יצירת הפרויקט.
צריך להטמיע את AuthTokenFactory
באפליקציה כפי שמתואר ב
אימות SDK לצרכנים.
Java
Task<ConsumerApi> consumerApiTask = ConsumerApi.initialize(
this, "myProviderId", authTokenFactory);
consumerApiTask.addOnSuccessListener(
consumerApi -> this.consumerApi = consumerApi);
Kotlin
val consumerApiTask =
ConsumerApi.initialize(this, "myProviderId", authTokenFactory)
consumerApiTask?.addOnSuccessListener { consumerApi: ConsumerApi ->
this@YourActivity.consumerApi = consumerApi
}
SDK של מפות Google וכלים לעיבוד מפות
Consumer SDK גרסה 2.x.x תומך ב-SDK של מפות Google ל-Android גרסה 18.1.0 ואילך. הטבלה
מופיע סיכום של כלי הרינדור שמוגדר כברירת מחדל לפי גרסת ה-SDK של מפות Google ויכולת התמיכה
של שני כלי הרינדור. עם זאת, מומלץ להשתמש בכלי העדכני ביותר לרינדור, אם אתם צריכים
כדי להשתמש בכלי לרינדור מדור קודם, אפשר לציין אותו במפורש באמצעות
MapsInitializer.initialize()
גרסת SDK של מפות Google | תמיכה בכלי לרינדור העדכני ביותר | תמיכה בכלי לרינדור מדור קודם | כלי לעיבוד שמוגדר כברירת מחדל |
---|---|---|---|
גרסה 18.1.0 ומטה | כן | כן | דור קודם* |
V18.2.0 | כן | כן | פורסמו לאחרונה |
* בעקבות ההשקה של הכלי החדש לעיבוד מפות Google, הכלי האחרון לרינדור יוגדר כברירת מחדל.
הוספת SDK של מפות כתלות
Gradle
צריך להוסיף את הפרטים הבאים לbuild.gradle
:
dependencies {
//...
implementation "com.google.android.gms:play-services-maps:VERSION_NUMBER"
}
Maven
צריך להוסיף את הפרטים הבאים לpom.xml
:
<dependencies>
...
<dependency>
<groupId>com.google.android.gms</groupId>
<artifactId>play-services-maps</artifactId>
<version>18.1.0</version>
</dependency>
</dependencies>
אתחול ה-SDK של מפות Google לפני הפעלת ה-SDK של הצרכן
צריך להתקשר לכיתת Application
או לסטארט-אפ Activity
MapsInitializer.initialize()
ולהמתין לתוצאת בקשת הרינדור לפני האתחול
SDK לצרכנים.
java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initViews();
MapsInitializer.initialize(getApplicationContext(), Renderer.LATEST,
new OnMapsSdkInitializedCallback() {
@Override
public void onMapsSdkInitialized(Renderer renderer) {
switch (renderer) {
case LATEST:
Log.i("maps_renderer", "LATEST renderer");
break;
case LEGACY:
Log.i("maps_renderer", "LEGACY renderer");
break;
}
initializeConsumerSdk();
}
});
}
Kotlin
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
initViews()
MapsInitializer.initialize(
getApplicationContext(), Renderer.LATEST,
object : OnMapsSdkInitializedCallback() {
fun onMapsSdkInitialized(renderer: Renderer?) {
when (renderer) {
LATEST -> Log.i("maps_renderer", "LATEST renderer")
LEGACY -> Log.i("maps_renderer", "LEGACY renderer")
}
initializeConsumerSdk()
}
})
}
יצירת ממשק המשתמש
אפשר להשתמש ב-ConsumerMapFragment
או
ConsumerMapView
כדי ליצור את ממשק המשתמש
תרגום מכונה. ConsumerMapFragment
מאפשר לך להגדיר
במפה שלך באמצעות
Fragment
ו-ConsumerMapView
מאפשר לך להשתמש ב-
View
. שיתוף נסיעות
הפונקציונליות זהה ב-ConsumerMapView
וב-
ConsumerMapFragment
, כך שאפשר לבחור אחד לפי
בין אם View
או
Fragment
מתאים יותר לאפליקציה.
הוספת תמיכה ב-API 19 (KitKat) ובפריטים גרפיים וקטוריים
אם עיצוב האפליקציה דורש תמיכה במכשירי API 19 (KitKat) ובפריטים גרפיים וקטוריים,
צריך להוסיף את הקוד הבא לפעילות שלך. קוד זה נמשך
AppCompatActivity
כדי להשתמש
רכיבים וקטוריים שניתנים להזזה ב-SDK לצרכנים.
Java
// ...
import android.support.v7.app.AppCompatActivity;
// ...
public class ConsumerTestActivity extends AppCompatActivity {
// ...
}
Kotlin
// ...
import android.support.v7.app.AppCompatActivity
// ...
class ConsumerTestActivity : AppCompatActivity() {
// ...
}
הוספה של קטע במפה או תצוגה
יוצרים את המפה להצגת שיתוף של מסלולים בכל מקטע של Android
או תצוגה, שמגדירים בקובץ ה-XML של פריסת האפליקציה (שנמצא
/res/layout
). לאחר מכן, המקטע (או התצוגה) מספק גישה לתהליך.
שיתוף מפה, שאליה האפליקציה שלך יכולה לגשת ולשנות. המפה מספקת גם
נקודת אחיזה אל ConsumerController
, שמאפשרת לאפליקציה לשלוט
להתאים אישית את חוויית השיתוף של התהליך.
שלט רחוק לשיתוף המפה של התהליך
את מפת שיתוף המסלולים מגדירים כשגם מקטעים (באמצעות
ConsumerMapFragment
), או כתצוגה (באמצעות ConsumerMapView
), כפי שמוצג
בדוגמה הבאה לקוד. לאחר מכן, השיטה onCreate()
אמורה להפעיל
הפקודה getConsumerGoogleMapAsync(callback)
, שמחזירה את הערך ConsumerGoogleMap
באופן אסינכרוני בקריאה החוזרת (callback). לאחר מכן משתמשים ב-ConsumerGoogleMap
כדי להציג
ולשתף אותו במסע, ואפשר לעדכן אותו לפי הצורך על ידי האפליקציה.
ConsumerMapFragment
אתם מגדירים את המקטע בקובץ ה-XML של פריסת האפליקציה, כפי שמוצג בדוגמה את הדוגמה הבאה בקוד הבא.
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerMapFragment"
android:id="@+id/consumer_map_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
הקריאה אל getConsumerGoogleMapAsync()
צריכה להגיע מonCreate()
.
Java
public class SampleAppActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// Find the ConsumerMapFragment.
ConsumerMapFragment consumerMapFragment =
(ConsumerMapFragment) fragmentManager.findFragmentById(R.id.consumer_map_fragment);
// Initiate the callback that returns the map.
if (consumerMapFragment != null) {
consumerMapFragment.getConsumerGoogleMapAsync(
new ConsumerMapReadyCallback() {
// The map returned in the callback is used to access the ConsumerController.
@Override
public void onConsumerMapReady(@NonNull ConsumerGoogleMap consumerGoogleMap) {
ConsumerController consumerController = consumerGoogleMap.getConsumerController();
}
});
}
}
}
Kotlin
class SampleAppActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Find the ConsumerMapFragment.
val consumerMapFragment =
fragmentManager.findFragmentById(R.id.consumer_map_fragment) as ConsumerMapFragment
consumerMapFragment.getConsumerGoogleMapAsync(
object : ConsumerMapReadyCallback() {
override fun onConsumerMapReady(consumerGoogleMap: ConsumerGoogleMap) {
val consumerController = consumerGoogleMap.getConsumerController()!!
}
}
)
}
}
ConsumerMapView
ניתן להשתמש בתצוגה בקטע או בפעילות, בהתאם להגדרה XML.
<com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerMapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/consumer_map_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
השיחה אל getConsumerGoogleMapAsync()
צריכה להיות מהצד onCreate()
. לחשבון
בנוסף לפרמטר הקריאה החוזרת, היא דורשת את הפעילות שמכילה את
מקטע, ו-GoogleMapOptions
(שיכול להיות null), המכיל תצורה
של MapView
. מחלקת הבסיס של הפעילות או המקטעים חייבת להיות
FragmentActivity
או Fragment
תמיכה (בהתאמה), מכיוון שהם מספקים
גישה למחזור החיים שלו.
Java
public class SampleAppActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
ConsumerMapView mapView = findViewById(R.id.consumer_map_view);
if (mapView != null) {
mapView.getConsumerGoogleMapAsync(
new ConsumerMapReadyCallback() {
// The map returned in the callback is used to access the ConsumerController.
@Override
public void onConsumerMapReady(@NonNull ConsumerGoogleMap consumerGoogleMap) {
ConsumerController consumerController = consumerGoogleMap.getConsumerController();
}
}, this, null);
}
}
}
Kotlin
class SampleAppActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val mapView = findViewById(R.id.consumer_map_view) as ConsumerMapView
mapView.getConsumerGoogleMapAsync(
object : ConsumerMapReadyCallback() {
// The map returned in the callback is used to access the ConsumerController.
override fun onConsumerMapReady(consumerGoogleMap: ConsumerGoogleMap) {
val consumerController = consumerGoogleMap.getConsumerController()!!
}
},
/* fragmentActivity= */ this,
/* googleMapOptions= */ null,
)
}
}
MapView
במקטע זהה לדוגמה שלמעלה עבור MapView
ב-
פעילות, למעט שהמקטע מנפח את הפריסה שכוללת את
MapView
במקטע onCreateView()
method.
Java
public class MapViewInFragment extends Fragment {
@Override
public View onCreateView(
@NonNull LayoutInflater layoutInflater,
@Nullable ViewGroup viewGroup,
@Nullable Bundle bundle) {
return layoutInflater.inflate(R.layout.consumer_map_view, viewGroup, false);
}
}
Kotlin
class MapViewInFragment : Fragment() {
override fun onCreateView(
layoutInflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
return layoutInflater.inflate(R.layout.consumer_map_view, viewGroup, false)
}
}
כוונון זום המצלמה כדי להתמקד במסע
ברירת המחדל של לחצן המיקום שלי שמובנית ב-SDK של מפות Google ממרכזת את המצלמה במיקום המכשיר.
אם יש סשן פעיל של שיתוף מסלול, כדאי למרכז את המצלמה כדי להתמקד בתהליך במקום במיקום המכשיר.
פתרון SDK מובנה לצרכן ב-Android: Auto Camera
כדי לאפשר לכם להתמקד בתהליך במקום במיקום המכשיר, ערכת SDK לצרכנים מספקת תכונה של מצלמה אוטומטית מופעלת כברירת מחדל. המצלמה משנה את מרחק התצוגה כדי להתמקד במסלול השיתוף של הנסיעה אל ציון הדרך הבא בנסיעה.
התאמה אישית של התנהגות המצלמה
אם דרושה לך שליטה רבה יותר על התנהגות המצלמה, ניתן להשבית או להפעיל מצלמה אוטומטית באמצעות ConsumerController.setAutoCameraEnabled().
ConsumerController.getCameraUpdate() מחזיר את גבולות המצלמה המומלצים באותו רגע. לאחר מכן אפשר לספק את הCameraUpdate
הזה כארגומנט
GoogleMap.moveCamera() או GoogleMap.animateCamera().
גישה לשיתוף נסיעות ולמפות
כדי לתמוך בשיתוף נסיעות ובאינטראקציה עם מפות באפליקציה, צריך הרשאת גישה
אל ConsumerGoogleMap
ו-
ConsumerController
.
ConsumerMapFragment
והקבוצה
ConsumerMapView
חוזרים באופן אסינכרוני
ConsumerGoogleMap
בConsumerMapReadyCallback
.
אפשרות החזרה במחיר ConsumerGoogleMap
ConsumerController
מ-getConsumerController()
. שלך
יכולים לגשת אל ConsumerGoogleMap
וגם
ConsumerController
באופן הבא.
Java
private ConsumerGoogleMap consumerGoogleMap;
private ConsumerController consumerController;
private ConsumerMapView consumerMapView;
consumerMapView.getConsumerGoogleMapAsync(
new ConsumerMapReadyCallback() {
@Override
public void onConsumerMapReady(@NonNull ConsumerGoogleMap consumerMap) {
consumerGoogleMap = consumerMap;
consumerController = consumerMap.getConsumerController();
}
},
this, null);
Kotlin
var consumerGoogleMap: ConsumerGoogleMap
var consumerController: ConsumerController
val consumerMapView = findViewById(R.id.consumer_map_view) as ConsumerMapView
consumerMapView.getConsumerGoogleMapAsync(
object : ConsumerMapReadyCallback() {
override fun onConsumerMapReady(consumerMap: ConsumerGoogleMap) {
consumerGoogleMap = consumerMap
consumerController = consumerMap.getConsumerController()
},
/* fragmentActivity= */ this,
/* googleMapOptions= */ null,
}
)
ConsumerGoogleMap
ConsumerGoogleMap
היא מחלקה wrapper של
כיתה אחת (GoogleMap
). הוא מספק לאפליקציה את היכולת
לקיים אינטראקציה עם המפה באמצעות ממשק API שדומה ל-
GoogleMap
שימוש במפת הצרכנים מאפשר לאפליקציה ולנסיעות שלך
כדי לקיים אינטראקציה חלקה עם אותה מפה בסיסית של Google. לדוגמה,
ב-GoogleMap
אפשר לבצע רישום של קריאה חוזרת (callback) בלבד, אבל
ב-ConsumerGoogleMap
יש תמיכה בקריאות חוזרות (callback) רשומות כפולות.
הקריאות החוזרות האלה מאפשרות לאפליקציה ולשיתוף הנסיעות לרשום את הקריאה החוזרת,
שנקראים ברצף.
ConsumerController
האפליקציה ConsumerController
מספקת גישה לפונקציות של שיתוף נסיעות,
כמו מעקב אחר נסיעות, שליטה בסטטוס הנסיעה והגדרת מיקומים.
הגדרה של שיתוף הנסיעות
אחרי שהקצה העורפי מתאים בין צרכן לבין רכב, צריך להשתמש ב-JourneySharingSession
כדי להתחיל את תהליך השיתוף של ממשק המשתמש. בשיתוף התהליך מוצגת ההתאמה
המיקום והמסלול של הרכב. אחרי הטמעת ה-SDK באפליקציה, אפשר להוסיף
הפונקציונליות למעקב אחרי נסיעות, להאזנה לעדכונים ולטיפול בשגיאות.
במסגרת ההליכים הבאים, ההנחה היא שהשירותים לקצה העורפי קיימים
השירותים להתאמה ללקוחות עם כלי רכב פעילים.
רישום אוזן באובייקט
TripModel
כדי לקבל פרטים לגביו הנסיעה, כמו זמן ההגעה המשוער (זמן ההגעה המשוער) והמרחק שהרכב צריך לנסוע לפני ההגעה.Java
// Create a TripModel instance for listening to updates to the trip specified by this trip name. String tripName = ...; TripModelManager tripModelManager = consumerApi.getTripModelManager(); TripModel tripModel = tripModelManager.getTripModel(tripName); // Create a JourneySharingSession instance based on the TripModel. JourneySharingSession session = JourneySharingSession.createInstance(tripModel); // Add the JourneySharingSession instance on the map for updating the UI. consumerController.showSession(session); // Register for trip update events. tripModel.registerTripCallback(new TripModelCallback() { @Override public void onTripETAToNextWaypointUpdated( TripInfo tripInfo, @Nullable Long timestampMillis) { // ... } @Override public void onTripActiveRouteRemainingDistanceUpdated( TripInfo tripInfo, @Nullable Integer distanceMeters) { // ... } // ... });
Kotlin
// Create a TripModel instance for listening to updates to the trip specified by this trip name. val tripName = "tripName" val tripModelManager = consumerApi.getTripModelManager() val tripModel = tripModelManager.getTripModel(tripName) // Create a JourneySharingSession instance based on the TripModel. val session = JourneySharingSession.createInstance(tripModel) // Add the JourneySharingSession instance on the map for updating the UI. consumerController.showSession(session) // Register for trip update events. tripModel.registerTripCallback( object : TripModelCallback() { override fun onTripETAToNextWaypointUpdated( tripInfo: TripInfo, timestampMillis: Long?, ) { // ... } override fun onTripActiveRouteRemainingDistanceUpdated( tripInfo: TripInfo, distanceMeters: Int?, ) { // ... } // ... })
הגדרת הנסיעה באמצעות
TripModelOptions
.Java
// Set refresh interval to 2 seconds. TripModelOptions tripOptions = TripModelOptions.builder().setRefreshIntervalMillis(2000).build(); tripModel.setTripModelOptions(tripOptions);
Kotlin
// Set refresh interval to 2 seconds. val tripOptions = TripModelOptions.builder().setRefreshIntervalMillis(2000).build() tripModel.setTripModelOptions(tripOptions)
הפסקת שיתוף הנסיעות
חשוב להפסיק את שיתוף הנסיעות כשאין בו יותר צורך, למשל כשהפעילות של המארח מושמדת. הפסקת שיתוף התהליכים מפסיקה גם בקשות רשת ל-Fleet Engine ומונעת דליפות זיכרון.
הקוד לדוגמה הבא מדגים איך להפסיק את שיתוף התהליך.
Java
public class MainActivity extends AppCompatActivity
implements ConsumerViewModel.JourneySharingListener {
// Class implementation
@Override
protected void onDestroy() {
super.onDestroy();
if (journeySharingSession != null) {
journeySharingSession.stop();
}
}
}
Kotlin
class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {
// Class implementation
override fun onDestroy() {
super.onDestroy()
journeySharingSession?.stop()
}
}
טיפול בשגיאות בנסיעה
השיטה onTripRefreshError
מציגה שגיאות שמתרחשות במהלך מעקב אחר נסיעות.
המיפוי של SDK לצרכנים
שגיאות תואמות לאותן הנחיות HTTP/RPC שנוצרו עבור
Google Cloud Platform.
דוגמאות לשגיאות נפוצות שעשויות להופיע במהלך מעקב אחר נסיעות:
HTTP | הכנסה לקליק | תיאור |
---|---|---|
400 | INVALID_ARGUMENT | הלקוח ציין שם נסיעה לא חוקי.
שם הנסיעה חייב להיות בפורמט
providers/{provider_id}/trips/{trip_id}
ה-provider_id חייב להיות המזהה של
פרויקט בענן בבעלות ספק השירות. |
401 | לא מאומת | הבקשה לא אומתה עקב אסימון JWT לא חוקי. השגיאה הזו תתבצע אם אסימון ה-JWT חתום ללא נסיעה את המזהה או את אסימון ה-JWT שפג תוקפם. |
403 | PERMISSION_DENIED | לא מספיק ללקוח הרשאה. השגיאה הזו מתקבלת אם ה-JWT האסימון לא חוקי, ללקוח אין או שה-API לא הופעל עבור בפרויקט הלקוח. אסימון ה-JWT יכול להיות חסר או שהאסימון חתום עם נסיעה מזהה שלא תואם למזהה הנסיעה המבוקש. |
429 | RESOURCE_EXHAUSTED | מכסת המשאבים היא אפס או הקצב מתנועת הגולשים חורגת מהמגבלה. |
503 | UNAVAILABLE | השירות לא זמין. בדרך כלל השרת מושבתת. |
504 | DEADLINE_EXCEEDED | המועד האחרון של הבקשה עבר. הפעולה הזו תגרור מתרחשת רק אם המתקשר מגדיר מועד אחרון שהוא קצר יותר מברירת המחדל של השיטה המועד האחרון (כלומר, המועד האחרון המבוקש אינו זהה) מספיק כדי שהשרת יוכל לעבד ) והבקשה לא הושלמה במסגרת המועד האחרון. |
מידע נוסף זמין במאמר הבא: טיפול בשגיאות ב-SDK לצרכנים.