การเริ่มต้นใช้งาน Driver SDK สําหรับ Android

คุณสามารถใช้ SDK ไดรเวอร์เพื่อให้การนำทางและการติดตามที่ดียิ่งขึ้นแก่แอปพลิเคชันการเดินทางและความคืบหน้าในการสั่งซื้อ Driver SDK มอบตำแหน่งยานพาหนะและการอัปเดตงานสำหรับ Fleet Engine ของโซลูชันการโดยสารและการนำส่งแบบออนดีมานด์

Driver SDK ช่วยให้บริการ Fleet Engine และบริการที่กำหนดเองทราบตำแหน่งและสถานะของรถอยู่เสมอ ตัวอย่างเช่น ยานพาหนะอาจเป็น ONLINE หรือ OFFLINE และตำแหน่งยานพาหนะจะเปลี่ยนไปตามการเดินทาง

ข้อกำหนดขั้นต่ำของระบบ

อุปกรณ์เคลื่อนที่ต้องใช้ Android 6.0 (API ระดับ 23) ขึ้นไป

การกำหนดค่า Maven

Driver SDK เวอร์ชัน 4.99 ขึ้นไปมีให้ใช้งานในที่เก็บ 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>

การกำหนดค่าโปรเจ็กต์

หากต้องการใช้ Driver SDK แอปของคุณต้องกำหนดเป้าหมายเป็น minSdkVersion ระดับ 23 ขึ้นไป

หากต้องการเรียกใช้แอปที่สร้างด้วย Driver SDK อุปกรณ์ Android นั้นต้องติดตั้งบริการ Google Play ไว้

ตั้งค่าโปรเจ็กต์การพัฒนา

วิธีตั้งค่าโปรเจ็กต์การพัฒนาและรับคีย์ API สำหรับโปรเจ็กต์ใน Google Cloud Console มีดังนี้

  1. สร้างโปรเจ็กต์ Google Cloud Console ใหม่หรือเลือกโปรเจ็กต์ที่มีอยู่เพื่อใช้กับ Driver SDK โปรดรอสักครู่จนกว่าโปรเจ็กต์ใหม่จะปรากฏใน Google Cloud Console

  2. เพื่อเรียกใช้แอปเดโม โปรเจ็กต์ต้องมีสิทธิ์เข้าถึง Maps SDK สำหรับ Android ใน Google Cloud Console ให้เลือก API และบริการ > ไลบรารี จากนั้นค้นหาและเปิดใช้ Maps SDK สำหรับ Android

  3. รับคีย์ API สำหรับโปรเจ็กต์โดยเลือก API และบริการ > ข้อมูลเข้าสู่ระบบ > สร้างข้อมูลเข้าสู่ระบบ > คีย์ API ดูข้อมูลเพิ่มเติมเกี่ยวกับการรับคีย์ API ได้ที่รับคีย์ API

เพิ่ม SDK ไดรเวอร์ลงในแอป

Driver SDK มีให้ใช้งานในที่เก็บ Google Maven ที่เก็บประกอบด้วยไฟล์ Project Object Model (.pom) และ Javadocs ของ SDK วิธีเพิ่ม Driver SDK ในแอป

  1. เพิ่มทรัพยากร Dependency ต่อไปนี้ในการกำหนดค่า Gradle หรือ Maven แทนตัวยึดตำแหน่ง VERSION_NUMBER สำหรับ 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

หากต้องการเพิ่มประสิทธิภาพงานนี้ คุณอาจใช้ปลั๊กอิน Secrets Gradle สำหรับ Android

วิธีติดตั้งปลั๊กอินและเก็บคีย์ API

  1. เปิดไฟล์ build.gradle ที่ระดับราก แล้วเพิ่มโค้ดต่อไปนี้ลงในองค์ประกอบ 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")
        }
    }
    
  2. เปิดไฟล์ build.gradle ระดับแอป แล้วเพิ่มโค้ดต่อไปนี้ลงในองค์ประกอบ plugins

    ดึงดูด

    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 ที่สมบูรณ์สำหรับแอปตัวอย่าง

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.driverapidemo">
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_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 ในแอป คุณต้องใส่ข้อความระบุแหล่งที่มาและใบอนุญาตโอเพนซอร์สเป็นส่วนหนึ่งของส่วนประกาศทางกฎหมายของแอป วิธีที่ดีที่สุดคือรวมการระบุแหล่งที่มาเป็นรายการในเมนูอิสระหรือเป็นส่วนหนึ่งของรายการในเมนูเกี่ยวกับ

ข้อมูลใบอนุญาตจะอยู่ในไฟล์ "Third_party_licenses.txt" ในไฟล์ AAR ที่ยกเลิกการเก็บ

ดูวิธีใส่ประกาศโอเพนซอร์สได้ที่ https://developers.google.com/android/guides/opensource

การอ้างอิง

หากคุณใช้ ProGuard เพื่อเพิ่มประสิทธิภาพบิลด์ คุณอาจต้องเพิ่มบรรทัดต่อไปนี้ลงในไฟล์การกำหนดค่า ProGuard

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

ระดับ API ขั้นต่ำที่รองรับคือ 23

เริ่มต้น SDK

ต้องระบุรหัสผู้ให้บริการ (โดยทั่วไปจะเป็นรหัสโปรเจ็กต์ Google Cloud) ในการเริ่มต้นออบเจ็กต์ DriverContext ดูรายละเอียดเพิ่มเติมเกี่ยวกับการตั้งค่าโปรเจ็กต์ Google Cloud ได้ที่การตรวจสอบสิทธิ์และการให้สิทธิ์

ก่อนที่จะใช้ Driver SDK คุณต้องเริ่มต้น Navigation SDK ก่อน วิธีเริ่มต้น SDK

  1. รับออบเจ็กต์ Navigator จาก NavigationApi

    Java

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

    Kotlin

    NavigationApi.getNavigator(
      this, // Activity
      object : NavigatorListener() {
        override fun onNavigatorReady(navigator: Navigator) {
          // Keep a reference to the Navigator (used to configure and start nav)
          this@myActivity.navigator = navigator
        }
      },
    )
    
  2. สร้างออบเจ็กต์ DriverContext เพื่อกรอกข้อมูลในช่องที่ต้องกรอก

    Java

    DriverContext driverContext = DriverContext.builder(application)
        .setProviderId(providerId)
        .setVehicleId(vehicleId)
        .setAuthTokenFactory(authTokenFactory)
        .setNavigator(navigator)
        .setRoadSnappedLocationProvider(
            NavigationApi.getRoadSnappedLocationProvider(application))
        .build();
    

    Kotlin

    val driverContext =
      DriverContext.builder(application)
        .setProviderId(providerId)
        .setVehicleId(vehicleId)
        .setAuthTokenFactory(authTokenFactory)
        .setNavigator(navigator)
        .setRoadSnappedLocationProvider(NavigationApi.getRoadSnappedLocationProvider(application))
        .build()
    
  3. ใช้ออบเจ็กต์ DriverContext เพื่อเริ่มต้น *DriverApi

    Java

    RidesharingDriverApi ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext);
    

    Kotlin

    val ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext)
    
  4. รับ RidesharingVehicleReporter จากออบเจ็กต์ API (*VehicleReporter ขยายระยะเวลา NavigationVehicleReporter)

    Java

    RidesharingVehicleReporter vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter();
    

    Kotlin

    val vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter()
    

กำลังตรวจสอบสิทธิ์กับ AuthTokenFactory

เมื่อ Driver SDK สร้างการอัปเดตตำแหน่ง ก็จะต้องส่งการอัปเดตเหล่านี้ไปยังเซิร์ฟเวอร์ Fleet Engine หากต้องการตรวจสอบสิทธิ์คำขอเหล่านี้ SDK ไดรเวอร์จะเรียกใช้ไปยังอินสแตนซ์ AuthTokenFactory ที่ผู้โทรระบุไว้ โรงงานมีหน้าที่สร้างโทเค็นการตรวจสอบสิทธิ์ ณ เวลาอัปเดตตำแหน่ง

วิธีสร้างโทเค็นมีความเฉพาะเจาะจงกับสถานการณ์ของนักพัฒนาซอฟต์แวร์แต่ละราย อย่างไรก็ตาม การติดตั้งใช้งานอาจจำเป็นต้อง

  • ดึงข้อมูลโทเค็นการตรวจสอบสิทธิ์ ซึ่งอาจอยู่ในรูปแบบ JSON จากเซิร์ฟเวอร์ HTTPS
  • แยกวิเคราะห์และแคชโทเค็น
  • โปรดรีเฟรชโทเค็นเมื่อหมดอายุ

โปรดดูรายละเอียดของโทเค็นที่เซิร์ฟเวอร์ Fleet Engine คาดหวังที่หัวข้อการสร้างโทเค็นเว็บ JSON (JWT) สำหรับการให้สิทธิ์

การจัดโครงสร้างของ AuthTokenFactory มีดังนี้

Java

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

Kotlin

class JsonAuthTokenFactory : AuthTokenFactory() {

  private var token: String = ""
  private var expiryTimeMs: Long = 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 fun getToken(context: AuthTokenContext): String {
    if (System.currentTimeMillis() > expiryTimeMs) {
      // The token has expired, go get a new one.
      fetchNewToken(authTokenContext.getVehicleId())
    }
     return token
  }

  fun fetchNewToken(vehicleId: String) {
    val url =
      Uri.Builder()
        .scheme("https")
        .authority("yourauthserver.example")
        .appendPath("token")
        .appendQueryParameter("vehicleId", vehicleId)
        .build()
        .toString()

    try {
      val reader = InputStreamReader(URL(url).openStream())

      reader.use {
        val obj = com.google.gson.JsonParser.parseReader(r).getAsJsonObject()

        token = obj.get("ServiceToken").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 (e: IOException) {
      // 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 RuntimeException("Could not get auth token", e)
    }
  }
}

การใช้งานเฉพาะนี้ใช้ไคลเอ็นต์ Java HTTP ในตัวเพื่อดึงข้อมูลโทเค็นในรูปแบบ JSON จากเซิร์ฟเวอร์การตรวจสอบสิทธิ์ของนักพัฒนาซอฟต์แวร์ ระบบจะบันทึกโทเค็น ไว้ใช้ซ้ำ ระบบจะดึงข้อมูลโทเค็นอีกครั้งหากโทเค็นเดิมอยู่ภายในช่วง 10 นาทีก่อนหมดอายุ

การติดตั้งใช้งานอาจดำเนินการต่างออกไป เช่น การใช้ชุดข้อความในเบื้องหลังเพื่อรีเฟรชโทเค็น

ข้อยกเว้นใน AuthTokenFactory จะถือเป็นชั่วคราว เว้นแต่จะเกิดขึ้นซ้ำๆ หลังจากพยายามติดต่อกันหลายครั้ง SDK ของไดรเวอร์จะสันนิษฐานว่าข้อผิดพลาดนั้นเป็นข้อผิดพลาดถาวรและจะหยุดพยายามส่งการอัปเดต

การรายงานสถานะและข้อผิดพลาดเกี่ยวกับ StatusListener

เนื่องจาก Driver SDK จะดำเนินการต่างๆ ในเบื้องหลัง ให้ใช้ StatusListener เพื่อทริกเกอร์การแจ้งเตือนเมื่อเกิดเหตุการณ์บางอย่าง เช่น ข้อผิดพลาด คำเตือน หรือข้อความแก้ไขข้อบกพร่อง ข้อผิดพลาดอาจเกิดขึ้นชั่วคราว (เช่น BACKEND_CONNECTIVITY_ERROR) หรืออาจทำให้การอัปเดตตำแหน่งหยุดลงอย่างถาวร (เช่น VEHICLE_NOT_FOUND ซึ่งบ่งชี้ถึงข้อผิดพลาดในการกำหนดค่า)

คุณระบุการติดตั้งใช้งาน StatusListener (ไม่บังคับ) ดังตัวอย่างต่อไปนี้

Java

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

Kotlin

class MyStatusListener : StatusListener() {
  /** Called when background status is updated, during actions such as location reporting. */
  override fun updateStatus(statusLevel: StatusLevel, statusCode: StatusCode, statusMsg: String) {
    // 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 เพื่อให้สื่อสารกับเซิร์ฟเวอร์ได้ โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้งาน SSL ใน Android จากบทความนี้ และบทความนี้ยังมีตัวอย่างโค้ดสำหรับการแพตช์ผู้ให้บริการด้านความปลอดภัยด้วย

การเปิดใช้การอัปเดตตำแหน่ง

เมื่อคุณมีอินสแตนซ์ *VehicleReporter แล้ว การเปิดใช้การอัปเดตตำแหน่งจะมีผลดังนี้

Java

RidesharingVehicleReporter reporter = ...;

reporter.enableLocationTracking();

Kotlin

val reporter = ...

reporter.enableLocationTracking()

ระบบจะส่งการอัปเดตตำแหน่งเป็นระยะๆ เมื่อสถานะของรถมีสถานะ ONLINE โปรดทราบว่าการเรียกใช้ reporter.enableLocationTracking() ไม่ได้ตั้งค่าสถานะรถยนต์เป็น ONLINE โดยอัตโนมัติ คุณต้องตั้งค่าสถานะรถอย่างชัดเจน

โดยค่าเริ่มต้น ช่วงเวลาการรายงานคือ 10 วินาที คุณเปลี่ยนแปลงช่วงเวลาการรายงานได้ด้วย reporter.setLocationReportingInterval(long, TimeUnit) ช่วงเวลาการอัปเดตขั้นต่ำที่รองรับคือ 5 วินาที การอัปเดตบ่อยขึ้นอาจส่งผลให้ คำขอทำงานช้าลงและมีข้อผิดพลาด

ปิดการอัปเดตตำแหน่ง

เมื่อเปลี่ยนกะคนขับเสร็จแล้ว คุณจะหยุดการอัปเดตตำแหน่งได้ และทำเครื่องหมายยานพาหนะให้ออฟไลน์อยู่ได้โดยโทรหา DeliveryVehicleReporter.disableLocationTracking หรือ RidesharingVehicleReporter.disableLocationTracking

การโทรครั้งนี้จะทำให้มีการตั้งเวลาการอัปเดตครั้งสุดท้ายให้นำส่งทันที ซึ่งบ่งชี้ว่ารถออฟไลน์อยู่ การอัปเดตนี้จะไม่มีตำแหน่งของผู้ใช้

การตั้งค่าสถานะของรถ

เมื่อเปิดใช้การอัปเดตตำแหน่ง การตั้งค่าสถานะของรถเป็น ONLINE จะทำให้ยานพาหนะพร้อมใช้งานสำหรับการค้นหา SearchVehicles ในทำนองเดียวกัน การทำเครื่องหมายยานพาหนะเป็น OFFLINE จะทำเครื่องหมายยานพาหนะว่าไม่พร้อมใช้งาน

คุณจะมีตัวเลือกในการตั้งค่าสถานะของรถยนต์ในฝั่งเซิร์ฟเวอร์ (ดูอัปเดตยานพาหนะ) หรือตั้งค่าใน SDK ไดรเวอร์โดยตรงดังนี้

Java

RidesharingVehicleReporter reporter = ...;

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

Kotlin

val reporter = ...

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

เมื่อเปิดใช้การอัปเดตตำแหน่ง การเรียกไปยัง setVehicleState จะมีผลในการอัปเดตตำแหน่งครั้งถัดไป

การทำเครื่องหมายยานพาหนะเป็น ONLINE เมื่อไม่ได้เปิดใช้การติดตามตำแหน่งจะส่งผลให้ได้รับ IllegalStateException รถอาจทำเครื่องหมายเป็น OFFLINE ได้หากยังไม่ได้เปิดใช้ หรือปิดใช้การติดตามตำแหน่งอย่างชัดเจน ซึ่งจะส่งผลให้มีการอัปเดตทันที การเรียกใช้ RidesharingVehicleReporter.disableLocationTracking() จะตั้งค่าสถานะพาหนะเป็น OFFLINE

โปรดทราบว่า setVehicleState จะแสดงผลทันที และจะมีการอัปเดตในชุดข้อความการอัปเดตตำแหน่ง ระบบจะเผยแพร่ข้อผิดพลาดในการอัปเดตสถานะรถโดยใช้ชุด StatusListener ที่เป็นตัวเลือกซึ่งระบุไว้ในการตั้งค่า DriverContext เช่นเดียวกับการจัดการข้อผิดพลาดเกี่ยวกับการอัปเดตตำแหน่ง