On-demand Rides and Deliveries Solution is currently available only to select partners.

Driver SDK for Android のスタートガイド

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

Driver SDK を使用して、移動や注文処理のアプリに高度なナビゲーションとトラッキングを提供できます。Driver SDK は車両の現在地とタスクの最新情報をオンデマンド配車および配達ソリューション フリート エンジンに提供します。

Driver SDK は Fleet Engine サービスとカスタム サービスに、車両の位置情報と状態を認識させます。たとえば、車両には ONLINE または OFFLINE を指定でき、車両の位置情報はルートの進行に伴って変化します。

最小システム要件

モバイル デバイスが Android 5.0(API レベル 21)以降を実行している必要があります。

Prerequisites

輸送と物流の Android SDK が Artifact Registry Maven リポジトリに公開されます。リポジトリには、SDK のプロジェクト オブジェクト モデル(.pom)ファイルとオフライン Javadoc が含まれています。

アクセスの取得

Google Workspace をご利用の場合は、オンボーディング時に google-maps-platform-sdk-users@workspacedomain.com などの Workspace グループを作成し、Google にその名前を指定します。これはおすすめの方法です。ワークスペース グループは、Maven リポジトリ gmp-artifacts/transportation へのアクセスを許可する許可リストに追加されます。 アクセスが必要なユーザーのメールアドレスとサービス アカウントのメールアドレスが、このリストに含まれていることを確認します。

組織で Workspace グループを作成できない場合は、これらのアーティファクトへのアクセスが必要なユーザーとサービス アカウントのメールアドレスのリストを Google に送信します。

ローカルでの開発

ローカル開発の場合は、Cloud SDK でログインするだけで十分です。

gcloud

gcloud auth login

ログインに使用するメールアドレスは、Workspace グループのメンバーである必要があります。

自動化(ビルドシステムまたは継続的インテグレーション)

ベスト プラクティスに従って自動化ホストを設定します。

  • Google Cloud 環境内でプロセスを実行する場合は、自動認証情報検出を使用します。

  • それ以外の場合は、サービス アカウント キーファイルをホストのファイル システムの安全な場所に保存し、GOOGLE_APPLICATION_CREDENTIALS 環境変数を適切に設定します。

認証情報に関連付けられたサービス アカウントのメールアドレスは、Workspace グループのメンバーである必要があります。

構成

ユーザーまたはサービスの認証情報を自動的に検出するように Maven または Gradle を構成します。

Gradle

プロジェクト ルート モジュール build.gradle ファイルではなく、アプリ モジュールの build.gradle ファイルに以下を追加します。

  plugins {
    id "com.google.cloud.artifactregistry.gradle-plugin" version "2.1.5"
  }
  repositories {
    maven {
      url "artifactregistry://us-west2-maven.pkg.dev/gmp-artifacts/transportation"
    }
  }

Maven

pom.xml に次の行を追加します。

  <repositories>
    <repository>
      <id>gmp-artifacts</id>
      <url>artifactregistry://us-west2-maven.pkg.dev/gmp-artifacts/transportation</url>
      <releases>
        <enabled>true</enabled>
      </releases>
    </repository>
  </repositories>
  <build>
    <extensions>
      <extension>
        <groupId>com.google.cloud.artifactregistry</groupId>
        <artifactId>artifactregistry-maven-wagon</artifactId>
        <version>2.1.0</version>
      </extension>
    </extensions>
  </build>

アクセスを確認する方法については、Java パッケージの管理をご覧ください。

Project Configuration

Driver SDK を使用するには、アプリで minSdkVersion 21 以降をターゲットにする必要があります。

Driver SDK を使用してビルドされたアプリを実行するには、Android デバイスに Google Play 開発者サービスがインストールされている必要があります。

開発プロジェクトを設定する

開発プロジェクトを設定し、Google Cloud Console でそのプロジェクトの API キーを取得するには:

  1. Driver SDK で使用する Google Cloud Console プロジェクトを新たに作成するか、既存のプロジェクトを選択します。Google Cloud Console に新しいプロジェクトが表示されるまで、数分待ちます。

  2. デモアプリを実行するには、プロジェクトから Maps SDK for Android にアクセスできる必要があります。Google Cloud Console で [API とサービス] ライブラリを選択し、Maps SDK for Android を検索して有効にします。

  3. プロジェクトの API キーを取得するには、[APIs & Services > Credentials > Create credentials > API key] を選択します。API キーの取得について詳しくは、API キーを取得するをご覧ください。

アプリに Driver SDK を追加する

Driver SDK は非公開の Maven リポジトリから入手できます。リポジトリには、SDK のプロジェクト オブジェクト モデル(.pom)ファイルと Javadocs が含まれています。Driver SDK をアプリに追加するには:

  1. Get Access の説明に従ってホストホスト リポジトリにアクセスする環境を設定します。
  2. Gradle または Maven の構成に次の依存関係を追加します。VERSION_NUMBER プレースホルダは、該当するバージョンの Driver SDK に置き換えてください。

    Gradle

    build.gradle に次の行を追加します。

    dependencies {
      ...
      implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-driver:VERSION_NUMBER'
    }
    

    Maven

    pom.xml に次の行を追加します。

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.mapsplatform.transportation</groupId>
        <artifactId>transportation-driver</artifactId>
        <version>VERSION_NUMBER</version>
      </dependency>
    </dependencies>
    

アプリに API キーを追加する

Driver SDK をアプリに追加したら、API キーをアプリに追加します。プロジェクト API キーは、開発プロジェクトを設定したときに取得したものを使用する必要があります。

このセクションでは、アプリで安全に参照されるように API キーを保存する方法について説明します。API キーをバージョン管理システムにチェックインしないでください。これは、プロジェクトのルート ディレクトリにある local.properties ファイルに保存する必要があります。local.properties ファイルについて詳しくは、Gradle プロパティ ファイルをご覧ください。

このタスクを効率化するには、Android 用 Secrets Gradle プラグインを使用します。

プラグインをインストールして 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.driverapidemo">
    <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>

必要な帰属情報をアプリに含める

アプリで Driver SDK を使用する場合は、アプリの法的通知の一部としてアトリビューション テキストとオープンソース ライセンスを含める必要があります。アトリビューションは、独立したメニュー項目として、または [概要] メニュー項目の一部として含めることをおすすめします。

必要なアトリビューション テキストとオープンソース ライセンスは、Driver SDK zip ファイルにあります。

  • NOTICE.txt
  • LICENSES.txt

依存関係

ProGuard を使用してビルドを最適化する場合は、ProGuard の構成ファイルに次の行を追加する必要があります。

-dontwarn com.google.**
-dontwarn okio.**

サポートされる最小 API レベルは 21 です。

SDK の初期化

DriverContext オブジェクトを初期化するには、プロバイダ ID(通常は Google Cloud プロジェクト ID)が必要です。Google Cloud プロジェクトの設定の詳細については、認証と認可をご覧ください。

Driver SDK を使用する前に、Navigation SDK を初期化する必要があります。SDK を初期化するには:

  1. NavigationApi から Navigator オブジェクトを取得します。

    NavigationApi.getNavigator(
        this, // Activity
        new NavigationApi.NavigatorListener() {
          @Override
          public void onNavigatorReady(Navigator navigator) {
            // Keep a reference to the Navigator (used to configure and start nav)
            this.navigator = navigator;
          }
        }
    );
    
  2. DriverContext オブジェクトを作成し、必須項目に入力します。

    DriverContext driverContext = DriverContext.builder(application)
        .setProviderId(providerId)
        .setVehicleId(vehicleId)
        .setAuthTokenFactory(authTokenFactory)
        .setNavigator(navigator)
        .setRoadSnappedLocationProvider(
            NavigationApi.getRoadSnappedLocationProvider(application))
        .build();
    
  3. DriverContext オブジェクトを使用して、*DriverApi を初期化します。

    RidesharingDriverApi ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext);
    
  4. API オブジェクトから RidesharingVehicleReporter を取得します。(*VehicleReporterNavigationVehicleReporter を拡張します)。

    RidesharingVehicleReporter vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter();
    

AuthTokenFactory を使用した認証

Driver SDK で位置情報の更新が生成されたら、その更新を Fleet Engine サーバーに送信する必要があります。これらのリクエストを認証するために、Driver SDK は呼び出し元が提供する AuthTokenFactory のインスタンスを呼び出します。ファクトリは、ロケーションの更新時に認証トークンを生成する役割を担います。

トークンが正確に生成される方法は、各デベロッパーの状況によって異なります。 ただし、実装ではおそらく次の条件を満たす必要があります。

  • HTTPS サーバーから認証トークン(多くの場合は JSON 形式)を取得する
  • トークンを解析してキャッシュに保存する
  • 有効期限が切れたらトークンを更新する

Fleet Engine サーバーが想定するトークンの詳細については、認可用の JSON ウェブトークン(JWT)の作成をご覧ください。

AuthTokenFactory のスケルトン実装を次に示します。

class JsonAuthTokenFactory implements AuthTokenFactory {
  private String token;  // initially null
  private long expiryTimeMs = 0;

  // This method is called on a thread whose only responsibility is to send
  // location updates. Blocking is OK, but just know that no location updates
  // can occur until this method returns.
  @Override
  public String getToken(AuthTokenContext authTokenContext) {
    if (System.currentTimeMillis() > expiryTimeMs) {
      // The token has expired, go get a new one.
      fetchNewToken(authTokenContext.getVehicleId());
    }
    return token;
  }

  private void fetchNewToken(String vehicleId) {
    String url =
        new Uri.Builder()
            .scheme("https")
            .authority("yourauthserver.example")
            .appendPath("token")
            .appendQueryParameter("vehicleId", vehicleId)
            .build()
            .toString();

    try (Reader r = new InputStreamReader(new URL(url).openStream())) {
      com.google.gson.JsonObject obj
          = com.google.gson.JsonParser.parseReader(r).getAsJsonObject();
      token = obj.get("Token").getAsString();
      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 10 minutes from that time.
      expiryTimeMs -= 10 * 60 * 1000;
    } catch (IOException e) {
      // It's OK to throw exceptions here. The StatusListener you passed to
      // create the DriverContext class will be notified and passed along the failed
      // update warning.
      throw new RuntimeException("Could not get auth token", e);
    }
  }
}

この実装では、組み込みの Java HTTP クライアントを使用して、デベロッパーの認証サーバーから JSON 形式のトークンを取得します。トークンは再利用のために保存されます。古いトークンの有効期限が 10 分以内の場合、トークンが再度フェッチされます。

実装によっては、バックグラウンド スレッドを使用してトークンを更新するなど、動作が異なる場合があります。

AuthTokenFactory の例外は、繰り返し発生する場合を除き、一時的な問題として扱われます。数回試した後、Driver SDK はエラーが永続的であると想定し、更新の送信を停止します。

StatusListener でのステータスと Error Reporting

Driver SDK はバックグラウンドでアクションを実行するため、StatusListener を使用して、エラー、警告、デバッグ メッセージなどの特定のイベントが発生したときに通知をトリガーします。エラーは性質上一時的なもの(BACKEND_CONNECTIVITY_ERROR など)である場合もあれば、位置情報の更新が恒久的に停止する場合もあります(VEHICLE_NOT_FOUND など、構成エラーを示します)。

次のようなオプションの StatusListener 実装を指定します。

class MyStatusListener implements StatusListener {
  /** Called when background status is updated, during actions such as location reporting. */
  @Override
  public void updateStatus(
      StatusLevel statusLevel, StatusCode statusCode, String statusMsg) {
    // Status handling stuff goes here.
    // StatusLevel may be DEBUG, INFO, WARNING, or ERROR.
    // StatusCode may be DEFAULT, UNKNOWN_ERROR, VEHICLE_NOT_FOUND,
    // BACKEND_CONNECTIVITY_ERROR, or PERMISSION_DENIED.
  }
}

SSL/TLS に関する注意事項

内部的に、Driver SDK の実装は SSL/TLS を使用して Fleet Engine サーバーと安全に通信します。古いバージョンの Android(API バージョン 19 以前)では、サーバーとの通信に SecurityProvider パッチが必要になる場合があります。Android で SSL を使用する方法については、こちらの記事をご覧ください。また、セキュリティ プロバイダにパッチを適用するためのコードサンプルも記載されています。

位置情報の更新を有効にする

*VehicleReporter インスタンスを取得すると、位置情報の更新の有効化は簡単です。

RidesharingVehicleReporter reporter = ...;

reporter.enableLocationTracking();

車両の状態が ONLINE になると、位置情報の更新が定期的に送信されます。reporter.enableLocationTracking() を呼び出しても、車両の状態が自動的に ONLINE に設定されることはありません。車両の状態を明示的に設定する必要があります。

レポート間隔は、デフォルトで 10 秒に設定されています。レポート間隔は reporter.setLocationReportingInterval(long, TimeUnit) で変更できます。サポートされる最小更新間隔は 5 秒です。更新頻度を上げると、リクエストとエラーが遅くなる可能性があります。

位置情報の更新を無効にする

運転手のシフトが終了したら、DeliveryVehicleReporter.disableLocationTracking または RidesharingVehicleReporter.disableLocationTracking を呼び出して、位置情報の更新を停止し、車両をオフラインとしてマークできます。

この呼び出しを行うと、最終アップデートが即時配信でスケジュールされ、車両がオフラインになったことが示されます。このアップデートには、ユーザーの位置情報は含まれません。

車両の状態の設定

位置情報の更新が有効になっている場合、車両の状態を ONLINE に設定すると、SearchVehicles クエリで車両が利用可能になります。同様に、車両を OFFLINE とマークすると、車両は使用不可としてマークされます。

車両の状態は、サーバー側に設定するか(車両を更新するを参照)、Driver SDK で直接設定することもできます。

RidesharingVehicleReporter reporter = ...;

reporter.enableLocationTracking();
reporter.setVehicleState(VehicleState.ONLINE);

位置情報の更新が有効になっている場合、setVehicleState の呼び出しは次の位置情報の更新時に反映されます。

位置情報のトラッキングが有効になっていないときに車両を ONLINE とマークすると、IllegalStateException になります。位置情報のトラッキングがまだ有効になっていないか、明示的に無効になっている車両は、OFFLINE とマークされることがあります。これにより、即座に更新されます。RidesharingVehicleReporter.disableLocationTracking() を呼び出すと、車両の状態が OFFLINE に設定されます。

setVehicleState はすぐに返され、更新は位置情報の更新スレッドで行われます。位置情報の更新のエラー処理と同様に、車両の状態の更新エラーは、DriverContext で設定されているオプションの StatusListener を使用して伝播されます。