Kể từ ngày 27 tháng 3 năm 2025, bạn nên sử dụng android-latest-release
thay vì aosp-main
để xây dựng và đóng góp cho AOSP. Để biết thêm thông tin, hãy xem phần Thay đổi đối với AOSP.
Định cấu hình máy chủ AppCard
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Sử dụng AppCardHost
để giao tiếp với các ứng dụng hiển thị Thẻ ứng dụng.
Quyền
Mọi ứng dụng sử dụng AppCardHost
đều phải có các quyền sau:
android.permission.INTERACT_ACROSS_USERS_FULL
android.permission.QUERY_ALL_PACKAGES
- (Chỉ trong API cấp 34 trở lên)
android.car.permission.BIND_APP_CARD_PROVIDER
Khởi chạy
Để khởi chạy máy chủ lưu trữ, hãy cung cấp:
- Ngữ cảnh
updateRate
Tốc độ cập nhật AppCard tính bằng mili giây.
fastUpdateRate
Tốc độ cập nhật tính bằng mili giây cho các thành phần được gắn thẻ bằng EnforceFastUpdateRate
responseExecutor
Một luồng mà bạn muốn nhận phản hồi từ các ứng dụng AppCard.
Thiết kế
Bạn có thể tương tác với AppCardHost
theo một trong hai cách sau:
HOẶC
AppCardListener
Thành phần AppCardListener
tự đăng ký với AppCardHost
để nhận thông tin cập nhật về thông tin liên lạc từ các ứng dụng AppCardHost
và AppCard.
Các hàm giao diện của AppCardListener
được trình bày chi tiết tại đây.
fun onAppCardReceived(AppCardContainer)
Hàm này được kích hoạt khi nhận được một Thẻ ứng dụng từ một ứng dụng. Hàm này được gửi dưới dạng AppCardContainer
, cung cấp một Thẻ ứng dụng và appIdentifier
để xác định ứng dụng đã gửi Thẻ ứng dụng
fun onComponentReceived(AppCardComponentContainer)
Hàm này được kích hoạt khi nhận được một thành phần AppCard từ một ứng dụng. Hàm này được gửi dưới dạng AppCardComponentContainer
, cung cấp một thành phần AppCards, Identifier
để xác định ứng dụng đã gửi AppCard và một mã nhận dạng chuỗi để trỏ đến AppCard mà thành phần liên quan.
fun onProviderRemoved(String, String?)
Hàm này được kích hoạt khi một trình cung cấp AppCard đã bị xoá hoặc tắt. Sử dụng phương thức này để dọn dẹp mọi AppCard đang hoạt động liên quan đến tên gói và quyền của nhà cung cấp đã cho.
Nếu authority là {@code null}
, thì toàn bộ gói đã bị xoá.
fun onProviderAdded(String, String?)
Hàm này được kích hoạt khi bạn thêm hoặc bật một nhà cung cấp AppCard.
Ví dụ về cách sử dụng. Sử dụng hàm này làm điều kiện kích hoạt để làm mới tất cả CardApp có sẵn trong bộ chọn CardApp. Nếu quyền là {@code null}
, thì toàn bộ gói đã được thêm.
fun onPackageCommunicationError(appIdentifier, Throwable)
Chức năng này được kích hoạt khi AppCardHost
gặp lỗi khi giao tiếp với nhà cung cấp AppCard.
Ví dụ về cách sử dụng. Sử dụng phương thức này để cho người dùng biết rằng một AppCard mà họ đã chọn đã gặp lỗi.
API
fun refreshCompatibleapp()
Bạn nên gọi phương thức này bất cứ khi nào hoạt động đang sử dụng máy chủ lưu trữ được tiếp tục để máy chủ lưu trữ có thể làm mới danh sách ứng dụng hỗ trợ Thẻ ứng dụng.
fun destroy()
Gọi phương thức này khi một hoạt động đang sử dụng máy chủ bị huỷ để máy chủ có thể dọn dẹp tất cả các kết nối và thành phần nội bộ.
fun registerListener(AppCardListener)
Dùng để đăng ký AppCardListener
.
fun unregisterListener(AppCardListener)
Dùng để huỷ đăng ký AppCardListener
.
fun getAllAppCards(AppCardContext)
Gọi phương thức này để cung cấp AppCardListener
đã đăng ký với tất cả AppCard được cung cấp trong hệ thống bằng một AppCardContext
nhất định, cung cấp gợi ý cho các nhà cung cấp về cách định cấu trúc AppCard của họ.
fun requestAppCard(AppCardContext, appIdentifier, String)
Gọi phương thức này để cung cấp một AppCardListener
đã đăng ký bằng một AppCard cụ thể, với điều kiện là AppCardContext
đưa ra gợi ý cho các nhà cung cấp về cách định cấu trúc AppCard của họ.
fun notifyAppCardRemoved(appIdentifier, String)
Thông báo cho nhà cung cấp Thẻ ứng dụng rằng Thẻ ứng dụng của họ không còn hoạt động nữa.
fun notifyAppCardInteraction(appIdentifier, String, String, String)
Thông báo cho nhà cung cấp Thẻ ứng dụng rằng người dùng đã tương tác với Thẻ ứng dụng của họ.
Lượt tương tác duy nhất được hỗ trợ là lượt nhấp vào nút, được biểu thị bằng AppCardMessageConstants.InteractionMessageConstants.MSG_INTERACTION_ON_CLICK
.
Bạn nên tạo một nút cho AppCard bằng trình nghe onClick
gọi hàm này bằng appIdentifier
, mã AppCard, mã thành phần và mã tương tác.
fun sendAppCardContextUpdate(AppCardContext, appIdentifier, String)
Gửi bản cập nhật AppCardContext
cho một AppCard cụ thể. Ví dụ: khi chuyển từ chế độ Đỗ xe sang chế độ Lái xe, hãy sử dụng phương thức này để gửi bản cập nhật AppCardContext
, trong đó isInteractable
được đặt thành false
cho mỗi AppCard đang hoạt động.
Câu hỏi thường gặp
Tôi có thể tìm thấy các cách triển khai mẫu ở đâu?
Máy chủ lưu trữ mẫu. Hiển thị tất cả AppCard có sẵn trong hệ thống, cùng với các tính năng kiểm thử.
DriverUI và Trình quản lý Pano. Trình quản lý Pano đóng vai trò là bộ chọn trong khi DriverUI đóng vai trò là trình trình bày.
Mỗi AppCardContentProvider
có thể hỗ trợ bao nhiêu AppCard?
AppCardContentProvider
có thể hỗ trợ vô số AppCard.
Tuy nhiên, hãy nhớ cân bằng số lượng Thẻ ứng dụng với hiệu suất bị giảm so với trải nghiệm người dùng tích cực.
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-06-26 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-06-26 UTC."],[],[],null,["# Configure an AppCard host\n\nUse `AppCardHost` to communicate with apps that show AppCards.\n\nPermissions\n-----------\n\nAny app that uses an `AppCardHost` must have the following permissions:\n\n- `android.permission.INTERACT_ACROSS_USERS_FULL`\n- `android.permission.QUERY_ALL_PACKAGES`\n- (In API level 34 and higher **only** ) `android.car.permission.BIND_APP_CARD_PROVIDER`\n\nInitialize\n----------\n\nTo initialize the host, provide:\n\n- Context\n- `updateRate` AppCard update rate in milliseconds.\n- `fastUpdateRate` Update rate in milliseconds for components tagged with `EnforceFastUpdateRate`\n- `responseExecutor` A thread on which you want to receive responses from AppCard apps.\n\nDesign\n------\n\nAn `AppCardHost` can be interacted with in one of two ways:\n\n- Register as an [`AppCardListener`](#appcardlistener)\n\nOR,\n\n- Interact with the [`AppCardHost` APIs](#api)\n\n### AppCardListener\n\nThe `AppCardListener` component registers itself with an `AppCardHost`\nto receive communication updates from the `AppCardHost` and AppCard apps.\nThe interface functions of an `AppCardListener` are detailed here.\n\n\u003cbr /\u003e\n\n`fun onAppCardReceived(AppCardContainer)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nThis function is triggered when an AppCard has been received from an app. It's sent as an `AppCardContainer` which provides an AppCard and an `appIdentifier` to identify the app that sent the AppCard\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun onComponentReceived(AppCardComponentContainer)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nThis function is triggered when an AppCard component is received from an app. It's sent as an `AppCardComponentContainer`, which provides an AppCards component, `Identifier` to identify the app that sent the AppCard, and a string ID to point to the AppCard to which the component is related.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun onProviderRemoved(String, String?)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nThis function is triggered when an AppCard provider has been removed or disabled. Use this method to clean up any active AppCard related to the given package name and provider authority.\u003cbr /\u003e\n\nIf authority is `{@code null}`, then an entire package was removed.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun onProviderAdded(String, String?)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nThis function is triggered when an AppCard provider has been added or enabled.\u003cbr /\u003e\n\n**Sample usage.** Use this function as a trigger to refresh all available\nAppCards in an AppCard picker. If authority is `{@code null}`, then an entire\npackage was added.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun onPackageCommunicationError(appIdentifier, Throwable)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nThis function is triggered when the `AppCardHost` encounters an error when communicating with an AppCard provider.\n\n\u003cbr /\u003e\n\n**Sample usage.** Use this method to show to the user that an AppCard they have\nselected has encountered an error.\n\n\u003cbr /\u003e\n\n### APIs\n\n\u003cbr /\u003e\n\n`fun refreshCompatibleapp()`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nThis method should be called whenever the activity that is using the host is resumed so that the host can refresh its list of apps that support AppCards.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun destroy()`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nCall this method when an activity that is using a host is destroyed so that the host can clean up all connections and internal members.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun registerListener(AppCardListener)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nUsed to register an `AppCardListener`.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun unregisterListener(AppCardListener)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nUsed to unregister an `AppCardListener`.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun getAllAppCards(AppCardContext)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nCall this method to supply a registered `AppCardListener` with all the AppCards provided in the system with a given `AppCardContext` that provides hints to the providers on how to structure their AppCard.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun requestAppCard(AppCardContext, appIdentifier, String)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nCall this method to supply a registered `AppCardListener` with a specific AppCard, given an `AppCardContext` that gives hints to the providers on how to structure their AppCard.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun notifyAppCardRemoved(appIdentifier, String)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nNotify an AppCard provider that its AppCard is no longer active.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun notifyAppCardInteraction(appIdentifier, String, String, String)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nNotify an AppCard provider that its AppCard has been interacted with. The only supported interaction is a button click, which is signified by a `AppCardMessageConstants.InteractionMessageConstants.MSG_INTERACTION_ON_CLICK`.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nWe recommend creating a button for an AppCard with an `onClick` listener that calls this function with `appIdentifier`, AppCard ID, component ID, and interaction ID.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n`fun sendAppCardContextUpdate(AppCardContext, appIdentifier, String)`\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\nSend an `AppCardContext` update for a specific AppCard. For example, when shifting from Park mode to Drive mode, use this method to send an `AppCardContext` update in which `isInteractable` is set to `false` for each active AppCard.\n\n\u003cbr /\u003e\n\nFAQ\n---\n\n1. Where can I find sample implementations?\n\n - [Sample host](https://android.googlesource.com/platform/packages/apps/Car/libs/+/refs/tags/ub-automotive-master-20250418/car-app-card-host-lib/sample-host/). Shows all available AppCards in the system, along with\n testing capabilities.\n\n - DriverUI and [Pano manager](https://cs.android.com/android/platform/superproject/+/android-latest-release:packages/services/Car/car_product/distant_display/apps/CarDistantDisplayPanoManager/;l=1?q=CarDistantDisplayPanoManager&sq=&ss=android%2Fplatform%2Fsuperproject%2Fmain). Pano manager acts as the picker while\n DriverUI acts as the presenter.\n\n2. How many AppCards can each `AppCardContentProvider` support?\n\n An `AppCardContentProvider` can support an infinite number of AppCards.\n However, be sure to balance the number of AppCards with degraded performance\n versus a positive user experience."]]