開始使用 Android 版 Consumer SDK

您可以使用 Consumer SDK 建構並執行與一般使用者整合的應用程式 以及隨選乘車和運送服務解決方案後端服務。您可以建立 Trip and Order Progress 應用程式,可顯示有效行程。 回應行程更新,並處理行程錯誤。

由於 Consumer SDK 採用模組化架構,因此您可以使用 並選擇要用於特定應用程式的 API 使用自己的 API、Fleet Engine 提供的後端服務 以及 Google 地圖平台的其他 API

基本系統需求

行動裝置必須搭載 Android 系統 6.0 版 (API 級別 23) 以上版本。

建構和依附元件設定

消費者 SDK 1.99.0 以上版本可透過 Google Maven 取得 Cloud Storage 也提供目錄同步處理功能先前使用的私人存放區管道已淘汰。

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>

專案設定

如要使用 Android 版 Consumer SDK,您的應用程式必須指定 minSdkVersion 23 以上版本。

如要執行透過 Consumer SDK 建構的應用程式,Android 裝置必須具備 Google Play 服務 已安裝。

設定開發專案

設定開發專案並取得 API 金鑰 建立專案:

  1. 建立新的 Google Cloud 控制台專案或選取現有專案,以便使用 消費者 SDK 整合後請稍候片刻,直到 新專案會顯示在 Google Cloud 控制台中

  2. 如要執行試用版應用程式,專案必須具備 Maps SDK 的存取權 。在 Google Cloud 控制台中,選取 API 與服務 >程式庫,然後搜尋並啟用 Maps SDK for Android。

  3. 選取專案的 API 金鑰,取得專案的 API 金鑰 API 與服務 >憑證 >建立憑證 >API 金鑰。 如要進一步瞭解如何取得 API 金鑰,請參閱 取得 API 金鑰

在應用程式中加入 Consumer SDK

Consumer SDK 可透過私人 Maven 存放區取得。 存放區包括 SDK 的專案物件模型 (.pom) 檔案和 Javadocs。 如要在應用程式中加入 Consumer SDK,請按照下列步驟操作:

  1. 按照下列說明設定環境以存取主機 Maven 存放區 請參閱上一節的說明

    如果您已在 中宣告集中式依附元件管理設定 settings.gradle,請按照以下說明停用該功能。

    • 移除 settings.gradle 中的下列程式碼區塊:

      import org.gradle.api.initialization.resolve.RepositoriesMode
      dependencyResolutionManagement {
          repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
          repositories {
              google()
              mavenCentral()
          }
      }
      
  2. 將以下依附元件新增至 Gradle 或 Maven 設定,將 所需 Consumer SDK 版本的 VERSION_NUMBER 預留位置。

    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>
    
  3. Consumer SDK 仰賴 Maps SDK。這個依附元件是由 如此一來,如果 Maps SDK 版本「並未」在 建立新版 Google 地圖時,建構設定檔如下所示: SDK 發行後,Consumer SDK 會繼續採用 支援的 Maps SDK 版本。

    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 金鑰

將 Consumer SDK 新增至應用程式後,請將 API 金鑰加進應用程式。 您必須使用取得專案 API 金鑰時取得的專案 API 金鑰 設定開發專案

本節說明如何儲存 API 金鑰,讓金鑰更安全 由您的應用程式參照。請勿檢查 API 金鑰版本 控制系統這個檔案應儲存在 local.properties 檔案中 這個目錄位於專案的根目錄如要進一步瞭解 local.properties 個檔案,請參閱 Gradle 屬性檔案

您可以使用 Secrets Gradle Plugin for Android 來簡化這項工作。

如要安裝這個外掛程式並儲存 API 金鑰,請按照下列步驟操作:

  1. 開啟根層級的 build.gradle 檔案,然後將下列程式碼加進 buildscript 底下的 dependencies 元素。

    Groovy

    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")
        }
    }
    
  2. 開啟應用程式層級的 build.gradle 檔案,然後將下列程式碼加進 plugins 元素。

    Groovy

    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
    

    Kotlin

    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    
  3. 如果您使用的是 Android Studio 使用 Gradle 同步處理專案

  4. 在專案層級目錄中開啟 local.properties 並新增 下方的程式碼。然後將 YOUR_API_KEY 替換成您的 API 金鑰。

    MAPS_API_KEY=YOUR_API_KEY
    
  5. 透過 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>

在應用程式中加入必要的作者資訊

如果您在應用程式中使用 Consumer SDK,則必須加入 將作者資訊文字和開放原始碼授權納入應用程式的法律聲明中 專區。最好的方法是將出處資訊列為獨立的選單項目,或者 「關於」選單項目的一部分

您可以在「third_party_licenses.txt」中找到授權資訊該檔案位於 已取消封存的 AAR 檔案

請參閱 https://developers.google.com/android/guides/opensource ,瞭解如何納入開放原始碼通知。

消費者 SDK 驗證

Consumer SDK 使用 JSON Web Token 提供驗證。 JSON Web Token (JWT) 是一種 JSON 基礎存取權杖, 或是對某項服務提出大量索賠舉例來說,伺服器 具有「以管理員身分登入」聲明的憑證為他們提供 向客戶說明接著,用戶端就能利用該權杖 並以管理員身分登入。

Consumer SDK 使用應用程式提供的 JSON Web Token 與 Fleet Engine 通訊詳情請參閱 Fleet Engine 驗證與授權

授權權杖必須包含 tripid:TRIP_ID 憑證附加資訊 authorization 標頭,其中 TRIP_ID 是行程 ID。這樣能為消費者 SDK 可存取行程詳細資料,包括車輛位置、路線和預計到達時間。

JSON Web Token 回呼

Consumer SDK 會註冊授權權杖回呼 與應用程式互動SDK 會呼叫應用程式 取得所有需要授權的網路要求權杖。

強烈建議您執行回呼實作快取授權 且只有在 expiry 時間過後才能重新整理。符記應 具有一小時的到期時間。

授權權杖回呼會指定所需的服務權杖 才能使用 TripService 服務。該頁面也會提供必要的 tripId 瞭解情境

以下程式碼範例示範如何實作授權 權杖回呼。

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

按照這些程序操作之前,我們會假設您已啟用 以及如何使用 Consumer SDK

取得 ConsumerApi 執行個體

如要使用 Consumer SDK,應用程式需要進行初始化 ConsumerApi。API 為單例模式, 初始化方法會採用 AuthTokenFactory。工廠會產生新的 使用者的 JWT 權杖。

providerId 是 Google Cloud 專案的專案 ID。詳情請參閱 Fleet Engine 使用手冊

應用程式應按照下列說明實作 AuthTokenFactoryConsumer 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
}

Maps SDK 和地圖轉譯器

Consumer SDK v2.x.x 支援 Maps SDK for Android 18.1.0 以上版本。表格 以下統整了 Maps SDK 版本的預設轉譯器,以及是否支援 兩個轉譯器的權重如果需要,建議您使用最新的轉譯器 使用舊版轉譯器,接著可以使用 MapsInitializer.initialize()

Maps SDK 版本 支援最新版轉譯器 支援舊版轉譯器 預設轉譯器
V18.1.0 以下版本 舊版*
V18.2.0 最新

* 隨著新版地圖轉譯器推出, 系統會預設使用最新的轉譯器。

新增 Maps 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>

初始化 Consumer SDK 前請先初始化 Maps SDK

Application 或啟動的 Activity 類別中,呼叫 MapsInitializer.initialize() 等轉譯器要求結果後再初始化 Consumer 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()
      }
    })
  }

建立使用者介面

您可以使用 ConsumerMapFragmentConsumerMapView 來建立使用者介面 應用程式。ConsumerMapFragment 可讓您定義 使用 FragmentConsumerMapView 則可讓您使用 View。共乘 ConsumerMapView 中的功能相同 ConsumerMapFragment,你可以依據需求選擇 無論是 View 還是 Fragment 更適合您的應用程式。

新增對 API 19 (KitKat) 和向量可繪項目的支援

如果您的應用程式設計需要 API 19 (KitKat) 裝置和向量可繪項目的支援, 將以下程式碼新增到活動中。這段程式碼 AppCompatActivity,即可使用 Consumer 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 回呼作業。然後,您會使用 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 (可以是空值),包含設定 的 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 一項活動,唯一的差別在於片段會加載包含 片段 onCreateView() 方法中的 MapView

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)
  }
}

調整相機縮放功能,將焦點放在特定旅程

Maps SDK 內建預設「我的位置」按鈕,會將相機置於裝置位置中心。

如果有正在進行的旅程分享工作階段,建議您將攝影機畫面置中 將重點放在旅程中,而非裝置位置資訊。

Android 專用的 Consumer SDK for Android 內建解決方案:AutoCamera

為讓您專注於旅程,而非裝置位置資訊, Consumer SDK 提供 AutoCamera 功能, 預設啟用的功能相機會放大並聚焦在分享歷程中, 預測下一個行程控點

AutoCamera

自訂相機行為

如果您需要進一步控管攝影機行為,可以停用或啟用 使用 ConsumerController.setAutoCameraEnabled() 來自動相機。

ConsumerController.getCameraUpdate() 目前會傳回目前建議的相機邊界。然後,您就能提供此 CameraUpdate 做為引數,給 GoogleMap.moveCamera()GoogleMap.animateCamera()

存取代僱駕駛服務與地圖

如要在應用程式中支援共乘和地圖互動功能,您必須具備存取權 傳送至 ConsumerGoogleMapConsumerController。 「ConsumerMapFragment」和 ConsumerMapView 都會以非同步方式傳回 ConsumerMapReadyCallback中有 ConsumerGoogleMap。 可退貨 (費用:ConsumerGoogleMap) 來自「getConsumerController()」的ConsumerController。個人中心 可以存取「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

ConsumerGoogleMapGoogleMap 類別。可讓應用程式執行下列操作: 會透過與地圖互動的 API, GoogleMap。使用消費者地圖可讓應用程式及乘車服務 分享功能,以流暢地與相同的基礎 GoogleMap 互動。例如: GoogleMap 僅允許單次回呼註冊,但 ConsumerGoogleMap 支援雙註冊回呼。 這些回呼可讓應用程式和共乘服務註冊回呼, 依序呼叫

ConsumerController

ConsumerController 可讓你使用共乘功能,例如 例如監控行程、控制行程狀態以及設定位置。

設定旅程分享

後端比對消費者與車輛後,請使用 JourneySharingSession 即可開始共用歷程的使用者介面歷程分享功能會顯示相符的項目 車輛位置和路線在應用程式中導入 SDK 後,您可以 用於監控行程、監聽更新及處理錯誤。 以下程序假設您使用後端服務,且 為媒合消費者和車輛提供服務

  1. 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?,
        ) {
          // ...
        }
    
      // ...
    })
    
  2. 使用 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 方法會顯示行程監控期間發生的錯誤。 Consumer SDK 的對照表 錯誤遵循相同的 HTTP/RPC 指南, Google Cloud Platform: 行程監控過程中出現的常見錯誤如下:

HTTP RPC 說明
400 人 INVALID_ARGUMENT 用戶端指定的行程名稱無效。 行程名稱必須遵循以下格式 providers/{provider_id}/trips/{trip_id}provider_id 必須是 服務供應商擁有的 Cloud 專案
401 年 未驗證 要求無法驗證,原因如下: 無效的 JWT 權杖。這個錯誤會發生 如果 JWT 權杖在未經過行程簽署的情況下簽署 ID 或 JWT 權杖已過期。
403 個 PERMISSION_DENIED 用戶端數量不足 權限。如果 JWT 含有這個錯誤 憑證無效,則用戶端沒有 權限或 API 尚未啟用 用戶端專案。JWT 權杖可能是 缺少憑證,或是符記已藉由行程簽署 與要求的行程 ID 不符。
429 人 RESOURCE_EXHAUSTED 資源配額為零或頻率 的流量超出上限。
503 個 目前無法購買 服務無法使用,一般是伺服器 相應的機會成本。
504 人 DEADLINE_EXCEEDED 已超出要求期限。這將 只有在呼叫端設定期限時才會發生 小於該方法的 期限 (即要求的期限並未 足以讓伺服器處理 請求) 且要求未完成 期限內。

若需更多資訊,請參閲 消費者 SDK 錯誤處理