追蹤行程時,消費者應用程式會向消費者顯示相應車輛的位置。如要執行這項操作,應用程式必須開始追蹤行程、更新行程進度,並在行程完成時停止追蹤。
本文將說明這項程序的運作方式。
事前準備
請確認已設定下列項目:
消費者應用程式的後端服務已就位,且消費者與車輛配對服務已可運作。
您已為應用程式設定地圖。
開始追蹤行程
後端伺服器將消費者與車輛配對後,請使用 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 | 資源配額為零,或流量超出上限。 |
503 | 無法使用 | 服務無法使用,通常是因伺服器停止運作所致。 |
504 | DEADLINE_EXCEEDED | 已超出要求期限。只有在呼叫者設定的期限短於方法的預設期限 (即要求的期限不夠讓伺服器處理要求),且要求未在期限內完成時,才會發生這項錯誤。 |
處理 Consumer SDK 錯誤
Consumer SDK 會使用回呼機制,將行程更新錯誤傳送至消費者應用程式。回呼參數是平台專屬的回傳型別 (Android 為 TripUpdateError
,iOS 為 NSError
)。
擷取狀態碼
傳遞至回呼的錯誤通常是 gRPC 錯誤,您也可以從中擷取狀態碼形式的其他資訊。如需完整狀態碼清單,請參閱「gRPC 中的狀態碼及其用途」。
Java
您可以從 onTripUpdateError()
傳回的 TripUpdateError
中,擷取提供錯誤詳細資料的 gRPC 狀態碼。
// Called when there is a trip update error.
@Override
public void onTripUpdateError(TripInfo tripInfo, TripUpdateError error) {
Status.Code code = error.getStatusCode();
}
Kotlin
您可以從 onTripUpdateError()
傳回的 TripUpdateError
中,擷取提供錯誤詳細資料的 gRPC 狀態碼。
// Called when there is a trip update error.
override fun onTripUpdateError(tripInfo: TripInfo, error: TripUpdateError) {
val code = error.getStatusCode()
}
解讀狀態碼
狀態碼涵蓋兩種錯誤:伺服器和網路相關錯誤,以及用戶端錯誤。
伺服器和網路錯誤
下列狀態碼代表網路或伺服器錯誤,您不需要採取任何行動來解決問題。Consumer SDK 會自動從這些錯誤中復原。
狀態碼 | 說明 |
---|---|
ABORTED | 伺服器已停止傳送回應。這通常是伺服器問題所致。 |
已取消 | 伺服器終止了連出回應。應用程式傳送至背景,或 Consumer 應用程式發生狀態變更時,通常會發生這種情況。 |
INTERRUPTED | |
DEADLINE_EXCEEDED | 伺服器回應時間過長。 |
無法使用 | 伺服器無法使用,這通常是由網路問題所致。 |
用戶端錯誤
下列狀態碼代表用戶端錯誤,您必須採取行動解決問題。在您停止分享行程前,Consumer SDK 會持續嘗試重新整理行程,但您必須採取行動,系統才會恢復。
狀態碼 | 說明 |
---|---|
INVALID_ARGUMENT | 消費者應用程式指定的行程名稱無效;行程名稱必須採用 providers/{provider_id}/trips/{trip_id} 格式。 |
NOT_FOUND | 系統從未建立行程。 |
PERMISSION_DENIED | Consumer 應用程式的權限不足。發生以下狀況時會出現這個錯誤:
|
RESOURCE_EXHAUSTED | 資源配額為零,或流量流動速率超過速度限制。 |
UNAUTHENTICATED | JWT 權杖無效,因此要求驗證失敗。如果 JWT 權杖在簽署時沒有行程 ID,或是 JWT 權杖已過期,就會發生這項錯誤。 |