Extend an Android app to Google Assistant with App Actions

1. Overview

App Actions help you expand the reach of your Android app by letting users launch directly into specific app features from Google Assistant. App Actions build on top of your app's deep links, giving users more ways to access the features they already want to use.

As an Android developer, you can implement one of the available built-in intents to help users get things done faster and more smoothly.

This codelab covers intermediate-level concepts for developing with Actions on Google. You should have prior experience with developing Android apps and handling deep links to follow this codelab. Developers entirely new to Android may instead want to get started with one of the codelabs for Android developer fundamentals.

What you'll build

In this codelab, you'll add these features to a sample fitness Android app:

  • Users can start an exercise timer in the app using Google Assistant.
  • Users can stop the exercise timer in the app using Google Assistant.

Four progressive screens where the Google Assistant starts a run tracker in an app.

What you'll learn

  • How to know if App Actions are right for your Android app.
  • How to connect a built-in intent with an Android activity.
  • How to get deep link URL parameters for an Android app from the Assistant.
  • How to use inline inventory to map identifiers to app functionality
  • How to test App Actions in Android Studio.

What you'll need

Before continuing, make sure you have the following tools in your environment:

  • A terminal to run shell commands with git installed.
  • The latest version of Android Studio.
  • A Google account with access to the Google Play Console.
  • A physical Android device on which to test your App Actions.

Familiarity with Kotlin and XML are recommended, although not required, to understand the code used in this codelab.

The App Actions in this codelab will only trigger successfully for Google Assistant languages in the following locales: en-US, en-GB, en-CA, en-IN, en-BE, en-SG, and en-AU. Other languages and locales are not available for the built-in intents used by the Android app in this codelab.

In this codelab, you'll use an Android device to test App Actions. Before testing on a physical Android device, make sure it's connected to your local development machine. You must be signed in to the Google app on the device and signed in to Android Studio using the same Google account.

2. Understand how it works

App Actions connect users from Google Assistant to your Android app. But how do they work?

When a user indicates to Assistant that they want to use your app, Assistant looks for App Actions registered to your app from an actions.xml file. App Actions are described in this file by using a combination of built-in intents (which semantically describe an app capability) and fulfillment instructions (like a deep link template).

An actions.xml file contains the following information for each App Action:

  • What built-in intent the App Action uses.
  • How the App Action can be fulfilled (for example, via deep link).
  • How parameters for the intent map to information provided to Assistant by the user.

Based on information given to Google Assistant by the user, App Actions creates a deep link to fulfill the intent. Your Android activity then filters for and handles the provided deep link to provide the user with their desired functionality.

Altogether, the result becomes a user experience where Assistant invokes your app functionality in response to a user's query.

3. Set up for local development

The starting point for this codelab is a sample fitness app for Android. In the app, users can start and stop exercise timers, as well as view information about their exercise routines.

Download your base files

To get the base files for this codelab, run the following command to clone the GitHub repository:

git clone --branch codelab-start https://github.com/actions-on-google/appactions-fitness-kotlin.git

Using the --branch codelab-start option checks out the branch where this codelab starts.

Once you've cloned the repository, open it in Android Studio:

  1. In the Welcome to Android Studio dialog, click Open an existing Android Studio project (if you already have a project open, close it first).
  2. To start working on the fitness app, find and select the folder where you cloned the repository.

Change Android application ID

As you implement App Actions for the fitness app, you'll be tasked with testing inputs using an Android Studio plugin. You'll install this plugin later in the codelab, but you won't be able to use the test tool until your app is uploaded to a project in the Google Play Console.

To make your version of the sample fitness app unique in the console, change the application ID listed in the default Android configs of your app/build.gradle file:


android {
    defaultConfig {
        applicationId "com.MYUNIQUENAME.android.fitactions"

Replace "MYUNIQUENAME" in the applicationId with something unique to you. Doing so changes the package name and prevents a later "Duplicate package name" issue when uploading to the Play Console.

Try out the app

Before making any other changes to the app, it may be helpful to get an idea of what the sample app can do. Try running the app on an emulator:

  1. In Android Studio, select Run > Run app or click Runacabcb8f8634af20.png in the toolbar.
  2. In the Select Deployment Target dialog, select a virtual device and click OK. The recommended OS version is Android 8 (API level 26) or higher, although Actions run on devices back to Android 5 (API level 21).

The emulator starts and boots just like a physical device, so it may take a while depending on the speed of your computer. Once your app builds and the emulator is ready, Android Studio uploads the app to the emulator and runs it.

Phone with the Fit Actions app open, showing exercise statistics.

Briefly explore the app to see what it can do. Tapping the Run icon starts an exercise timer, and tapping the X icon then stops the timer. These are the two tasks you'll enable with App Actions.

Repeat the above steps on your test device to confirm that the app functions the same way on both surfaces. Before continuing, set up and verify that Assistant is working on your physical device by long-pressing on the Home button. You'll need to sign in to Assistant on your test device if you haven't already.

Upload to Play Console

Build your app in Android Studio and upload it to the Play Console as an internal release. Uploading the app is a prerequisite for using the App Actions test tool in Android Studio.

In Android Studio, do the following steps:

  1. Go to Build > Generate Signed Bundle / APK.
  2. Select "Android App Bundle" and click Next.
  3. Enter details to digitally sign your app and click Next.
  4. Select the "release" build variant and click Finish.

In the Google Play Console, upload the app bundle you just created as a new app:

  1. On the All apps page, click Create app.
  2. Give the app any name you want and click Create app. For this codelab, you won't need to fill out any of the app information once the app is created.
  3. From the sidebar menu, go to Release and find the Internal testing page.
  4. Click Create new release on the Internal testing page.
  5. In the App bundles and APKs panel, upload the AAB file you generated earlier (it's likely in the app/release directory).
  6. Click Save.

Now that you've successfully uploaded your app to the Play Console, it's time to go back to Android Studio.

Install test plugin

Google Assistant needs to be aware of App Actions registered to your app, so you need to communicate that information somehow. During development, you do that using the "App Actions test tool" Android Studio plugin.

If you don't already have the plugin, install it:

  1. Go to File > Settings (Android Studio > Preferences on MacOS).
  2. In the Plugins section, go to Marketplace and search for "App Actions test tool".
  3. Install the tool and restart Android Studio.

4. Identify App Actions and prepare deep links

To set up an App Action, you need to find a built-in intent that maps to a function performed by your Android app. The built-in intents reference page lists the built-in intents available for Google Assistant, each of which models a common way users express tasks they're trying to do.

In the reference, built-in intents that can be fulfilled by App Actions are grouped by category and functionality.

For this codelab, you're implementing two built-in intents to help out your user:

This process involves setting up a deep link, defining the App Action in the app's XML resources, then connecting the two.

Deep links take users directly to content, passing information from the intent to the app in the process. By default, the Assistant uses deep links to fulfill the intent and pass parameters to the app. For this codelab, incoming deep links use the "fit-actions.firebaseapp.com" host and "https" scheme.

In the Android manifest file, add an intent filter for the main activity to define the supported deep links:


<activity android:name="com.devrel.android.fitactions.FitMainActivity" ...>
    ... // Other intent filters

    <!-- Define your supported deeplinks -->

        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

            android:scheme="https" />

Now in the main activity, add the following function to define the behavior for an incoming deep link:


private fun handleDeepLink(data: Uri?) {
    when (data?.path) {
        DeepLink.START -> {
            // Get the parameter defined as "exerciseType" and add it to the fragment arguments
            val exerciseType = data.getQueryParameter(DeepLink.Params.ACTIVITY_TYPE).orEmpty()
            val type = FitActivity.Type.find(exerciseType)
            val arguments = Bundle().apply {
                putSerializable(FitTrackingFragment.PARAM_TYPE, type)

            updateView(FitTrackingFragment::class.java, arguments)
        DeepLink.STOP -> {
            // Stop the tracking service if any and return to home screen.
            stopService(Intent(this, FitTrackingService::class.java))
        else -> {
            // Path is not supported or invalid, start normal flow.

DeepLink.START and DeepLink.STOP are defined as constants in the sample app, and they map to the corresponding paths of an incoming deep link. In the DeepLink.START case, the handler also gets arguments that come in via deep link URL parameters.

Now, update the handleIntent function of the same file to use the deep link handler:


private fun Intent.handleIntent() {
    when (action) {
        // When the action is triggered by a deep-link, Intent.ACTION_VIEW will be used
        Intent.ACTION_VIEW -> handleDeepLink(data)
        // Otherwise start the app as you would normally do.
        else -> showDefaultView()

Now when the app filters an intent of the format "https://fit-actions.firebaseapp.com/start", it starts an exercise timer.

If you're familiar with the Android Debug Bridge (adb), you can test the deep link handler on a running device. To do so, update the app on your device and use the following shell command:

adb shell am start -a android.intent.action.VIEW -d "https://fit-actions.firebaseapp.com/start"

5. Define App Actions

For App Actions to work, Google Assistant needs to know which App Actions are registered to your app. You communicate this information by uploading an actions.xml file to the Play Console as part of your Android package.

It only takes a few steps to create the new resource and reference it:

  1. Create actions.xml to establish which built-in intents to connect and what parameters are needed.
  2. Map built-in intent parameters to deep link parameters in your activities.
  3. Add a reference to your actions.xml file in AndroidManifest.xml.

Create actions.xml

To describe the App Actions supported by the app, you create a new XML file named actions.xml in app/src/main/res/xml.

In Android Studio, do the following steps:

  1. Go to File > New > XML > App Actions XML File.
  2. Enter "actions" as the Actions File Name.
  3. Click Finish to both create the new actions.xml file and add a reference to it in your AndroidManifest.xml.

Once the new file is created, replace the contents of actions.xml with the following code:


<?xml version="1.0" encoding="utf-8"?>

    <action intentName="actions.intent.START_EXERCISE">
        <fulfillment urlTemplate="https://fit-actions.firebaseapp.com/start{?exerciseType}">
                urlParameter="exerciseType" />

    <action intentName="actions.intent.STOP_EXERCISE">
        <fulfillment urlTemplate="https://fit-actions.firebaseapp.com/stop" />

In the above code, you use elements to define App Actions for starting and stopping an exercise timer in the app. The intentName attributes correspond to the two built-in intents you're fulfilling using App Actions, and the elements tell Assistant how to use your app to achieve the action.

Here, both actions are fulfilled by constructing deep links using the urlTemplate attribute. The URL templates use the host and scheme you defined for deep links in your AndroidManifest.xml file. The paths in each URL template correspond to what the handleDeepLink function (added earlier to the main activity) expects.

Note that for starting the timer, you also map the exercise.name parameter from the built-in intent to the exerciseType URL parameter. This allows your deep link handler to get arguments for its business logic from Assistant.

Confirm that your Android manifest references actions.xml

In the previous step, Android Studio added a reference to your actions.xml file in AndroidManifest.xml. Verify this by checking for the following element in the Android manifest:



        android:resource="@xml/actions" />

If you see the above <meta-data> element in your manifest file, move on to testing your App Action.

If you don't see the above <meta-data> element in your manifest file, add it.

Test App Actions

It's time to try out your App Actions on your test device!

Connect your test device and use the test tool to test the App Action:

  1. Go to Tools > App Actions > App Actions Test Tool. You may be asked to sign in to Android Studio. Use the same account used earlier with the Google Play Console.
  2. In the Invocation Name field, enter "Fit Actions".
  3. If the language of your Assistant is not "English (US)", enter the locale that matches the language of your Assistant in the Locale field.
  4. Click Create Preview.
  5. Using the Configure drop-down list, select the built-in intent you want to test.
  6. Click Run. If given the option to open with Google, select "Always" to allow Assistant to open supported links (you can change this later in your app settings).

When the App Actions test tool creates or updates a preview of your App Actions, it does so for a single Google account, temporarily registering your defined App Actions. That preview enables Assistant to recognize your App Actions before deploying the production version of your app to the Google Play Console.

Once the test tool fetches the built-in intents for your app, you can directly provide the intents with parameter values and trigger the App Action from Android Studio!

As an alternative, you can use the invocation name directly in the Assistant app on your device to try out your App Action. For example, you could say "Hey Google, start running in Fit Actions" to launch the App Action that starts an exercise timer.

6. Support specific wordings

You can now start and stop exercise timers in your fitness app via Google Assistant, but you may have noticed that only certain exercises are recognized. Requests like "Start my swim in Fit Actions" or "Start hiking in Fit Actions" lead to a timer that starts with the text "Start unknown in...".

That's because the only exercise types currently supported by the sample app are "Running", "Cycling", and "Walking." How can you better accommodate users who want to use the app to track other exercises?

For this app, you can increase the number of available exercises in a couple of ways:

  • Add app support for more exercise types like swimming and climbing (limited by the supported text field values for the actions.intent.START_EXERCISE built-in intent)
  • Map another supported exercise type, like "hiking", to one that's supported in the app like "walking"

If you add support for more exercise types, then you can connect to more pathways in your app based on the exercise a user wants to do. That's one way to help users, and it's the correct choice if your app can perform different tasks for different exercises.

For the fitness app, you can take the second option to make Google Assistant immediately more accommodating. Once you do, users will be able to start a timer using queries containing another supported text field value. In this codelab, you'll use inline inventory to map "Start hiking" to the app functionality for "Start walking".

Inline inventory

Inline inventory defines specific entities your app expects users to include when triggering App Actions with Assistant. You add inline inventory in your actions.xml file to directly create a listing of supported options for users. Inventory items are grouped in an <entity-set> element, and action definitions can reference entity sets to use them for mapping parameters.

As mentioned earlier, the sample app has functionality to support "Running", "Cycling", and "Walking". Create an entity set and reference it in actions.intent.START_EXERCISE so your app only needs to use entity identifiers for deep linking:


    <action intentName="actions.intent.START_EXERCISE">

        <!-- Map a parameter to an entity set reference -->
        <parameter name="exercise.name">
            <entity-set-reference entitySetId="ExerciseEntitySet" />

    <!-- Define an inline inventory -->
    <!-- This sample maps supported entities with the class FitActivity.Type -->
    <entity-set entitySetId="ExerciseEntitySet">
            identifier="RUNNING" />
            identifier="WALKING" />
            identifier="WALKING" />
            identifier="CYCLING" />

Each <entity> element in the inline inventory represents a unique match for the user's query. Entities allow Assistant to distinguish between supported inputs like running, walking, and cycling. They're especially useful when you want Assistant to recognize certain information that's specific to your app, like menu items or services.

By adding an entity for the "hiking" string, you allow hikers to take advantage of functionality you already built for walking!

Test your inventory

In the test tool, creating or updating a preview fetches the registered built-in intents for your app. You can then directly provide the intents with parameter values and trigger the App Action from Android Studio.

Try out your inventory in the App Actions test tool:

  1. Click Update Preview.
  2. From the Configure drop-down list, select "actions.intent.START_EXERCISE".
  3. Type "hiking" into the exercise.name field.
  4. Select your device from the Select Target Device drop-down list.
  5. Click Run.

The App Actions test tool uses the input "hiking" to start an exercise timer for walking (on a test device).

7. Next steps


You've now covered the skills necessary to add App Actions to an Android app.

What we've covered

  • How to identify Android activities that have a corresponding built-in intent users can trigger via App Actions.
  • How to pass parameters from a built-in intent to an Android app.
  • How to use inline inventory to map supported values to app functionality identifiers.
  • How to test App Actions in Android Studio.

What's next

From here, you can try making further refinements to your fitness app. To give you some inspiration, we've provided an extended version of the app in the master branch of the repo on GitHub. The extended version uses Android Slices to additionally present exercise information through Assistant. It also incorporates the App Action deployment requirements for production Android apps.

To learn more about Actions on Google, explore these resources:

Follow us on Twitter @ActionsOnGoogle to stay tuned to our latest announcements, and tweet to #AoGDevs to share what you have built!

Feedback survey

Before you go, please fill out this form to help us improve the codelab. Let us know if you encountered any issues, needed more information to complete steps, or even if everything just went smoothly!