This section details the different features of the library that you can make use of to implement the functionality of your point of interest (POI) app.
Declare category support in your manifest
Your app needs to declare the androidx.car.app.category.POI
car app category in the intent filter of its
CarAppService
.
<application>
...
<service
...
android:name=".MyCarAppService"
android:exported="true">
<intent-filter>
<action android:name="androidx.car.app.CarAppService" />
<category android:name="androidx.car.app.category.POI"/>
</intent-filter>
</service>
...
<application>
Access the map template
Apps can access the PlaceListMapTemplate
specifically designed for showing a list of points of interest alongside a map
that is rendered by the host.
In order to get access to this template, your app needs to declare the
androidx.car.app.MAP_TEMPLATES
permission in its AndroidManifest.xml
:
<uses-permission android:name="androidx.car.app.MAP_TEMPLATES"/>
Refresh PlaceListMapTemplate content
You can allow drivers to refresh content with the tap of a button while browsing
lists of places built with
PlaceListMapTemplate
.
Implement the
OnContentRefreshListener
interface's onContentRefreshRequested
method and use
PlaceListMapTemplate.Builder.setOnContentRefreshListener
to set the listener on the template to enable list refresh.
The following snippet shows setting the listener on the template:
Kotlin
PlaceListMapTemplate.Builder() ... .setOnContentRefreshListener { // Execute any desired logic ... // Then call invalidate() so onGetTemplate() is called again invalidate() } .build()
Java
new PlaceListMapTemplate.Builder() ... .setOnContentRefreshListener(() -> { // Execute any desired logic ... // Then call invalidate() so onGetTemplate() is called again invalidate(); }) .build();
The refresh button is only shown in the header of the
PlaceListMapTemplate
if the listener has a value.
When the driver clicks the refresh button, the onContentRefreshRequested
method of your
OnContentRefreshListener
implementation is called. Within onContentRefreshRequested
,
call the Screen.invalidate
method. The host subsequently calls back into your app’s
Screen.onGetTemplate
method to retrieve the template with the refreshed content. See Refresh the
contents of a template for more information about
refreshing templates. As long as the next template returned by onGetTemplate
is of the same type, it is
counted as a refresh and is not counted towards the template quota.
Integrate with Google Assistant using App Actions
App Actions let users launch and control Android Apps with their voice, using Google Assistant. You can integrate Assistant with point of interest apps by adding an App Actions capability. Capabilities are an expression of the relevant feature of an app and contain a Built-in intent (BII) and its fulfillment. For example, this enables users to say "Hey Google, find street parking on ExampleApp" and your app can open to the appropriate screen in your app.
Limitations
App Actions have the following limitations:
- Available only for apps that use the Car App Library in the point of interest category.
- Voice support is only for Parking or Charging Built-in intents.
- App Action fulfillment can only be done with deep links.
Integration steps
Add the following
<meta-data>
element in the<application>
element of yourAndroidManifest.xml
file:<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" />
To enable Assistant to link to your app's content with deep links, you need an
<intent-filter>
element in yourAndroidManifest.xml
file.For Android Auto the intent-filter is the same as your mobile app.
For Android Automotive OS fulfillment, App Actions are triggered by
CarAppService
sessions. To allow a session to trigger your deeplink, you must specify an intent filter in the<activity>
element of yourAndroidManifest.xml
file.
<activity ... android:name="androidx.car.app.activity.CarAppActivity"> … <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="YOUR_SCHEME" android:host="YOUR_HOST" /> </intent-filter> </activity>
Create a
shortcuts.xml
file in theres/xml
directory of your app’s project with the appropriate capabilities:<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Your Capability definitions will go here --> </shortcuts>
See the Capability sections below for information about the Parking and Charging capabilities.
Update your app to handle fulfillment for a session.
The following are samples of intent handling for
Session.onCreateScreen
andSession.onNewIntent
onCreateScreen
Kotlin
@Override fun onCreateScreen(@NonNull intent: Intent): Screen { if (intent.getData() != null) { val uri: Uri = intent.getData() // uri = "YOUR_SCHEME://YOUR_HOST?name=Levis%20center" // Build your Templates with parsed uri parameters ... } }
Java
@Override public Screen onCreateScreen(@NonNull Intent intent) { if (intent.getData() != null) { Uri uri = intent.getData(); // uri = "YOUR_SCHEME://YOUR_HOST?name=Levis%20center" // Build your Templates with parsed uri parameters … } }
onNewIntent
Kotlin
@Override fun onNewIntent(@NonNull intent: Intent): Screen { if (intent.getData() != null) { val uri: Uri = intent.getData() // uri = "YOUR_SCHEME://YOUR_HOST?name=Levis%20center" // Build your Templates with parsed uri parameters … } }
Java
@Override public void onNewIntent(@NonNull Intent intent) { if (intent.getData() != null) { Uri uri = intent.getData(); // uri = "YOUR_SCHEME://YOUR_HOST?name=Levis%20center" // Build your Templates with parsed uri parameters … } }
Capabilities
App Actions support the following capabilities:
Parking
Action ID:
actions.intent.GET_PARKING_FACILITY
Description: Get parking facility. May specify a type of parking, app name, and location.
Locale support: en-US
Parameters:
parkingFacility.disambiguatingDescription
- A descriptor for the type of parking, for example "free", "valet", or "street". You can filter for the type of parking facility using this parameter.- The following parameters can help you determine the location of the parking facility requested by the user. If none of these are present, you should return facilities closest to the user's current location.
parkingFacility.name
- A name for the location of the facility, for example "Mountain View"parkingFacility.address
- An address for the location of the facility, for example "123 Easy St, Mountain View, CA"parkingFacility.geo.latitude
- The latitude of the facility, for example "37.3861"parkingFacility.geo.longitude
- The longitude of the facility, for example "-122.084"
Sample
capability
definition:<?xml version="1.0" encoding="utf-8"?> <!-- This is a sample shortcuts.xml --> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability android:name="actions.intent.GET_PARKING_FACILITY"> <intent> <url-template android:value="YOUR_SCHEME://YOUR_HOST{?name,address,disambiguatingDescription,latitude,longitude}"> <!-- Eg. name = "Googleplex" --> <parameter android:name="parkingFacility.name" android:key="name"/> <!-- Eg. address = "1600 Amphitheatre Pkwy, Mountain View, CA 94043" --> <parameter android:name="parkingFacility.address" android:key="address"/> <!-- Eg. disambiguatingDescription = "valet" --> <parameter android:name="parkingFacility.disambiguatingDescription" android:key="disambiguatingDescription"/> <!-- Eg. latitude = "37.3861" --> <parameter android:name="parkingFacility.geo.latitude" android:key="latitude"/> <!-- Eg. longitude = "-122.084" --> <parameter android:name="parkingFacility.geo.longitude" android:key="longitude"/> </intent> </capability> </shortcuts>
Charging
Action ID:
actions.intent.GET_CHARGING_STATION
Description: Get charging station. May specify an app name or location.
Locale support: en-US
Parameters:
chargingStation.disambiguatingDescription
- A descriptor for the type of station, for example "free", "paid". You can filter for the type of charging station using this parameter.- The following parameters can help you determine the location of the charging station requested by the user. If none of these are present, you should return stations closest to the user's current location.
chargingStation.name
- A name for the location of the station, for example "Mountain View"chargingStation.address
- An address for the location of the station, for example "123 Easy St, Mountain View, CA"chargingStation.geo.latitude
- The latitude of the station, for example "37.3861"chargingStation.geo.longitude
- The longitude of the station, for example "-122.084"
Sample
capability
definition:<?xml version="1.0" encoding="utf-8"?> <!-- This is a sample shortcuts.xml --> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <capability android:name="actions.intent.GET_CHARGING_STATION"> <intent> <url-template android:value="YOUR_SCHEME://YOUR_HOST{?name,address,latitude,longitude,type}"> <!-- Eg. name = "Googleplex" --> <parameter android:name="chargingStation.name" android:key="name"/> <!-- Eg. address = "1600 Amphitheatre Pkwy, Mountain View, CA 94043" --> <parameter android:name="chargingStation.address" android:key="address"/> <!-- Eg. latitude = "37.3861" --> <parameter android:name="chargingStation.geo.latitude" android:key="latitude"/> <!-- Eg. longitude = "-122.084" --> <parameter android:name="chargingStation.geo.longitude" android:key="longitude"/> </intent> </capability> </shortcuts>
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 2022-12-09 UTC.
[{ "type": "thumb-down", "id": "missingTheInformationINeed", "label":"Missing the information I need" },{ "type": "thumb-down", "id": "tooComplicatedTooManySteps", "label":"Too complicated / too many steps" },{ "type": "thumb-down", "id": "outOfDate", "label":"Out of date" },{ "type": "thumb-down", "id": "samplesCodeIssue", "label":"Samples / code issue" },{ "type": "thumb-down", "id": "otherDown", "label":"Other" }] [{ "type": "thumb-up", "id": "easyToUnderstand", "label":"Easy to understand" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"Solved my problem" },{ "type": "thumb-up", "id": "otherUp", "label":"Other" }]