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

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

เนื่องจาก Consumer SDK มีสถาปัตยกรรมแบบแยกส่วน คุณจึงสามารถใช้ชิ้นส่วน API ที่คุณต้องการใช้สำหรับแอปพลิเคชันของคุณ และผสานรวม ด้วย API ของคุณเอง บริการแบ็กเอนด์จาก Fleet Engine และการเพิ่ม API ของแพลตฟอร์ม Google Maps

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

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

การกำหนดค่าบิลด์และการขึ้นต่อกัน

Consumer SDK เวอร์ชัน 1.99.0 ขึ้นไปมีให้ใช้งานโดยใช้ 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>

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

หากต้องการใช้ Consumer SDK สําหรับ Android แอปของคุณต้องกําหนดเป้าหมาย minSdkVersion 23 ขึ้นไป

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

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

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

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

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

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

เพิ่ม SDK ของผู้บริโภคลงในแอปของคุณ

Consumer SDK พร้อมให้ใช้งานผ่านที่เก็บส่วนตัวของ Maven มีไฟล์ Project Object Model (.pom) และ Javadocs ของ SDK วิธีเพิ่ม SDK ของผู้บริโภคลงในแอป

  1. ตั้งค่าสภาพแวดล้อมของคุณเพื่อเข้าถึงที่เก็บของ Maven ของโฮสต์ตามที่อธิบายไว้ใน ส่วนก่อนหน้า

    หากคุณประกาศการกำหนดค่าการจัดการทรัพยากร Dependency แบบรวมศูนย์ใน settings.gradle ให้ปิดใช้โดยทำดังนี้

    • นำโค้ดบล็อกต่อไปนี้ใน settings.gradle ออก:

      import org.gradle.api.initialization.resolve.RepositoriesMode
      dependencyResolutionManagement {
          repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
          repositories {
              google()
              mavenCentral()
          }
      }
      
  2. เพิ่มทรัพยากร Dependency ต่อไปนี้ในการกำหนดค่า Gradle หรือ Maven โดยแทนที่ VERSION_NUMBER ตัวยึดตำแหน่งสำหรับเวอร์ชัน SDK ของผู้บริโภคที่ต้องการ

    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. SDK ของผู้บริโภคจะขึ้นอยู่กับ Maps SDK ทรัพยากร Dependency นี้ได้รับการกำหนดค่าในลักษณะต่อไปนี้ หากเวอร์ชัน Maps SDK ไม่มีการกำหนดไว้อย่างชัดแจ้งใน ไฟล์การกำหนดค่าบิลด์ดังต่อไปนี้ เมื่อ Maps เวอร์ชันใหม่ เปิดตัว 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 ในเวอร์ชันของคุณ ระบบควบคุม ซึ่งควรจัดเก็บไว้ในไฟล์ local.properties อยู่ในไดเรกทอรีรากของโปรเจ็กต์ของคุณ ดูข้อมูลเพิ่มเติมเกี่ยวกับ local.properties ไฟล์ โปรดดู ไฟล์คุณสมบัติ Gradle

หากต้องการเพิ่มประสิทธิภาพงานนี้ คุณสามารถใช้ ปลั๊กอินข้อมูลลับ 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.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>

ใส่การระบุแหล่งที่มาที่จำเป็นในแอปของคุณ

หากใช้ SDK ของผู้บริโภคในแอป คุณจะต้องใส่ ข้อความระบุแหล่งที่มาและใบอนุญาตโอเพนซอร์สเป็นส่วนหนึ่งของประกาศทางกฎหมายของแอป คุณควรรวมการระบุแหล่งที่มาเป็นรายการเมนูอิสระหรือ ของรายการในเมนูเกี่ยวกับ

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

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

การตรวจสอบสิทธิ์ SDK ของผู้บริโภค

Consumer SDK มีการตรวจสอบสิทธิ์โดยใช้ JSON Web Token JSON Web Token (JWT) คือโทเค็นเพื่อการเข้าถึง JSON-base ที่มอบ หรืออ้างสิทธิ์ ในบริการหนึ่งๆ หลายครั้ง ตัวอย่างเช่น เซิร์ฟเวอร์อาจสร้าง โทเค็นที่มีการอ้างสิทธิ์ "เข้าสู่ระบบในฐานะผู้ดูแลระบบ" และระบุให้ ให้ลูกค้า จากนั้นไคลเอ็นต์จะใช้โทเค็นดังกล่าวเพื่อพิสูจน์ว่า มีการลงชื่อเข้าสู่ระบบในฐานะผู้ดูแลระบบ

Consumer SDK ใช้ JSON เว็บโทเค็นที่แอปพลิเคชันมีให้ ในการสื่อสารกับ Fleet Engine ดูข้อมูลเพิ่มเติมที่การตรวจสอบสิทธิ์และการให้สิทธิ์ของ Fleet Engine

โทเค็นการให้สิทธิ์ต้องมีการอ้างสิทธิ์ tripid:TRIP_ID ในโทเค็นของโทเค็น authorization โดยที่ TRIP_ID คือรหัสการเดินทาง ซึ่งทำให้ผู้บริโภค การเข้าถึงรายละเอียดการเดินทางของ SDK รวมถึงตำแหน่งของรถ เส้นทาง และเวลาถึงโดยประมาณ

Callback ของ JSON Web Token

Consumer SDK จะลงทะเบียน Callback ของโทเค็นการให้สิทธิ์ กับแอปพลิเคชันในระหว่างการเริ่มต้น SDK เรียกแอปพลิเคชัน เพื่อรับโทเค็นสำหรับคำขอเครือข่ายทั้งหมดที่ต้องมีการให้สิทธิ์

เราขอแนะนำเป็นอย่างยิ่งให้การให้สิทธิ์แคชการใช้งาน Callback ของคุณ และจะรีเฟรชโทเค็นใหม่เมื่อผ่านเวลา expiry แล้วเท่านั้น โทเค็นควร จะมีวันหมดอายุ 1 ชั่วโมง

การเรียกกลับของโทเค็นการให้สิทธิ์จะระบุโทเค็นบริการที่ต้องใช้ สำหรับบริการ TripService และยังมีtripIdที่จำเป็น สำหรับบริบท

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีนำการให้สิทธิ์ไปใช้ Callback ของโทเค็น

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 โปรดดู คู่มือผู้ใช้ Fleet Engine เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้างโปรเจ็กต์

แอปของคุณควรใช้ AuthTokenFactory ตามที่อธิบายไว้ใน การตรวจสอบสิทธิ์ 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 และ Maps

SDK สำหรับผู้บริโภคเวอร์ชัน 2.x.x รองรับ Maps SDK สำหรับ Android เวอร์ชัน 18.1.0 ขึ้นไป ตาราง ด้านล่างนี้สรุปตัวแสดงผลเริ่มต้นตามเวอร์ชัน Maps SDK และการรองรับ ของโหมดแสดงภาพทั้ง 2 ภาพ เราขอแนะนำให้ใช้โหมดแสดงภาพล่าสุด แต่ถ้าต้องการ ที่จะใช้ตัวแสดงผลแบบเดิม คุณจึงสามารถระบุอย่างชัดแจ้งโดยใช้ MapsInitializer.initialize()

เวอร์ชันของ Maps SDK รองรับโหมดแสดงภาพล่าสุด รองรับตัวแสดงผลแบบเดิม ตัวแสดงผลเริ่มต้น
เวอร์ชัน 18.1.0 และเวอร์ชันที่ต่ำกว่า ใช่ ใช่ เดิม*
V18.2.0 ใช่ ใช่ ล่าสุด

* การเปิดตัว Maps Renderer ใหม่ โหมดแสดงภาพล่าสุดจะเป็นค่าเริ่มต้น

เพิ่ม Maps SDK เป็นทรัพยากร Dependency

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>

เริ่มต้น Maps SDK ก่อนเริ่มต้น Consumer SDK

ใน Application หรือชั้นเรียน Activity ที่เพิ่งเริ่มต้น โปรดโทร MapsInitializer.initialize() และรอผลคำขอตัวแสดงผลก่อนเริ่มต้น 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()
      }
    })
  }

สร้างอินเทอร์เฟซผู้ใช้

คุณจะใช้ ConsumerMapFragment หรือ ConsumerMapView เพื่อสร้างอินเทอร์เฟซผู้ใช้สำหรับ แอปพลิเคชัน ConsumerMapFragment ช่วยให้คุณกำหนด แผนที่ของคุณโดยใช้ Fragment ในขณะที่ ConsumerMapView อนุญาตให้คุณใช้ View บริการร่วมเดินทาง ฟังก์ชันการทำงานจะเหมือนกันทั้งใน ConsumerMapView และ ConsumerMapFragment ดังนั้นคุณสามารถเลือก 1 รายการตาม ไม่ว่าจะเป็น View หรือ Fragment เหมาะกับแอปพลิเคชันของคุณมากกว่า

เพิ่มการรองรับ API 19 (KitKat) และ Vector แบบถอนออกได้

หากการออกแบบแอปกำหนดให้รองรับอุปกรณ์ API 19 (KitKat) และไฟล์เวกเตอร์ที่ถอนออกได้ เพิ่มโค้ดต่อไปนี้ลงในกิจกรรม รหัสนี้ครอบคลุมถึง AppCompatActivity เพื่อใช้ เวกเตอร์ที่ถอนออกได้ใน 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 ไม่พร้อมกันใน Callback จากนั้นใช้ 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() ใน นอกจากพารามิเตอร์ Callback แล้ว จะต้องมีกิจกรรมที่มี ส่วนย่อย และ 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 ใน กิจกรรมใดกิจกรรมหนึ่ง เว้นแต่ว่าส่วนย่อยจะขยายเลย์เอาต์ที่รวม MapView ในเมธอด onCreateView()

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 จะจับตำแหน่งกล้องไว้ที่ตำแหน่งของอุปกรณ์

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

Consumer SDK สำหรับโซลูชันในตัวของ Android: กล้องอัตโนมัติ

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

AutoCamera

การปรับแต่งลักษณะการทำงานของกล้อง

หากต้องการควบคุมลักษณะการทำงานของกล้องได้มากขึ้น คุณก็ปิดใช้หรือเปิดใช้ได้ กล้องอัตโนมัติที่ใช้ ConsumerController.setAutoCameraEnabled()

ConsumerController.getCameraUpdate() แสดงผลขอบเขตกล้องที่แนะนำในขณะนั้น จากนั้นคุณสามารถระบุ CameraUpdate นี้เป็นอาร์กิวเมนต์ให้กับ GoogleMap.moveCamera() หรือ GoogleMap.animateCamera()

เข้าถึงบริการร่วมเดินทางและแผนที่

คุณต้องมีสิทธิ์เข้าถึงจึงจะรองรับบริการร่วมเดินทางและการโต้ตอบบนแผนที่ในแอปพลิเคชันของคุณ ถึง ConsumerGoogleMap และ ConsumerController ConsumerMapFragment และ ConsumerMapView แสดงผลแบบไม่พร้อมกันทั้งคู่ ConsumerGoogleMap ใน ConsumerMapReadyCallback ConsumerGoogleMap ทำรีเทิร์น ConsumerController จาก getConsumerController() คุณ จะเข้าถึง 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

ConsumerGoogleMap คือคลาส Wrapper สำหรับ ชั้นเรียนGoogleMap ทำให้แอปของคุณสามารถ โต้ตอบกับแผนที่โดยใช้ API ที่เทียบเท่ากับ GoogleMap การใช้แผนที่ผู้บริโภคช่วยให้แอปของคุณ เพื่อโต้ตอบกับ Google Map เดียวกันได้อย่างราบรื่น ตัวอย่างเช่น GoogleMap อนุญาตให้ลงทะเบียน Callback เพียงครั้งเดียวและ ConsumerGoogleMap รองรับ Callback ที่ลงทะเบียนแบบคู่ Callback เหล่านี้ช่วยให้แอปและการแชร์รถโดยสารสามารถลงทะเบียน Callback ที่ ตามลำดับ

ConsumerController

ConsumerController ให้สิทธิ์เข้าถึงฟังก์ชันการโดยสารรถร่วมกัน เช่น ทั้งการตรวจสอบการเดินทาง การควบคุมสถานะการเดินทาง และการตั้งค่าสถานที่

ตั้งค่าการแชร์เส้นทาง

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

  1. ลงทะเบียน Listener บนออบเจ็กต์ 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 จะแสดงข้อผิดพลาดที่เกิดขึ้นระหว่างการตรวจสอบการเดินทาง การแมปสำหรับ SDK ของผู้บริโภค เป็นไปตามหลักเกณฑ์ HTTP/RPC เดียวกันที่สร้างขึ้นสำหรับ Google Cloud Platform ข้อผิดพลาดที่พบบ่อยที่เกิดขึ้นระหว่างการตรวจสอบการเดินทางมีดังนี้

HTTP RPC คำอธิบาย
400 INVALID_ARGUMENT ไคลเอ็นต์ระบุชื่อการเดินทางไม่ถูกต้อง ชื่อการเดินทางต้องเป็นไปตามรูปแบบ providers/{provider_id}/trips/{trip_id} provider_id ต้องเป็นรหัสของ โปรเจ็กต์ที่อยู่ในระบบคลาวด์ของผู้ให้บริการ
401 ไม่มีการตรวจสอบสิทธิ์ คำขอไม่ได้รับการตรวจสอบสิทธิ์เนื่องจาก โทเค็น JWT ไม่ถูกต้อง ข้อผิดพลาดนี้จะเกิดขึ้น หากมีการลงชื่อโทเค็น JWT โดยไม่มีการเดินทาง รหัสหรือโทเค็น JWT หมดอายุแล้ว
403 PERMISSION_DENIED ไคลเอ็นต์มีข้อมูลไม่เพียงพอ สิทธิ์ ข้อผิดพลาดนี้เกิดขึ้นหาก JWT โทเค็นไม่ถูกต้อง ไคลเอ็นต์ไม่มี หรือไม่ได้เปิดใช้ API สำหรับ โปรเจ็กต์ไคลเอ็นต์ โทเค็น JWT อาจเป็น สูญหายหรือโทเค็นมีการลงชื่อด้วยการเดินทาง รหัสไม่ตรงกับรหัสการเดินทางที่ขอ
429 RESOURCE_EXHAUSTED โควต้าทรัพยากรเป็นศูนย์หรืออัตรา ของการเข้าชมเกินขีดจำกัด
503 UNAVAILABLE ไม่พร้อมให้บริการ โดยปกติเซิร์ฟเวอร์ ไม่ทำงาน
504 DEADLINE_EXCEEDED เกินกำหนดเวลาในการส่งคำขอแล้ว การดำเนินการนี้จะ จะเกิดขึ้นก็ต่อเมื่อผู้โทรกำหนดเวลาไว้ สั้นกว่าค่าเริ่มต้นของเมธอด กำหนดเวลา (เช่น กำหนดเวลาที่ขอไม่ มากเพียงพอที่เซิร์ฟเวอร์จะประมวลผล คำขอ) และคำขอไม่เสร็จสมบูรณ์ ภายในกำหนดเวลา

สำหรับข้อมูลเพิ่มเติม โปรดดู การจัดการข้อผิดพลาด SDK ของผู้บริโภค