當您追蹤行程時,消費者應用程式會向消費者顯示適當車輛的位置。為此,應用程式需要開始追蹤行程、更新行程進度,並在行程完成時停止追蹤。
本文將說明這項程序的運作方式。
事前準備
確認以下項目已完成設定:
消費者應用程式的後端服務已就位,且用於將消費者與車輛配對的服務已可運作。
您已為應用程式設定地圖。
開始追蹤行程
當後端伺服器將車輛與車輛配對時,請使用 JourneySharingSession
開始行程。
下列程式碼範例示範如何在檢視畫面載入後,開始行程。
Java
public class MainActivity extends AppCompatActivity
implements ConsumerViewModel.JourneySharingListener {
// Class implementation
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create a TripModel instance to listen for 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) {
// ...
}
// ...
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (journeySharingSession != null) {
journeySharingSession.stop();
}
}
}
Kotlin
class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {
// Class implementation
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Create a TripModel instance to listen for 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?,
) {
// ...
}
// ...
})
}
override fun onDestroy() {
super.onDestroy()
journeySharingSession?.stop()
}
}
更新行程進度
如要更新行程進度詳細資料 (例如車輛抵達前所需的距離和預計抵達時間),應用程式必須註冊及設定事件監聽器,如以下範例所示。
在
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 發出不必要的網路要求,並防止記憶體耗損。
使用 JourneySharingSession
停止追蹤行程,如以下程式碼範例所示。
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
方法會顯示行程監控期間發生的錯誤。錯誤訊息符合 Google Cloud 錯誤標準。如需錯誤訊息定義和所有錯誤代碼的詳細資訊,請參閱 Google Cloud 錯誤說明文件。
以下是行程監控過程中可能發生的幾個常見錯誤:
HTTP | RPC | 說明 |
---|---|---|
400 | INVALID_ARGUMENT | 用戶端指定的旅遊名稱無效。行程名稱必須採用下列格式:providers/{provider_id}/trips/{trip_id} 。provider_id 必須是服務供應商擁有的 Cloud 專案 ID。 |
401 | UNAUTHENTICATED | 如果沒有有效的驗證憑證,就會收到這項錯誤訊息。例如,如果 JWT 憑證未經簽署就附上行程 ID,或是 JWT 憑證已過期。 |
403 | PERMISSION_DENIED | 如果用戶端沒有足夠的權限 (例如,擁有消費者角色的使用者嘗試呼叫 updateTrip)、如果 JWT 權杖無效,或是用戶端專案未啟用 API,則會收到這個錯誤。JWT 權杖可能遺失,或權杖使用與要求行程 ID 不符的行程 ID 進行簽署。 |
429 | RESOURCE_EXHAUSTED | 資源配額為 0,或流量速率超出上限。 |
503 | 無法使用 | 服務無法使用,通常是因伺服器停止運作所致。 |
504 | DEADLINE_EXCEEDED | 已超出要求期限。只有在呼叫者設定的期限短於方法的預設期限 (即要求的期限不夠讓伺服器處理要求),且要求未在期限內完成時,才會發生這項錯誤。 |
處理消費者 SDK 錯誤
Consumer SDK 會透過回呼機制,將行程更新錯誤傳送至消費者應用程式。回呼參數是平台專屬的傳回類型 (Android 上的 TripUpdateError
,在 iOS 上則是 NSError
)。
擷取狀態碼
傳遞至回呼的錯誤通常是 gRPC 錯誤,您也可以從中擷取狀態碼形式的其他資訊。如需完整的狀態碼清單,請參閱「狀態碼及其在 gRPC 中的用法」。
Java
您可以擷取 gRPC 狀態碼,從 onTripUpdateError()
傳回的 TripUpdateError
中取得錯誤詳細資料。
// Called when there is a trip update error.
@Override
public void onTripUpdateError(TripInfo tripInfo, TripUpdateError error) {
Status.Code code = error.getStatusCode();
}
Kotlin
您可以擷取 gRPC 狀態碼,該狀態碼會從 onTripUpdateError()
傳回的 TripUpdateError
提供錯誤相關詳細資料。
// Called when there is a trip update error.
override fun onTripUpdateError(tripInfo: TripInfo, error: TripUpdateError) {
val code = error.getStatusCode()
}
解讀狀態碼
狀態碼涵蓋兩種錯誤:伺服器和網路相關錯誤,以及用戶端錯誤。
伺服器和網路錯誤
下列狀態碼適用於網路或伺服器錯誤,您不需要採取任何行動來解決這些錯誤。Consumer SDK 會自動復原這些錯誤。
狀態碼 | 說明 |
---|---|
ABORTED | 伺服器停止傳送回應。這通常是伺服器問題所致。 |
已取消 | 伺服器終止了傳出回應。這通常會發生在 應用程式傳送至背景時,或是 消費者應用程式發生狀態變更時。 |
INTERRUPTED | |
DEADLINE_EXCEEDED | 伺服器回應時間過長。 |
無法使用 | 伺服器無法使用。這通常是因為網路問題。 |
用戶端錯誤
下列狀態碼適用於用戶端錯誤,您必須採取行動才能解決。在您結束行程分享之前,Consumer SDK 會持續重試重新整理行程,但必須等到您採取行動,系統才會恢復。
狀態碼 | 說明 |
---|---|
INVALID_ARGUMENT | 消費者應用程式指定的行程名稱無效;行程名稱必須採用以下格式:providers/{provider_id}/trips/{trip_id} 。 |
NOT_FOUND | 這個行程從未建立。 |
PERMISSION_DENIED | 消費者應用程式權限不足。發生以下狀況時會出現這個錯誤:
|
RESOURCE_EXHAUSTED | 資源配額為零,或流量速率超出速限。 |
未驗證 | 由於 JWT 權杖無效,因此要求驗證失敗。如果簽署 JWT 權杖時沒有行程 ID,或是 JWT 權杖已過期,就會發生這個錯誤。 |