Xây dựng ứng dụng chỉ đường

Phần này mô tả chi tiết các tính năng khác nhau của thư viện mà bạn có thể sử dụng để triển khai chức năng của ứng dụng chỉ đường từng chặng.

Khai báo khả năng hỗ trợ chỉ đường trong tệp kê khai

Ứng dụng chỉ đường của bạn cần khai báo androidx.car.app.category.NAVIGATION danh mục ứng dụng cho ô tô trong bộ lọc ý định của CarAppService:

<application>
    ...
   <service
       ...
        android:name=".MyNavigationCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService" />
        <category android:name="androidx.car.app.category.NAVIGATION"/>
      </intent-filter>
    </service>
    ...
<application>

Hỗ trợ các ý định chỉ đường

Để hỗ trợ các Ý định chỉ đường cho ứng dụng của bạn, bao gồm cả những Ý định đến từ Trợ lý Google bằng cách sử dụng truy vấn bằng giọng nói, ứng dụng của bạn cần xử lý ý định CarContext.ACTION_NAVIGATE trong Session.onCreateScreenSession.onNewIntent.

Hãy xem tài liệu về CarContext.startCarApp để biết thông tin chi tiết về định dạng của ý định.

Truy cập vào các mẫu chỉ đường

Ứng dụng chỉ đường có thể truy cập các mẫu được thiết kế riêng (cho ứng dụng chỉ đường) sau đây. Tất cả các mẫu này hiển thị một nền tảng (surface) trong nền mà ứng dụng của bạn có thể truy cập để vẽ bản đồ của bạn, cùng với các thông tin khác do ứng dụng của bạn cung cấp (có thể khác nhau tuỳ theo mẫu).

  • NavigationTemplate: hiển thị bản đồ cùng với thông báo thông tin tuỳ chọn hoặc các đường đi định tuyến và số liệu ước tính di chuyển trong quá trình chỉ đường đang hoạt động.
  • PlaceListNavigationTemplate: hiển thị danh sách các địa điểm có thể có điểm đánh dấu tương ứng được vẽ trên bản đồ.
  • RoutePreviewNavigationTemplate: hiển thị danh sách các tuyến đường mà một trong số đó có thể được chọn và đánh dấu trong bản đồ.

Để biết thêm thông tin chi tiết về cách thiết kế giao diện người dùng của ứng dụng chỉ đường bằng các mẫu đó, xem Nguyên tắc thiết kế thư viện ứng dụng Android cho Ô tô.

Để có quyền truy cập vào các mẫu chỉ đường, ứng dụng của bạn cần khai báo quyền androidx.car.app.NAVIGATION_TEMPLATES trong AndroidManifest.xml:

<uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES"/>

Vẽ bản đồ

Các ứng dụng chỉ đường có thể truy cập vào Surface để vẽ bản đồ trên các mẫu liên quan.

Sau đó, ứng dụng có thể truy cập đối tượng SurfaceContainer bằng cách cài đặt một thực thể SurfaceCallback vào dịch vụ ô tô AppManager:

Kotlin

carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)

Java

carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);

SurfaceCallback cung cấp lệnh gọi lại khi SurfaceContainer có sẵn cùng với các lệnh gọi lại khác trong trường hợp các thuộc tính của Surface thay đổi.

Để có quyền truy cập vào nền tảng, ứng dụng của bạn cần khai báo quyền androidx.car.app.ACCESS_SURFACE trong AndroidManifest.xml:

<uses-permission android:name="androidx.car.app.ACCESS_SURFACE"/>

Khu vực nhìn thấy của bản đồ

Máy chủ có thể vẽ các phần tử giao diện người dùng cho nhiều mẫu khác nhau trên đầu bản đồ. Máy chủ lưu trữ sẽ giao tiếp khu vực được đảm bảo không bị che khuất và người dùng có thể nhìn thấy toàn bộ bằng cách gọi SurfaceCallback.onVisibleAreaChanged. Ngoài ra, để giảm thiểu số lượng thay đổi, máy chủ lưu trữ cũng sẽ gọi phương thức SurfaceCallback.onStableAreaChanged có hình chữ nhật nhỏ nhất hiển thị dựa trên mẫu hiện tại.

Ví dụ: Khi một ứng dụng chỉ đường đang sử dụng NavigationTemplate với một chuỗi hành động ở trên cùng, chuỗi hành động đó có thể tự ẩn khi người dùng không tương tác với màn hình trong một thời gian để có thêm không gian trên bản đồ. Trong trường hợp này, hệ thống sẽ gọi lại onStableAreaChangedonVisibleAreaChanged có cùng hình chữ nhật. Khi chuỗi hành động bị ẩn, chỉ onVisibleAreaChanged được gọi với khu vực lớn hơn. Nếu người dùng tương tác với màn hình, thì một lần nữa, chỉ onVisibleAreaChanged được gọi với hình chữ nhật đầu tiên.

Chế độ tối

Các ứng dụng chỉ đường phải vẽ lại bản đồ của ứng dụng vào thực thể Surface có màu tối thích hợp khi máy chủ lưu trữ xác định rằng các điều kiện đó đảm bảo cho thực thể, như đã mô tả trong nguyên tắc về chất lượng của ứng dụng Android Auto.

Để quyết định xem có nên vẽ bản đồ màu tối hay không, bạn có thể sử dụng phương thức CarContext.isDarkMode. Bất cứ khi nào trạng thái chế độ tối thay đổi, bạn sẽ nhận được một lệnh gọi tới Session.onCarConfigurationChanged.

Các ứng dụng chỉ đường phải truyền thêm siêu dữ liệu chỉ đường bằng máy chủ lưu trữ. Máy chủ lưu trữ sẽ sử dụng thông tin này để cung cấp thông tin cho đầu phát trung tâm của xe và để ngăn các ứng dụng chỉ đường xung đột về các tài nguyên dùng chung.

Bạn có thể cung cấp siêu dữ liệu chỉ đường thông qua dịch vụ ô tô NavigationManager có thể truy cập từ CarContext:

Kotlin

val navigationManager = carContext.getCarService(NavigationManager::class.java)

Java

NavigationManager navigationManager = carContext.getCarService(NavigationManager.class);

Bắt đầu, kết thúc và ngừng chỉ đường

Để quản lý nhiều ứng dụng chỉ đường, thông báo xác định tuyến đường và dữ liệu của cụm đồng hồ trên xe, máy chủ lưu trữ cần biết trạng thái chỉ đường hiện tại. Khi người dùng bắt đầu quá trình chỉ đường, ứng dụng phải gọi NavigationManager.navigationStarted. Tương tự, khi quá trình chỉ đường kết thúc, chẳng hạn như khi người dùng tới điểm đến hoặc người dùng huỷ quá trình chỉ đường, ứng dụng sẽ gọi NavigationManager.navigationEnded.

Bạn chỉ nên gọi NavigationManager.navigationEnded khi người dùng đã hoàn tất quá trình chỉ đường. Ví dụ: Nếu bạn cần tính toán lại tuyến đường khi đang ở giữa chuyến đi, hãy sử dụng Trip.Builder.setLoading(true).

Đôi khi, máy chủ lưu trữ cần một ứng dụng để ngừng quá trình chỉ đường và sẽ gọi stopNavigation trong đối tượng NavigationManagerListener do ứng dụng của bạn cung cấp thông qua NavigationManager.setListener. Sau đó, ứng dụng phải ngừng đưa ra thông tin về ngã rẽ tiếp theo trong màn hình cụm đồng hồ, thông báo chỉ đường và hướng dẫn bằng giọng nói.

Thông tin chuyến đi

Trong khi đang chỉ đường, ứng dụng cần gọi NavigationManager.updateTrip. Thông tin được cung cấp trong lệnh gọi này sẽ được sử dụng trong cụm đồng hồ và màn hình hiển thị ngang tầm mắt của xe. Không phải tất cả thông tin đều có thể hiển thị cho người dùng, tuỳ thuộc vào phương tiện cụ thể mà tài xế đang lái. Ví dụ: Đầu phát trung tâm trên máy tính để bàn cho thấy Step đã được thêm vào Trip, nhưng không hiển thị thông tin Destination.

Để kiểm thử rằng thông tin đang đi tới cụm đồng hồ, công cụ Đầu phát trung tâm trên máy tính để bàn (DHU) có thể được định cấu hình để hiển thị một màn hình cụm đồng hồ đơn giản. Tạo tệp cluster.ini có các nội dung sau:

[general]
instrumentcluster = true

Sau đó, bạn có thể gọi DHU bằng một tham số dòng lệnh khác:

dhu -c cluster.ini

Thông báo từng chặng

Bạn có thể đưa ra hướng dẫn chỉ đường từng chặng (TBT) kèm theo thông báo chỉ đường được cập nhật thường xuyên. Để được coi là thông báo chỉ đường trên màn hình ô tô, trình tạo của thông báo phải làm như sau:

  1. Đánh dấu thông báo là đang diễn ra bằng phương thức NotificationCompat.Builder.setOngoing.
  2. Đặt danh mục của thông báo thành Notification.CATEGORY_NAVIGATION.
  3. Mở rộng thông báo bằng CarAppExtender.

Thông báo chỉ đường sẽ hiển thị trong tiện ích dải điều hướng ở cuối màn hình ô tô. Nếu bạn đặt mức độ quan trọng của thông báo thành IMPORTANCE_HIGH, thông báo đó cũng sẽ hiển thị dưới dạng thông báo cảnh báo (HUN). Nếu bạn không đặt tầm quan trọng bằng phương thức CarAppExtender.Builder.setImportance, thì tầm quan trọng của kênh thông báo sẽ được sử dụng.

Ứng dụng có thể đặt PendingIntent trong CarAppExtender sẽ được gửi đến ứng dụng khi người dùng nhấn vào HUN hoặc tiện ích dải điều hướng.

Nếu NotificationCompat.Builder.setOnlyAlertOnce được gọi với giá trị true, thì thông báo có tầm quan trọng cao sẽ chỉ cảnh báo một lần trong HUN.

Đoạn mã sau đây cho biết cách tạo thông báo chỉ đường:

Kotlin

NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
    ...
    .setOnlyAlertOnce(true)
    .setOngoing(true)
    .setCategory(NotificationCompat.CATEGORY_NAVIGATION)
    .extend(
        CarAppExtender.Builder()
            .setContentTitle(carScreenTitle)
            ...
            .setContentIntent(
                PendingIntent.getBroadcast(
                    context,
                    ACTION_OPEN_APP.hashCode(),
                    Intent(ACTION_OPEN_APP).setComponent(
                        ComponentName(context, MyNotificationReceiver::class.java)),
                        0))
            .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
            .build())
    .build()

Java

new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
    ...
    .setOnlyAlertOnce(true)
    .setOngoing(true)
    .setCategory(NotificationCompat.CATEGORY_NAVIGATION)
    .extend(
        new CarAppExtender.Builder()
            .setContentTitle(carScreenTitle)
            ...
            .setContentIntent(
                PendingIntent.getBroadcast(
                    context,
                    ACTION_OPEN_APP.hashCode(),
                    new Intent(ACTION_OPEN_APP).setComponent(
                        new ComponentName(context, MyNotificationReceiver.class)),
                        0))
            .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
            .build())
    .build();

Nguyên tắc dành cho thông báo từng chặng

Các ứng dụng chỉ đường cần cập nhật thông báo TBT thường xuyên khi có thay đổi về khoảng cách. Theo đó, tiện ích dải điều hướng sẽ cập nhật và chỉ hiển thị thông báo dưới dạng HUN. Các ứng dụng có thể kiểm soát hành vi của HUN bằng cách đặt mức độ quan trọng của thông báo bằng phương thức CarAppExtender.Builder.setImportance. Việc đặt mức độ quan trọng thành IMPORTANCE_HIGH sẽ hiển thị HUN và việc đặt giá trị này thành bất kỳ giá trị nào khác sẽ chỉ cập nhật tiện ích dải điều hướng.

Hướng dẫn bằng giọng nói

Để phát hướng dẫn chỉ đường trên loa ô tô, ứng dụng của bạn phải yêu cầu quyền phát âm thanh. Là một phần trong AudioFocusRequest, bạn nên đặt mức sử dụng là AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE. Bạn cũng nên đặt mức lấy quyền phát là AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK.

Mô phỏng chức năng chỉ đường

Để xác minh chức năng chỉ đường của ứng dụng khi gửi ứng dụng đến Cửa hàng Google Play, ứng dụng của bạn phải triển khai lệnh gọi lại NavigationManagerCallback.onAutoDriveEnabled. Khi lệnh gọi lại này được gọi, ứng dụng của bạn sẽ mô phỏng chức năng chỉ đường tới điểm đến đã chọn khi người dùng bắt đầu quá trình chỉ đường. Ứng dụng của bạn có thể thoát khỏi chế độ này bất cứ khi nào vòng đời của Session hiện tại đạt đến trạng thái Lifecycle.Event.ON_DESTROY.

Bạn có thể kiểm thử để đảm bảo rằng việc triển khai onAutoDriveEnabled sẽ được gọi bằng cách thực thi lệnh sau từ một dòng lệnh:

adb shell dumpsys activity service CAR_APP_SERVICE_NAME AUTO_DRIVE

Ví dụ:

adb shell dumpsys activity service androidx.car.app.samples.navigation.car.NavigationCarAppService AUTO_DRIVE

Ứng dụng chỉ đường mặc định trên ô tô

Trong Android Auto, ứng dụng chỉ đường mặc định trên ô tô tương ứng với ứng dụng chỉ đường gần nhất mà người dùng khởi chạy. Ví dụ: Đây là ứng dụng sẽ nhận được ý định chỉ đường khi người dùng gọi lệnh chỉ đường thông qua trợ lý hoặc khi một ứng dụng khác gửi ý định bắt đầu quá trình chỉ đường.

Cho phép người dùng tương tác với bản đồ của bạn

Từ Car App API cấp 2 trở lên, bạn có thể thêm thao tác thu phóng và kéo vào bản đồ của mình trong NavigationTemplate để cho phép người dùng xem các phần khác nhau của bản đồ.

Phương thức SurfaceCallback

SurfaceCallback có ba phương pháp gọi lại cho phép bạn thêm tính tương tác trên bản đồ vào NavigationTemplate: onScale, onScrollonFling. Hãy xem bảng bên dưới để biết những lệnh gọi lại này liên quan như thế nào đến hoạt động tương tác của người dùng.

Hoạt động tương tác Phương thức SurfaceCallback
Chụm (thu phóng) onScale
Kéo bằng một lần nhấn onScroll
Hất bằng một lần nhấn onFling
Nhấn đúp onScale (với hệ số tỷ lệ do máy chủ lưu trữ mẫu xác định)
Lời nhắc xoay ở chế độ Kéo onScroll (có hệ số khoảng cách do máy chủ lưu trữ mẫu xác định)

Chuỗi hành động trên bản đồ

NavigationTemplate có thể có một chuỗi hành động trên bản đồ cho các hành động liên quan đến bản đồ như phóng to và thu nhỏ, căn giữa lại, hiển thị la bàn hoặc bất kỳ hành động nào khác mà ứng dụng có thể chọn hiển thị. Chuỗi hành động trên bản đồ có thể có tối đa bốn nút chỉ hiển thị bằng biểu tượng có thể được làm mới mà không ảnh hưởng đến chiều sâu của nhiệm vụ. Tương tự như Chuỗi hành động, chuỗi hành động trên bản đồ sẽ ẩn khi ở trạng thái rảnh và xuất hiện lại ở trạng thái đang hoạt động.

Để nhận được lệnh gọi lại về tính tương tác trên bản đồ, bạn phải thêm nút Action.PAN trong chuỗi hành động trên bản đồ. Nếu ứng dụng của bạn bỏ qua nút Action.PAN trong chuỗi hành động trên bản đồ, thì bạn sẽ không nhận được hoạt động đầu vào của người dùng từ các phương thức SurfaceCallback và máy chủ lưu trữ sẽ thoát khỏi mọi chế độ kéo đã kích hoạt trước đó. Khi người dùng nhấn nút kéo, máy chủ lưu trữ sẽ chuyển sang chế độ kéo. Trên màn hình cảm ứng, nút kéo sẽ không hiển thị.

Chế độ kéo

Ở chế độ kéo, máy chủ lưu trữ mẫu sẽ chuyển hoạt động đầu vào của người dùng từ các thiết bị đầu vào không nhấn (chẳng hạn như bộ điều khiển xoay và bàn di chuột) sang các phương thức SurfaceCallback thích hợp. Phản hồi hành động của người dùng để vào hoặc thoát chế độ kéo bằng phương thức setPanModeListener trong NavigationTemplate Builder. Máy chủ lưu trữ có thể ẩn các thành phần giao diện người dùng khác trong mẫu khi người dùng đang ở chế độ kéo.

Khu vực ổn định

Khu vực ổn định sẽ cập nhật giữa trạng thái rảnh và trạng thái hoạt động. Ứng dụng của bạn phải vẽ các thông tin liên quan đến việc lái xe như tốc độ, giới hạn tốc độ hoặc cảnh báo giao thông đường bộ tuỳ thuộc vào kích thước của khu vực ổn định để thông tin quan trọng trên bản đồ không bị chuỗi hành động trên bản đồ che khuất.