Bạn có thể sử dụng SDK trình điều khiển để cải thiện tính năng điều hướng và theo dõi vào ứng dụng Tiến trình đặt hàng và Chuyến đi của bạn. SDK trình điều khiển cung cấp thông tin cập nhật về vị trí của xe và nhiệm vụ liên quan đến Công cụ cho nhóm giải pháp gọi xe và giao hàng theo yêu cầu.
SDK Driver giúp các dịch vụ Fleet Engine và các dịch vụ tuỳ chỉnh của bạn luôn nhận biết
vị trí và trạng thái của xe. Ví dụ: xe có thể là ONLINE
hoặc OFFLINE
và vị trí của xe thay đổi khi chuyến đi diễn ra.
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
SDK trình điều khiển phiên bản 4.99 trở lên có trong kho lưu trữ Google Maven.
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 Trình điều khiển, ứng dụng của bạn phải nhắm mục tiêu
minSdkVersion
23 trở lên.
Để chạy một ứng dụng tạo bằng SDK trình điều khiển, Android thiết bị phải có 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à tải khoá API cho dự án trên Google Cloud Console:
Tạo dự án mới trên Google Cloud Console hoặc chọn một dự án hiện có để sử dụng thông qua SDK trình điều khiển. Đợi vài phút cho đến khi dự án mới sẽ hiển thị trên Bảng điều khiển Google Cloud.
Để chạy ứng dụng minh hoạ, dự án của bạn phải có quyền truy cập vào SDK bản đồ cho Android. Trong Google Cloud Console, hãy chọn API và Dịch vụ > thư viện, sau đó tìm kiếm và bật SDK Maps cho Android.
Nhận khoá API cho dự án bằng cách chọn 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 tải khoá API, hãy xem Tải khoá API.
Thêm SDK Trình điều khiển vào ứng dụng của bạn
SDK Trình điều khiển có sẵn trong kho lưu trữ Google Maven. Chiến lược phát hành đĩa đơn kho lưu trữ bao gồm các tệp Mô hình đối tượng dự án (.pom) của SDK và Javadocs. Cách thêm SDK Trình điều khiển vào ứng dụng:
Thêm phần phụ thuộc sau vào cấu hình Gradle hoặc Maven, thay thế phần phụ thuộc Phần giữ chỗ
VERSION_NUMBER
cho phiên bản SDK Trình điều khiển mong muốn.Gradle
Thêm phần sau vào
build.gradle
:dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-driver:VERSION_NUMBER' }
Maven
Thêm phần sau vào
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-driver</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
SDK trình điều khiển phụ thuộc vào SDK điều hướng, phần phụ thuộc này được định cấu hình trong một theo cách mà nếu cần một phiên bản cụ thể của SDK điều hướng, phiên bản đó phải rõ ràng được xác định trong tệp cấu hình bản dựng như sau, việc bỏ qua khối mã được đề cập sẽ cho phép dự án luôn tải xuống phiên bản mới nhất của SDK điều hướng trong phiên bản phát hành chính. Xin lưu ý rằng hành vi kết hợp của các phiên bản mới nhất của SDK trình điều khiển và SDK điều hướng đã trải qua quá trình thử nghiệm nghiêm ngặt trước khi phát hành.
Sắp xếp cấu hình phần phụ thuộc của quá trình phát triển và phát hành môi trường tương ứng.
Gradle
Thêm phần sau vào
build.gradle
:dependencies { ... implementation 'com.google.android.libraries.navigation:navigation:5.0.0' }
Maven
Thêm phần sau vào
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.libraries.navigation</groupId> <artifactId>navigation</artifactId> <version>5.0.0</version> </dependency> </dependencies>
Thêm khoá API vào ứng dụng của bạn
Sau khi bạn thêm SDK trình điều khiển 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 của dự án mà bạn đã nhận được khi thiết lập dự án phát triển của bạn.
Phần này mô tả cách lưu trữ khoá API để bạn có thể sử dụng khoá một cách an toàn hơn
mà ứng dụng của bạn tham chiếu đến. Bạn không nên kiểm tra khoá API trong phiên bản của mình
hệ thống kiểm soát. Thông tin này phải được lưu trữ trong tệp local.properties
, tức là
nằm trong thư mục gốc của dự án. Để biết thêm thông tin về
local.properties
tệp, xem
Các tệp thuộc tính Gradle.
Để đơn giản hoá công việc này, bạn có thể sử dụng Trình bổ trợ Secrets 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 cơ sở rồi thêm mã sau vào tệp 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 tệp 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 sử dụng Android Studio, đồng bộ hoá dự án với Gradle.
Mở
local.properties
trong thư mục cấp dự án rồi thêm sau đây. 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 trình bày một tệp kê khai hoàn chỉnh cho một ứng dụng mẫu:
<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>
Đưa các thuộc tính bắt buộc vào ứng dụng của bạn
Nếu sử dụng SDK Trình điều khiển trong ứng dụng, bạn phải thêm văn bản ghi công và giấy phép nguồn mở như một phần trong thông báo pháp lý của ứng dụng . Tốt nhất là nên bao gồm các thuộc tính dưới dạng một mục trình đơn độc lập hoặc dưới dạng một phần của mục trong trình đơn Giới thiệu.
Bạn có thể tìm thấy thông tin về giấy phép tại "third_party_permissions.txt" tệp trong tệp AAR đã huỷ lưu trữ.
Tham khảo https://developers.google.com/android/guides/opensource về cách đưa thông báo nguồn mở vào.
Phần phụ thuộc
Nếu bạn sử dụng ProGuard để tối ưu hoá bản dựng, bạn có thể cần thêm các dòng sau vào ProGuard tệp cấu hình:
-dontwarn com.google.**
-dontwarn okio.**
Cấp độ API tối thiểu được hỗ trợ là 23.
Khởi chạy SDK
Bạn phải có mã nhà cung cấp (thường là mã dự án trên Google Cloud) để
khởi tạo đối tượng DriverContext
. Để biết thêm chi tiết về cách thiết lập
Dự án trong Google Cloud, xem
Xác thực và uỷ quyền.
Trước khi sử dụng SDK trình điều khiển, trước tiên bạn phải khởi chạy SDK điều hướng. Cách khởi chạy SDK:
Lấy đối tượng
Navigator
từ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 } }, )
Tạo đối tượng
DriverContext
, điền sẵn các trường bắt buộc.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()
Sử dụng đối tượng
DriverContext
để khởi tạo*DriverApi
.Java
RidesharingDriverApi ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext);
Kotlin
val ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext)
Lấy
RidesharingVehicleReporter
từ đối tượng API. (*VehicleReporter
mở rộngNavigationVehicleReporter
.)Java
RidesharingVehicleReporter vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter();
Kotlin
val vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter()
Đang xác thực với AuthTokenFactory
Khi SDK Driver tạo thông tin cập nhật vị trí,
nó phải gửi những nội dung cập nhật này cho
máy chủ Fleet Engine. Để xác thực các yêu cầu này,
SDK trình điều khiển sẽ gọi ra phương thức gọi do người gọi cung cấp
thực thể của AuthTokenFactory
.
Nhà máy chịu trách nhiệm tạo mã thông báo xác thực tại vị trí
thời gian cập nhật.
Cách tạo mã thông báo chính xác sẽ tuỳ thuộc vào trường hợp của từng nhà phát triển. Tuy nhiên, việc triển khai có thể sẽ cần phải:
- tìm nạp mã thông báo xác thực (có thể ở định dạng JSON) từ một máy chủ HTTPS
- phân tích cú pháp và lưu mã thông báo vào bộ nhớ đệm
- làm mới mã thông báo khi hết hạn
Để biết thông tin chi tiết về các mã thông báo mà máy chủ Fleet Engine dự kiến, hãy xem Tạo Mã thông báo web JSON (JWT) để uỷ quyền.
Dưới đây là cách triển khai khung của 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)
}
}
}
Cách triển khai cụ thể này sử dụng ứng dụng HTTP Java tích hợp sẵn để tìm nạp một mã thông báo ở định dạng JSON từ máy chủ xác thực của nhà phát triển. Mã thông báo là đã lưu để sử dụng lại. Mã thông báo được tìm nạp lại nếu mã thông báo cũ nằm trong vòng 10 phút về thời gian hết hạn.
Quá trình triển khai của bạn có thể hoạt động theo cách khác, chẳng hạn như sử dụng luồng ở chế độ nền để làm mới mã thông báo.
Các ngoại lệ trong AuthTokenFactory
sẽ được xem là tạm thời, trừ phi có các ngoại lệ đó
lặp lại. Sau một số lần thử, SDK trình điều khiển
sẽ giả định rằng
lỗi này là vĩnh viễn và sẽ ngừng cố gắng gửi bản cập nhật.
Báo cáo trạng thái và lỗi với StatusListener
Vì SDK trình điều khiển thực hiện các hành động trong
ở chế độ nền, hãy sử dụng StatusListener
để kích hoạt thông báo khi nhất định
các sự kiện xảy ra, chẳng hạn như lỗi, cảnh báo hoặc thông báo gỡ lỗi. Có thể có lỗi
có tính chất tạm thời (chẳng hạn như BACKEND_CONNECTIVITY_ERROR
) hoặc chúng có thể
khiến thông tin cập nhật vị trí bị dừng vĩnh viễn (chẳng hạn như VEHICLE_NOT_FOUND
,
chỉ báo lỗi cấu hình).
Bạn có thể triển khai StatusListener
(không bắt buộc) như sau:
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.
}
}
Lưu ý về SSL/TLS
Trong nội bộ, việc triển khai SDK Trình điều khiển sử dụng
SSL/TLS để giao tiếp an toàn
với máy chủ Fleet Engine. Các phiên bản Android cũ hơn (API phiên bản 19 hoặc
thấp hơn) có thể cần bản vá SecurityProvider
để có thể giao tiếp với
máy chủ. Bạn sẽ thấy biểu tượng này
bài viết
để biết thêm thông tin về cách làm việc với SSL trong Android. Bài viết này cũng
chứa mã mẫu để vá trình cung cấp dịch vụ bảo mật.
Bật tính năng cập nhật vị trí
Sau khi bạn có một phiên bản *VehicleReporter
, thao tác bật tính năng cập nhật vị trí sẽ
đơn giản:
Java
RidesharingVehicleReporter reporter = ...;
reporter.enableLocationTracking();
Kotlin
val reporter = ...
reporter.enableLocationTracking()
Thông tin cập nhật vị trí được gửi định kỳ khi trạng thái xe đang
ONLINE
. Xin lưu ý rằng việc gọi reporter.enableLocationTracking()
không
tự động đặt trạng thái của xe thành ONLINE
. Bạn phải
đặt trạng thái xe một cách rõ ràng.
Theo mặc định, khoảng thời gian báo cáo là 10 giây. Khoảng thời gian báo cáo có thể
được thay đổi bằng reporter.setLocationReportingInterval(long, TimeUnit)
. Chiến lược phát hành đĩa đơn
khoảng thời gian cập nhật tối thiểu được hỗ trợ là 5 giây. Bản cập nhật thường xuyên hơn có thể
dẫn đến yêu cầu và lỗi chậm hơn.
Tắt cập nhật vị trí
Khi quá trình chuyển đổi của người lái xe hoàn tất, thông tin cập nhật vị trí có thể dừng lại và
xe được đánh dấu là không có kết nối mạng bằng cách gọi
DeliveryVehicleReporter.disableLocationTracking
hoặc
RidesharingVehicleReporter.disableLocationTracking
.
Lệnh gọi này sẽ khiến một bản cập nhật cuối cùng được lên lịch để gửi ngay, cho biết xe đang không kết nối mạng. Bản cập nhật này sẽ không chứa thông tin vị trí.
Đặt trạng thái xe
Khi tính năng cập nhật vị trí đang bật, việc đặt trạng thái của xe thành ONLINE
sẽ
hiển thị thông tin về xe cho SearchVehicles
cụm từ tìm kiếm; tương tự, đánh dấu
xe vì OFFLINE
sẽ đánh dấu xe là không có sẵn.
Bạn có thể đặt trạng thái xe ở phía máy chủ (xem phần Cập nhật phương tiện), hoặc trực tiếp trong SDK trình điều khiển:
Java
RidesharingVehicleReporter reporter = ...;
reporter.enableLocationTracking();
reporter.setVehicleState(VehicleState.ONLINE);
Kotlin
val reporter = ...
reporter.enableLocationTracking()
reporter.setVehicleState(VehicleState.ONLINE)
Khi bạn bật tính năng cập nhật vị trí, lệnh gọi đến setVehicleState
sẽ có hiệu lực lúc
thông tin cập nhật vị trí tiếp theo.
Bạn sẽ thấy xe được đánh dấu là ONLINE
khi tính năng theo dõi vị trí đang tắt
trong IllegalStateException
. Một chiếc xe có thể được đánh dấu là OFFLINE
khi
tính năng theo dõi vị trí chưa được bật hoặc bị tắt một cách rõ ràng. Kết quả là
trong bản cập nhật tức thì. Cuộc gọi đến
RidesharingVehicleReporter.disableLocationTracking()
sẽ
đặt trạng thái của xe thành OFFLINE
.
Xin lưu ý rằng setVehicleState
sẽ trả về ngay lập tức và quá trình cập nhật sẽ được thực hiện trên
chuỗi thông tin cập nhật vị trí. Tương tự như xử lý lỗi khi cập nhật vị trí, lỗi
cập nhật trạng thái xe được truyền bằng cách sử dụng tuỳ chọn được cung cấp
StatusListener
được đặt trong DriverContext
.