Bạn có thể sử dụng SDK người tiêu dùng để tạo và chạy một ứng dụng cơ bản dành cho người tiêu dùng, được tích hợp với các dịch vụ phụ trợ Giải pháp gọi xe và giao hàng theo yêu cầu. Bạn có thể tạo ứng dụng Chuyến đi và Tiến trình đặt hàng có thể hiển thị chuyến đi đang hoạt động, phản hồi thông tin cập nhật về chuyến đi và xử lý các lỗi về chuyến đi.
Vì SDK người dùng có cấu trúc mô-đun, nên bạn có thể sử dụng các phần của API mà bạn muốn dùng cho ứng dụng cụ thể và tích hợp các phần đó với API riêng của bạn, các dịch vụ phụ trợ do Fleet Engine cung cấp và bổ sung API của Nền tảng Google Maps.
Yêu cầu tối thiểu về hệ thống
Thiết bị di động phải chạy Android 6.0 (API cấp 23) trở lên.
Cấu hình bản dựng và phần phụ thuộc
Người dùng SDK phiên bản 1.99.0 trở lên hiện có sẵn trong kho lưu trữ Maven của Google. Kênh kho lưu trữ riêng tư từng dùng hiện không còn được dùng nữa.
Gradle
Thêm đoạn mã sau vào tệp build.gradle
của bạn:
repositories {
...
google()
}
Maven
Thêm đoạn mã sau vào tệp pom.xml
của bạn:
<project>
...
<repositories>
<repository>
<id>google-maven-repository</id>
<url>https://maven.google.com</url>
</repository>
</repositories>
...
</project>
Cấu hình dự án
Để sử dụng SDK người tiêu dùng cho Android, ứng dụng của bạn phải nhắm đến minSdkVersion
23 trở lên.
Để chạy một ứng dụng được tạo bằng SDK người tiêu dùng, thiết bị Android phải cài đặt Dịch vụ Google Play.
Thiết lập dự án phát triển
Cách thiết lập dự án phát triển và lấy khoá API cho dự án trên Google Cloud Console:
Tạo dự án Google Cloud Console mới hoặc chọn dự án hiện có để sử dụng với SDK người dùng. Đợi vài phút cho đến khi dự án mới xuất hiện trên Google Cloud Console.
Để chạy ứng dụng minh hoạ, dự án của bạn phải có quyền truy cập vào SDK Maps dành cho Android. Trong Google Cloud Console, hãy chọn APIs & Services > Library (API và dịch vụ > Thư viện), sau đó tìm kiếm và bật SDK Maps cho Android.
Lấy khoá API cho dự án bằng cách chọn APIs & Services > Credentials > Create credentials > API key (API và Dịch vụ > Thông tin xác thực > Tạo thông tin xác thực > Khoá API). Để biết thêm thông tin về cách lấy khoá API, hãy xem bài viết Lấy khoá API.
Thêm Consumer SDK vào ứng dụng
SDK Người dùng được cung cấp qua một kho lưu trữ Maven riêng tư. Kho lưu trữ bao gồm các tệp Mô hình đối tượng dự án (.pom) của SDK và tài liệu Java. Cách thêm Consumer SDK vào ứng dụng:
Thiết lập môi trường để truy cập vào kho lưu trữ Maven của máy chủ như mô tả trong phần trước.
Nếu bạn đã khai báo cấu hình quản lý phần phụ thuộc tập trung trong
settings.gradle
, hãy vô hiệu hoá cấu hình đó như sau.Xoá khối mã dưới đây trong
settings.gradle
:import org.gradle.api.initialization.resolve.RepositoriesMode dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Thêm phần phụ thuộc sau vào cấu hình Gradle hoặc Maven, thay thế phần giữ chỗ
VERSION_NUMBER
cho phiên bản SDK người dùng mong muốn.Gradle
Thêm nội dung sau vào
build.gradle
của bạn:dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-consumer:VERSION_NUMBER' }
Maven
Thêm nội dung sau vào
pom.xml
của bạn:<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-consumer</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
Người dùng SDK phụ thuộc vào SDK Maps. Phần phụ thuộc này được định cấu hình theo cách mà nếu phiên bản của SDK Maps không được xác định rõ ràng trong tệp cấu hình bản dựng, chẳng hạn như khi phiên bản mới của SDK Maps được phát hành, SDK người tiêu dùng sẽ tiếp tục sử dụng phiên bản SDK Maps tối thiểu được hỗ trợ mà SDK đó yêu cầu.
Gradle
Thêm nội dung sau vào
build.gradle
của bạn:dependencies { ... implementation 'com.google.android.gms:play-services-maps:18.1.0' }
Maven
Thêm nội dung sau vào
pom.xml
của bạn:<dependencies> ... <dependency> <groupId>com.google.android.gms</groupId> <artifactId>play-services-maps</artifactId> <version>18.1.0</version> </dependency> </dependencies>
Thêm khoá API vào ứng dụng
Sau khi thêm SDK người dùng vào ứng dụng, hãy thêm khoá API vào ứng dụng. Bạn phải sử dụng khoá API dự án đã nhận được khi thiết lập dự án phát triển.
Phần này mô tả cách lưu trữ khoá API để ứng dụng của bạn có thể tham chiếu khoá đó một cách an toàn hơn. Bạn không nên kiểm tra khoá API trong hệ thống quản lý phiên bản của mình. Tệp này phải được lưu trữ trong tệp local.properties
, nằm trong thư mục gốc của dự án. Để biết thêm thông tin về tệp local.properties
, hãy xem các tệp thuộc tính Gradle.
Để đơn giản hoá tác vụ này, bạn có thể dùng Trình bổ trợ Bí mật cho Gradle cho Android.
Cách cài đặt trình bổ trợ và lưu trữ khoá API:
Mở tệp
build.gradle
ở cấp độ gốc rồi thêm mã sau vào phần tửdependencies
trongbuildscript
.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") } }
Mở tệp
build.gradle
ở cấp ứng dụng rồi thêm mã sau vào phần tửplugins
.Groovy
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
Nếu bạn sử dụng Android Studio, hãy đồng bộ hoá dự án với Gradle.
Mở
local.properties
trong thư mục cấp dự án, sau đó thêm mã sau. Thay thếYOUR_API_KEY
bằng khoá API.MAPS_API_KEY=YOUR_API_KEY
Trong tệp
AndroidManifest.xml
, hãy chuyển đếncom.google.android.geo.API_KEY
rồi cập nhật thuộc tínhandroid:value
như sau:<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
Ví dụ sau đây minh hoạ một tệp kê khai đầy đủ cho một ứng dụng mẫu:
<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>
Bao gồm các thuộc tính bắt buộc trong ứng dụng của bạn
Nếu sử dụng SDK Người tiêu dùng trong ứng dụng, bạn phải đưa văn bản phân bổ và giấy phép nguồn mở vào mục thông báo pháp lý của ứng dụng. Bạn nên đưa các thuộc tính vào dưới dạng mục trình đơn độc lập hoặc dưới dạng mục trong trình đơn About (Giới thiệu).
Bạn có thể tìm thấy thông tin về giấy phép tại tệp "third_party_ permissions.txt" trong tệp AAR đã huỷ lưu trữ.
Hãy tham khảo https://developers.google.com/android/guides/opensource để biết cách đưa thông báo nguồn mở vào.
Xác thực SDK người dùng
SDK người dùng cung cấp phương thức xác thực bằng mã thông báo web JSON. Mã thông báo web JSON (JWT) là mã truy cập cơ sở JSON cung cấp một hoặc nhiều thông báo xác nhận quyền sở hữu đối với một dịch vụ. Ví dụ: máy chủ có thể tạo một mã thông báo với yêu cầu "đăng nhập với tư cách quản trị viên" và cung cấp mã đó cho ứng dụng. Sau đó, ứng dụng có thể sử dụng mã thông báo đó để chứng minh rằng họ đã đăng nhập với tư cách quản trị viên.
SDK người dùng sử dụng Mã thông báo web JSON do ứng dụng cung cấp để giao tiếp với Fleet Engine. Xem bài viết Xác thực và uỷ quyền cho nhóm thiết bị để biết thêm thông tin.
Mã thông báo uỷ quyền phải bao gồm thông báo xác nhận quyền sở hữu tripid:TRIP_ID
trong tiêu đề authorization
của mã thông báo, trong đó TRIP_ID
là mã chuyến đi. Nhờ vậy, SDK người tiêu dùng có thể truy cập thông tin chi tiết về chuyến đi, bao gồm cả vị trí xe, tuyến đường và giờ đến dự kiến.
Lệnh gọi lại Mã thông báo web JSON
SDK người dùng sẽ đăng ký lệnh gọi lại mã thông báo uỷ quyền với ứng dụng trong quá trình khởi chạy. SDK gọi ứng dụng để lấy mã thông báo cho tất cả các yêu cầu mạng yêu cầu uỷ quyền.
Bạn nên chỉ nên làm mới các mã thông báo uỷ quyền trong bộ nhớ đệm khi triển khai lệnh gọi lại và chỉ làm mới các mã này khi thời gian expiry
đã trôi qua. Mã thông báo phải được phát hành với thời hạn là một giờ.
Lệnh gọi lại mã thông báo uỷ quyền chỉ định mã thông báo dịch vụ nào cần thiết cho dịch vụ TripService
. Mã này cũng cung cấp tripId
cần thiết cho ngữ cảnh.
Ví dụ về mã sau đây minh hoạ cách triển khai lệnh gọi lại mã thông báo uỷ quyền.
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
}
}
}
Khởi chạy API
Trước khi làm theo các quy trình này, hệ thống giả định rằng bạn đã bật các dịch vụ thích hợp và SDK người dùng.
Tải thực thể ConsumerApi
Để sử dụng SDK người dùng, ứng dụng của bạn cần khởi chạy ConsumerApi
không đồng bộ. API này là một singleton.
Phương thức khởi chạy sẽ lấy một AuthTokenFactory
. Nhà máy sẽ tạo mã thông báo JWT mới cho người dùng khi cần.
providerId
là Mã dự án cho dự án của bạn trên Google Cloud. Vui lòng xem Hướng dẫn sử dụng Fleet Engine để biết thêm thông tin về cách tạo dự án.
Ứng dụng của bạn nên triển khai AuthTokenFactory
như mô tả trong phần Xác thực SDK người tiêu dùng.
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
}
Khởi động SDK Maps để yêu cầu trình kết xuất ưu tiên
Người dùng SDK phiên bản 2.0.0 hỗ trợ SDK Bản đồ cho Android phiên bản 18.1.0 trở lên. Công cụ này hỗ trợ các yêu cầu chỉ định trình kết xuất đồ hoạ Google Maps ưu tiên. Để biết thông tin chi tiết, hãy tham khảo bài viết Trình kết xuất bản đồ mới(chọn sử dụng).
Thêm SDK Maps làm phần phụ thuộc
Gradle
Thêm nội dung sau vào build.gradle
của bạn:
dependencies {
//...
implementation "com.google.android.gms:play-services-maps:18.1.0"
}
Maven
Thêm nội dung sau vào pom.xml
của bạn:
<dependencies>
...
<dependency>
<groupId>com.google.android.gms</groupId>
<artifactId>play-services-maps</artifactId>
<version>18.1.0</version>
</dependency>
</dependencies>
Khởi chạy SDK bản đồ trước khi khởi chạy SDK người dùng
Trong lớp Application
hoặc khởi động Activity
, hãy gọi
MapsInitializer.initialize() và đợi kết quả yêu cầu kết xuất trước khi khởi chạy
SDK Người tiêu dùng.
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()
}
})
}
Tạo giao diện người dùng
Bạn có thể sử dụng ConsumerMapFragment
hoặc ConsumerMapView
để tạo giao diện người dùng cho ứng dụng của mình. ConsumerMapFragment
cho phép bạn xác định bản đồ bằng Fragment
, còn ConsumerMapView
cho phép bạn sử dụng View
. Chức năng chia sẻ chuyến đi giống nhau ở cả ConsumerMapView
và ConsumerMapFragment
, vì vậy, bạn có thể chọn một chế độ dựa trên việc View
hay Fragment
phù hợp hơn với ứng dụng của mình.
Thêm tính năng hỗ trợ cho API 19 (KitKat) và các vectơ vẽ được
Nếu thiết kế ứng dụng của bạn yêu cầu hỗ trợ các thiết bị API 19 (KitKat) và các vectơ vẽ được, hãy thêm mã sau vào Hoạt động của bạn. Mã này mở rộng
AppCompatActivity
để sử dụng
các vectơ vẽ được trong SDK người dùng.
Java
// ...
import android.support.v7.app.AppCompatActivity;
// ...
public class ConsumerTestActivity extends AppCompatActivity {
// ...
}
Kotlin
// ...
import android.support.v7.app.AppCompatActivity
// ...
class ConsumerTestActivity : AppCompatActivity() {
// ...
}
Thêm mảnh hoặc chế độ xem bản đồ
Bạn tạo bản đồ để hiển thị thông tin chia sẻ hành trình trong một mảnh Android hoặc thành phần hiển thị mà bạn xác định trong tệp XML bố cục ứng dụng (nằm trong /res/layout
). Sau đó, mảnh (hoặc chế độ xem) cung cấp quyền truy cập vào bản đồ chia sẻ hành trình mà ứng dụng của bạn có thể truy cập và sửa đổi. Bản đồ cũng cung cấp một đối tượng xử lý cho ConsumerController
, cho phép ứng dụng của bạn kiểm soát và tuỳ chỉnh trải nghiệm chia sẻ hành trình.
Bản đồ và tay điều khiển chế độ chia sẻ hành trình
Bạn xác định bản đồ chia sẻ hành trình dưới dạng một mảnh (sử dụng ConsumerMapFragment
) hoặc dưới dạng khung hiển thị (sử dụng ConsumerMapView
), như trong đoạn mã ví dụ sau đây. Khi đó, phương thức onCreate()
của bạn sẽ gọi getConsumerGoogleMapAsync(callback)
. Phương thức này sẽ trả về ConsumerGoogleMap
không đồng bộ trong lệnh gọi lại. Sau đó, bạn sử dụng ConsumerGoogleMap
để cho thấy hành trình chia sẻ và ứng dụng của bạn có thể cập nhật thông tin này nếu cần.
ConsumerMapFragment
Bạn xác định mảnh trong tệp XML bố cục ứng dụng, như được minh hoạ trong mã ví dụ sau đây.
<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" />
Lệnh gọi đến getConsumerGoogleMapAsync()
phải đến từ phương thức 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
Bạn có thể sử dụng thành phần hiển thị này trong một mảnh hoặc trong một hoạt động, như xác định trong tệp 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" />
Lệnh gọi đến getConsumerGoogleMapAsync()
phải từ onCreate()
. Ngoài tham số gọi lại, tham số này còn yêu cầu hoạt động hoặc mảnh có chứa hoạt động và GoogleMapOptions
(có thể mang giá trị rỗng) chứa các thuộc tính cấu hình cho MapView
. Lớp cơ sở hoạt động hoặc mảnh phải là FragmentActivity
hoặc Fragment
hỗ trợ (tương ứng), vì lớp này cung cấp quyền truy cập vào vòng đời của lớp đó.
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
trong một mảnh cũng giống như ví dụ trên đối với MapView
trong một hoạt động, ngoại trừ việc mảnh tăng cường bố cục chứa MapView
trong phương thức của mảnh 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)
}
}
Điều chỉnh mức thu phóng của máy ảnh để lấy nét trong hành trình
Nút Vị trí của tôi mặc định được tích hợp trong SDK Maps đặt máy ảnh vào vị trí thiết bị.
Nếu có một phiên Chia sẻ hành trình đang hoạt động, bạn nên căn giữa camera để tập trung vào hành trình thay vì vị trí của thiết bị.
Giải pháp tích hợp sẵn SDK người dùng cho Android: AutoCamera
Để cho phép bạn tập trung vào hành trình thay vì vị trí thiết bị, SDK người dùng sẽ cung cấp tính năng AutoCamera được bật theo mặc định. Máy ảnh sẽ thu phóng để tập trung vào tuyến đường chia sẻ hành trình và điểm tham chiếu chuyến đi tiếp theo.
Tuỳ chỉnh hoạt động của máy ảnh
Nếu cần kiểm soát hoạt động của máy ảnh nhiều hơn, bạn có thể tắt hoặc bật tính năng tự động camera bằng cách sử dụng ConsumerController.setAutoCameraEnabled().
ConsumerController.getCameraUpdate() trả về các giới hạn được đề xuất cho máy ảnh tại thời điểm đó. Sau đó, bạn có thể cung cấp CameraUpdate
này làm đối số cho GoogleMap.moveCamera() hoặc GoogleMap.animateCamera().
Sử dụng tính năng đi chung xe và bản đồ
Để hỗ trợ hoạt động tương tác trên bản đồ và đi chung xe trong ứng dụng, bạn cần có quyền truy cập vào ConsumerGoogleMap
và ConsumerController
.
ConsumerMapFragment
và ConsumerMapView
đều trả về không đồng bộ ConsumerGoogleMap
trong ConsumerMapReadyCallback
.
ConsumerGoogleMap
trả về ConsumerController
từ getConsumerController()
. Bạn có thể truy cập ConsumerGoogleMap
và ConsumerController
như sau.
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
là một lớp trình bao bọc cho lớp GoogleMap
. Công cụ này cho phép ứng dụng của bạn tương tác với bản đồ bằng một API tương đương với GoogleMap
. Việc sử dụng bản đồ người tiêu dùng cho phép ứng dụng và dịch vụ đi chung xe của bạn tương tác liền mạch với cùng một GoogleMap cơ bản. Ví dụ: GoogleMap
chỉ cho phép đăng ký một lệnh gọi lại duy nhất, nhưng ConsumerGoogleMap
hỗ trợ các lệnh gọi lại được đăng ký kép.
Các lệnh gọi lại này cho phép ứng dụng và dịch vụ đi chung xe đăng ký các lệnh gọi lại được gọi tuần tự.
ConsumerController
ConsumerController
cung cấp quyền truy cập vào chức năng đi chung xe như theo dõi chuyến đi, kiểm soát trạng thái chuyến đi và đặt vị trí.
Thiết lập tính năng chia sẻ hành trình
Sau khi phần phụ trợ đã so khớp người tiêu dùng với một chiếc xe, hãy sử dụng JourneySharingSession
để bắt đầu giao diện người dùng của tính năng chia sẻ hành trình. Tính năng chia sẻ hành trình cho thấy vị trí và tuyến đường của xe trùng khớp. Sau khi triển khai SDK trong ứng dụng, bạn có thể thêm chức năng theo dõi các chuyến đi, theo dõi thông tin cập nhật và xử lý lỗi.
Các quy trình sau đây giả định rằng các dịch vụ phụ trợ đã có sẵn và các dịch vụ so khớp người tiêu dùng với xe đang hoạt động.
Đăng ký trình nghe trên đối tượng
TripModel
để nhận thông tin chi tiết về chuyến đi, chẳng hạn như ETA (Thời gian đến ước tính) và quãng đường mà xe cần đi trước khi đến.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?, ) { // ... } // ... })
Thiết lập chuyến đi của bạn bằng
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)
Dừng chia sẻ hành trình
Đảm bảo rằng bạn ngừng chia sẻ hành trình khi không còn cần đến, chẳng hạn như khi hoạt động lưu trữ bị huỷ bỏ. Việc dừng chia sẻ hành trình cũng sẽ dừng các yêu cầu về mạng gửi tới Fleet Engine và ngăn chặn việc rò rỉ bộ nhớ.
Mã mẫu sau đây minh hoạ cách dừng chia sẻ hành trình.
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()
}
}
Xử lý lỗi chuyến đi
Phương thức onTripRefreshError
hiển thị các lỗi xảy ra trong quá trình giám sát chuyến đi.
Việc ánh xạ lỗi SDK người tiêu dùng tuân theo cùng các nguyên tắc HTTP/RPC được thiết lập cho Google Cloud Platform.
Sau đây là các lỗi thường gặp trong quá trình giám sát chuyến đi:
HTTP | RPC | Nội dung mô tả |
---|---|---|
400 | INVALID_ARGUMENT | Khách hàng đã chỉ định tên chuyến đi không hợp lệ. Tên chuyến đi phải theo định dạng providers/{provider_id}/trips/{trip_id} .
provider_id phải là mã nhận dạng của dự án trên đám mây do nhà cung cấp dịch vụ sở hữu. |
401 | KHÔNG XÁC THỰC | Yêu cầu chưa được xác thực do mã thông báo JWT không hợp lệ. Lỗi này sẽ xảy ra nếu mã thông báo JWT được ký mà không có mã chuyến đi hoặc mã thông báo JWT đã hết hạn. |
403 | PERMISSION_DENIED | Ứng dụng khách không có đủ quyền. Lỗi này xảy ra nếu mã thông báo JWT không hợp lệ, ứng dụng không có quyền hoặc API không được bật cho dự án ứng dụng. Có thể mã thông báo JWT bị thiếu hoặc mã thông báo được ký bằng một mã chuyến đi không khớp với mã chuyến đi đã yêu cầu. |
429 | RESOURCE_EXHAUSTED | Hạn mức tài nguyên bằng 0 hoặc tỷ lệ lưu lượng truy cập vượt quá giới hạn. |
503 | UNAVAILABLE | Dịch vụ hiện không hoạt động. Thông thường, máy chủ ngừng hoạt động. |
504 | DEADLINE_EXCEEDED | Đã quá thời hạn yêu cầu. Điều này sẽ chỉ xảy ra nếu phương thức gọi đặt ra một thời hạn ngắn hơn thời hạn mặc định của phương thức (tức là thời hạn được yêu cầu không đủ để máy chủ xử lý yêu cầu) và yêu cầu không hoàn tất trong thời hạn đó. |
Để biết thêm thông tin, hãy xem bài viết Xử lý lỗi SDK người tiêu dùng.