Starting March 27, 2025, we recommend using android-latest-release
instead of aosp-main
to build and contribute to AOSP. For more information, see Changes to AOSP.
Configure an AppCard host
Stay organized with collections
Save and categorize content based on your preferences.
Use AppCardHost
to communicate with apps that show AppCards.
Permissions
Any app that uses an AppCardHost
must have the following permissions:
android.permission.INTERACT_ACROSS_USERS_FULL
android.permission.QUERY_ALL_PACKAGES
- (In API level 34 and higher only)
android.car.permission.BIND_APP_CARD_PROVIDER
Initialize
To initialize the host, provide:
- Context
updateRate
AppCard update rate in milliseconds.
fastUpdateRate
Update rate in milliseconds for components tagged with
EnforceFastUpdateRate
responseExecutor
A thread on which you want to receive responses from
AppCard apps.
Design
An AppCardHost
can be interacted with in one of two ways:
OR,
AppCardListener
The AppCardListener
component registers itself with an AppCardHost
to receive communication updates from the AppCardHost
and AppCard apps.
The interface functions of an AppCardListener
are detailed here.
fun onAppCardReceived(AppCardContainer)
This 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
fun onComponentReceived(AppCardComponentContainer)
This 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.
fun onProviderRemoved(String, String?)
This 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.
If authority is {@code null}
, then an entire package was removed.
fun onProviderAdded(String, String?)
This function is triggered when an AppCard provider has been added or
enabled.
Sample usage. Use this function as a trigger to refresh all available
AppCards in an AppCard picker. If authority is {@code null}
, then an entire
package was added.
fun onPackageCommunicationError(appIdentifier, Throwable)
This function is triggered when the AppCardHost
encounters an error when
communicating with an AppCard provider.
Sample usage. Use this method to show to the user that an AppCard they have
selected has encountered an error.
APIs
fun refreshCompatibleapp()
This 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.
fun destroy()
Call this method when an activity that is using a host is destroyed
so that the host can clean up all connections and internal members.
fun registerListener(AppCardListener)
Used to register an AppCardListener
.
fun unregisterListener(AppCardListener)
Used to unregister an AppCardListener
.
fun getAllAppCards(AppCardContext)
Call 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.
fun requestAppCard(AppCardContext, appIdentifier, String)
Call 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.
fun notifyAppCardRemoved(appIdentifier, String)
Notify an AppCard provider that its AppCard is no longer active.
fun notifyAppCardInteraction(appIdentifier, String, String, String)
Notify 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
.
We recommend creating a button for an AppCard with an onClick
listener
that calls this function with appIdentifier
, AppCard ID, component
ID, and interaction ID.
fun sendAppCardContextUpdate(AppCardContext, appIdentifier, String)
Send 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.
FAQ
Where can I find sample implementations?
Sample host. Shows all available AppCards in the system, along with
testing capabilities.
DriverUI and Pano manager. Pano manager acts as the picker while
DriverUI acts as the presenter.
How many AppCards can each AppCardContentProvider
support?
An AppCardContentProvider
can support an infinite number of AppCards.
However, be sure to balance the number of AppCards with degraded performance
versus a positive user experience.
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2025-06-26 UTC.
[null,null,["Last updated 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."]]