คุณสามารถใช้ Consumer 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 มีดังนี้
สร้างโปรเจ็กต์คอนโซล Google Cloud ใหม่หรือเลือกโปรเจ็กต์ที่มีอยู่เพื่อใช้กับ SDK ผู้บริโภค โปรดรอสักครู่จนกว่าโปรเจ็กต์ใหม่จะปรากฏใน Google Cloud Console
เพื่อเรียกใช้แอปเดโม โปรเจ็กต์ต้องมีสิทธิ์เข้าถึง Maps SDK สำหรับ Android ใน Google Cloud Console ให้เลือก API และบริการ > ไลบรารี จากนั้นค้นหาและเปิดใช้ Maps SDK สำหรับ Android
รับคีย์ API สำหรับโปรเจ็กต์โดยเลือก API และบริการ > ข้อมูลเข้าสู่ระบบ > สร้างข้อมูลเข้าสู่ระบบ > คีย์ API ดูข้อมูลเพิ่มเติมเกี่ยวกับการรับคีย์ API ได้ที่รับคีย์ API
เพิ่ม Consumer SDK ลงในแอป
Consumer SDK พร้อมให้ใช้งานผ่านที่เก็บ Maven ส่วนตัว ที่เก็บประกอบด้วยไฟล์ Project Object Model (.pom) และ Javadocs ของ SDK วิธีเพิ่ม Consumer SDK ลงในแอป
ตั้งค่าสภาพแวดล้อมเพื่อเข้าถึงที่เก็บ Maven ของโฮสต์ตามที่อธิบายไว้ในส่วนก่อนหน้านี้
หากคุณได้ประกาศการกำหนดค่าการจัดการทรัพยากร Dependency จากส่วนกลางไว้ใน
settings.gradle
ให้ปิดใช้ดังนี้นำโค้ดบล็อกต่อไปนี้ใน
settings.gradle
ออกimport org.gradle.api.initialization.resolve.RepositoriesMode dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
เพิ่มทรัพยากร Dependency ต่อไปนี้ลงในการกำหนดค่า Gradle หรือ Maven ของคุณ แล้วแทนที่ตัวยึดตำแหน่ง
VERSION_NUMBER
สำหรับเวอร์ชัน Consumer 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>
Consumer 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
หากต้องการเพิ่มประสิทธิภาพงานนี้ คุณอาจใช้ปลั๊กอิน Secrets Gradle สำหรับ Android
วิธีติดตั้งปลั๊กอินและเก็บคีย์ API
เปิดไฟล์
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") } }
เปิดไฟล์
build.gradle
ระดับแอป แล้วเพิ่มโค้ดต่อไปนี้ลงในองค์ประกอบplugins
ดึงดูด
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
หากใช้ Android Studio ให้ซิงค์โปรเจ็กต์กับ Gradle
เปิด
local.properties
ในไดเรกทอรีระดับโปรเจ็กต์ แล้วเพิ่มโค้ดต่อไปนี้ แทนที่YOUR_API_KEY
ด้วยคีย์ API ของคุณMAPS_API_KEY=YOUR_API_KEY
ในไฟล์
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>
ใส่การระบุแหล่งที่มาที่จำเป็นลงในแอปของคุณ
หากใช้ 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-base ที่มีการอ้างสิทธิ์อย่างน้อย 1 รายการในบริการต่างๆ ตัวอย่างเช่น เซิร์ฟเวอร์สามารถสร้างโทเค็นที่มีการอ้างสิทธิ์ว่า "เข้าสู่ระบบเป็นผู้ดูแลระบบ" และให้โทเค็นนั้นกับไคลเอ็นต์ จากนั้นไคลเอ็นต์จะใช้โทเค็นดังกล่าวเพื่อพิสูจน์ว่าโทเค็นเข้าสู่ระบบในฐานะผู้ดูแลระบบได้
Consumer SDK ใช้ JSON Web Token ที่แอปพลิเคชันมีให้เพื่อสื่อสารกับ Fleet Engine โปรดดูข้อมูลเพิ่มเติมที่การตรวจสอบสิทธิ์และการให้สิทธิ์ของ Flleet Engine
โทเค็นการให้สิทธิ์ต้องมีการอ้างสิทธิ์ tripid:TRIP_ID
ในส่วนหัว authorization
ของโทเค็น โดยที่ TRIP_ID
คือรหัสการเดินทาง ซึ่งทำให้ SDK ผู้บริโภคเข้าถึงรายละเอียดการเดินทาง รวมถึงตำแหน่งของรถ เส้นทาง และเวลาถึงโดยประมาณได้
โค้ดเรียกกลับของ JSON Web Token
Consumer SDK จะบันทึกการเรียกกลับโทเค็นการให้สิทธิ์กับแอปพลิเคชันในระหว่างการเริ่มต้น SDK จะเรียกแอปพลิเคชันให้รับโทเค็นสำหรับคำขอเครือข่ายทั้งหมดที่ต้องมีการให้สิทธิ์
เราขอแนะนำเป็นอย่างยิ่งให้ใช้โทเค็นการให้สิทธิ์แคชการใช้งานโค้ดเรียกกลับและรีเฟรชโทเค็นดังกล่าวเฉพาะเมื่อเวลาผ่านไป expiry
เท่านั้น โทเค็นควรออกเมื่อหมดอายุ 1 ชั่วโมง
โค้ดเรียกกลับของโทเค็นการให้สิทธิ์จะระบุว่าต้องใช้โทเค็นบริการใดสำหรับบริการ 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
หากต้องการใช้ SDK สำหรับผู้บริโภค แอปของคุณต้องเริ่มต้น ConsumerApi
แบบไม่พร้อมกัน API เป็น Singleton
วิธีเริ่มต้นจะใช้ AuthTokenFactory
โรงงานจะสร้างโทเค็น JWT ใหม่ให้กับผู้ใช้เมื่อจำเป็น
providerId
คือรหัสโปรเจ็กต์ของโปรเจ็กต์ Google Cloud ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้างโปรเจ็กต์ได้ที่คู่มือผู้ใช้ Flet 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 และโหมดแสดงภาพแผนที่
Consumer SDK v2.x.x รองรับ Maps SDK สำหรับ Android v18.1.0 ขึ้นไป ตารางด้านล่างจะสรุปตัวแสดงผลเริ่มต้นตามเวอร์ชัน Maps SDK และการรองรับตัวแสดงผลทั้ง 2 แบบ เราขอแนะนำให้ใช้ตัวแสดงผลล่าสุด แต่หากจำเป็นต้องใช้ตัวแสดงผลแบบเดิม ให้ระบุอย่างชัดเจนโดยใช้ MapsInitializer.initialize()
เวอร์ชัน Maps SDK | รองรับโหมดแสดงภาพล่าสุด | รองรับตัวแสดงผลแบบเดิม | ตัวแสดงผลเริ่มต้น |
---|---|---|---|
V18.1.0 และต่ำกว่า | ได้ | ได้ | เดิม* |
V18.2.0 | ได้ | ได้ | ล่าสุด |
* ด้วยการเปิดตัวโปรแกรมแสดงภาพแผนที่ใหม่ โหมดแสดงภาพล่าสุดจะเป็นค่าเริ่มต้น
เพิ่ม 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
คุณจึงเลือกโดยขึ้นอยู่กับว่า View
หรือ Fragment
เหมาะกับแอปพลิเคชันของคุณมากกว่า
เพิ่มการรองรับ API 19 (KitKat) และ Vector Drawables
หากการออกแบบแอปต้องการการรองรับอุปกรณ์ 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() {
// ...
}
เพิ่มมุมมองหรือส่วนย่อยของแผนที่
คุณสร้างแผนที่เพื่อแสดงการแชร์เส้นทางใน Fragment ของ Android หรือมุมมอง ซึ่งคุณกำหนดไว้ในไฟล์ XML ของเลย์เอาต์ของแอปพลิเคชัน (อยู่ใน
/res/layout
) จากนั้น Fragment (หรือมุมมอง) จะให้สิทธิ์เข้าถึงแผนที่ที่แชร์เส้นทาง ซึ่งแอปของคุณจะเข้าถึงและแก้ไขได้ แผนที่ยังมีแฮนเดิลให้ 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
มุมมองนี้สามารถใช้ใน Fragment หรือในกิจกรรมก็ได้ตามที่กำหนดไว้ในไฟล์ 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()
นอกเหนือจากพารามิเตอร์โค้ดเรียกกลับ พารามิเตอร์นี้ต้องมีกิจกรรมหรือ Fragment ที่มี และ GoogleMapOptions
(ซึ่งอาจเป็น Null) ซึ่งมีแอตทริบิวต์การกําหนดค่าสำหรับ MapView
คลาสกิจกรรมหรือคลาสฐาน Fragment ต้องเป็น 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
ใน Fragment เหมือนกับตัวอย่างด้านบนสำหรับ MapView
ในกิจกรรม เว้นแต่ว่า Fragment จะขยายเลย์เอาต์ที่รวม MapView
ในเมธอด Fragment 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 จะทำให้กล้องอยู่ตรงกลางตำแหน่งอุปกรณ์
หากมีเซสชันการแชร์เส้นทางการท่องเว็บอยู่ คุณอาจต้องตั้งกล้องให้อยู่ตรงกลางเพื่อโฟกัสที่การเดินทาง ไม่ใช่ตำแหน่งของอุปกรณ์
SDK สำหรับผู้บริโภคสำหรับโซลูชันในตัวของ Android: Autocamera
Consumer SDK มอบฟีเจอร์ Auto Camera ที่เปิดใช้โดยค่าเริ่มต้นเพื่อให้คุณโฟกัสกับการใช้งานแทนตำแหน่งอุปกรณ์ กล้องจะซูมเพื่อโฟกัสที่เส้นทางที่แชร์การเดินทางและจุดอ้างอิงการเดินทางถัดไป
การปรับแต่งลักษณะการทำงานของกล้อง
หากต้องการควบคุมลักษณะการทำงานของกล้องได้มากขึ้น คุณสามารถปิดหรือเปิดใช้ กล้องอัตโนมัติได้โดยใช้ ConsumerController.setAutoCameraEnabled()
ConsumerController.getCameraUpdate() จะแสดงขอบเขตกล้องที่แนะนำ ณ เวลานั้น จากนั้นคุณจะระบุ CameraUpdate
นี้เป็นอาร์กิวเมนต์ให้กับ GoogleMap.moveCamera() หรือ GoogleMap.animateCamera() ได้
ใช้บริการร่วมเดินทางและแผนที่
คุณต้องมีสิทธิ์เข้าถึง ConsumerGoogleMap
และ ConsumerController
เพื่อรองรับบริการร่วมเดินทางและการโต้ตอบกับแผนที่ในแอปพลิเคชันของคุณ
ConsumerMapFragment
และ ConsumerMapView
ทั้ง 2 ค่าจะแสดงผล 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 Maps ที่เกี่ยวข้องเดียวกันได้อย่างราบรื่น ตัวอย่างเช่น GoogleMap
อนุญาตให้มีการลงทะเบียนโค้ดเรียกกลับเพียงครั้งเดียว แต่ ConsumerGoogleMap
รองรับการเรียกกลับที่ลงทะเบียนแบบคู่
โค้ดเรียกกลับเหล่านี้ช่วยให้แอปและการแชร์รถของคุณลงทะเบียนการติดต่อกลับ ซึ่งจะเรียกใช้ตามลำดับได้
ConsumerController
ConsumerController
ให้สิทธิ์เข้าถึงฟังก์ชันบริการร่วมเดินทาง เช่น การตรวจสอบการเดินทาง การควบคุมสถานะการเดินทาง และการตั้งค่าตำแหน่ง
ตั้งค่าการแชร์เส้นทาง
หลังจากแบ็กเอนด์จับคู่ผู้บริโภคกับยานพาหนะแล้ว ให้ใช้ JourneySharingSession
เพื่อเริ่มอินเทอร์เฟซผู้ใช้ของการแชร์เส้นทาง การแชร์เส้นทางการท่องเว็บจะแสดงตำแหน่ง
ของยานพาหนะและเส้นทางที่ตรงกัน หลังจากติดตั้งใช้งาน SDK ในแอปแล้ว คุณสามารถเพิ่มฟังก์ชันสำหรับตรวจสอบการเดินทาง ฟังอัปเดต และจัดการข้อผิดพลาดได้
ขั้นตอนต่อไปนี้จะถือว่ามีบริการแบ็กเอนด์ที่ใช้งานอยู่แล้ว และบริการของคุณสำหรับการจับคู่ผู้บริโภคกับยานพาหนะนั้นใช้งานได้
ลงทะเบียนผู้ฟังในออบเจ็กต์
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 และป้องกันไม่ให้หน่วยความจำรั่วไหลด้วย
โค้ดตัวอย่างต่อไปนี้แสดงวิธีหยุดการแชร์เส้นทาง
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 ต้องเป็นรหัสของโปรเจ็กต์ที่อยู่ในระบบคลาวด์ของผู้ให้บริการ |
401 | ไม่ได้ตรวจสอบสิทธิ์ | คำขอไม่ได้รับการตรวจสอบสิทธิ์เนื่องจากโทเค็น JWT ไม่ถูกต้อง ข้อผิดพลาดนี้จะเกิดขึ้นหากมีการเซ็นโทเค็น JWT โดยไม่มีรหัสทริปหรือโทเค็น JWT หมดอายุ |
403 | PERMISSION_DENIED | ไคลเอ็นต์ไม่มีสิทธิ์เพียงพอ ข้อผิดพลาดนี้จะเกิดขึ้นหากโทเค็น JWT ไม่ถูกต้อง ไคลเอ็นต์ไม่มีสิทธิ์ หรือไม่ได้เปิดใช้ API สำหรับโปรเจ็กต์ไคลเอ็นต์ โทเค็น JWT อาจขาดหายไปหรือมีการลงชื่อด้วยรหัสการเดินทางที่ไม่ตรงกับรหัสการเดินทางที่ขอ |
429 | RESOURCE_EXHAUSTED | โควต้าทรัพยากรเป็น 0 หรืออัตราการรับส่งข้อมูลเกินขีดจำกัด |
503 | UNAVAILABLE | ไม่พร้อมให้บริการ โดยทั่วไปเซิร์ฟเวอร์จะล่ม |
504 | DEADLINE_EXCEEDED | เกินกำหนดเวลาในการส่งคำขอแล้ว กรณีนี้จะเกิดขึ้นก็ต่อเมื่อผู้โทรมีกำหนดเวลา ที่น้อยกว่ากำหนดเวลาเริ่มต้นของเมธอด (เช่น กำหนดเวลาที่ขอมาไม่เพียงพอให้เซิร์ฟเวอร์ประมวลผลคำขอ) และคำขอไม่เสร็จสิ้นภายในกำหนดเวลา |
ดูข้อมูลเพิ่มเติมได้ที่ การจัดการข้อผิดพลาดเกี่ยวกับ SDK ของผู้บริโภค