Added in [API level 36](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

# android.app.appfunctions

*** ** * ** ***

Android App Functions provides APIs for applications to expose functionality to the system for cross-app orchestration, and for system-privileged agents to discover and execute this functionality.

Most developers should implement app functions through the [AppFunctions
Jetpack SDK](https://developer.android.com/reference/androidx/appfunctions/package-summary). The Jetpack SDK offers a more convenient and type-safe way to build app
functions.

App Functions is currently a beta/experimental preview feature.

### What are App Functions?

An app function is a discrete piece of functionality within an application that is made
available for execution by trusted, system-privileged applications (referred to as "agents").
This allows agents to orchestrate complex workflows across multiple applications. For example, an
agent could execute a "createNote" function in a note-taking app or a "playSong" function in a
music app.

The App Functions framework interacts with two main players:

- **The App:** Any application that exposes one or more app functions.
- **The Agent:** A trusted application that discovers and executes app functions from other apps.

All interactions with the App Functions system start with `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager` and
`https://developer.android.com/reference/android/app/appfunctions/AppFunctionService`.

### The App: Providing Functions

An app can provide functions in two ways: through a dedicated service or by registering them
at runtime. In both cases, functions must first be declared in an XML asset file.

#### Declaring Function Metadata

All app functions, regardless of implementation, must be declared in an XML asset file. This
file defines the `https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata` for each function.

**Example XML declaration (e.g., `assets/note_app_functions.xml`):**

    <appfunctions>
        <appfunction>
            <id>createNote</id>
            <enabledByDefault>true</enabledByDefault>
            <parameters>...</parameters>
            <returnType>...</returnType>
            ...
        </appfunction>
    </appfunctions>

#### Functions implemented using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionService`

This approach is suitable for functionality that is always available regardless of a
component's lifecycle. The system will wake up your app to execute the function when executed by
an agent.

- Declare the function metadata in an XML asset file, as described above.
- Implement a class that extends `https://developer.android.com/reference/android/app/appfunctions/AppFunctionService`.
- Override the `https://developer.android.com/reference/android/app/appfunctions/AppFunctionService#onExecuteFunction(android.app.appfunctions.ExecuteAppFunctionRequest,%20java.lang.String,%20android.content.pm.SigningInfo,%20android.os.CancellationSignal,%20android.os.OutcomeReceiver<android.app.appfunctions.ExecuteAppFunctionResponse,android.app.appfunctions.AppFunctionException>)` method to provide the execution logic.
- Declare the service in your `AndroidManifest.xml`, requiring the `https://developer.android.com/reference/android/Manifest.permission#BIND_APP_FUNCTION_SERVICE` permission, and include an intent filter for the `https://developer.android.com/reference/android/app/appfunctions/AppFunctionService#SERVICE_INTERFACE` action.
- Reference the metadata XML file from the service declaration using a `<property>` tag named `"android.app.appfunctions"`.

**Example `AndroidManifest.xml`:**

    <service
        android:name=".NoteAppFunctionService"
        android:permission="android.permission.BIND_APP_FUNCTION_SERVICE"
        android:exported="true">
      <property
          android:name="android.app.appfunctions"
          android:value="note_app_functions.xml" />
      <intent-filter>
        <action android:name="android.app.appfunctions.AppFunctionService" />
      </intent-filter>
    </service>

**Important:** Only one `https://developer.android.com/reference/android/app/appfunctions/AppFunctionService` implementation can be active in an app
at a time.

**Example implementation:**

```
class NoteAppFunctionService : AppFunctionService() {
    override fun onExecuteFunction(
        request: ExecuteAppFunctionRequest,
        callingPackage: String,
        callingPackageSigningInfo: SigningInfo,
        cancellationSignal: CancellationSignal,
        callback: OutcomeReceiver<ExecuteAppFunctionResponse, AppFunctionException>
    ) {
        when (request.functionIdentifier) {
            "createNote" -> {
                // Implement createNote functionality.
                callback.onResult(ExecuteAppFunctionResponse(...))
            }
            else -> {
                // Should never happen, the system will automatically return FUNCTION_NOT_FOUND.
                callback.onError(
                    AppFunctionException(
                        AppFunctionException.FUNCTION_NOT_FOUND,
                        "Unknown function: ${request.functionIdentifier}"
                    )
                )
            }
        }
    }
}
```

**Important:** It is strongly recommended that you do not alter your function\\u2019s behavior
based on the `callingPackage` or `callingPackageSigningInfo`. Your function should
behave consistently for all callers to ensure a predictable experience. Starting in `https://developer.android.com/reference/android/os/Build.VERSION_CODES#CINNAMON_BUN`, the value of `callingPackage` will always be
an empty string and `callingPackageSigningInfo` will always be an unknown signing info.

#### Functions implemented using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#registerAppFunction(java.lang.String,%20java.util.concurrent.Executor,%20android.app.appfunctions.AppFunction)`

Starting in Android `https://developer.android.com/reference/android/os/Build.VERSION_CODES#CINNAMON_BUN`, this approach is
suitable for functionality that is only available when the app is in a certain runtime state,
such as functionality tied to a specific `https://developer.android.com/reference/android/app/Activity`.

- Declare the function metadata in an XML asset file, as described above. Add a `<scope>activity|global</scope>` tag to each `<appfunction>` to define its scope. See [Function Scopes](https://developer.android.com/reference/android/app/appfunctions/package-summary#function-scopes) below for details.
- Implement the `https://developer.android.com/reference/android/app/appfunctions/AppFunction` interface to define the execution logic.
- At runtime (e.g., in `https://developer.android.com/reference/android/app/Activity#onStart()`), register your `https://developer.android.com/reference/android/app/appfunctions/AppFunction` implementation using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#registerAppFunction(java.lang.String,%20java.util.concurrent.Executor,%20android.app.appfunctions.AppFunction)`.
- Keep the returned `https://developer.android.com/reference/android/app/appfunctions/AppFunctionRegistration` object and call `https://developer.android.com/reference/android/app/appfunctions/AppFunctionRegistration#unregister()` when the function is no longer relevant (e.g., in `https://developer.android.com/reference/android/app/Activity#onStop()` or before `https://developer.android.com/reference/android/app/Service#stopForeground(boolean)`).

**Example `AndroidManifest.xml`:**

    <application ...>
      <property
          android:name="android.app.appfunctions"
          android:value="note_runtime_app_functions.xml" />
      ...
    </application>

**Example implementation:**

```
class NoteActivity : Activity() {
    private lateinit var appFunctionRegistration: AppFunctionRegistration

    override fun onStart() {
        super.onStart()
        val appFunctionManager = getSystemService<AppFunctionManager>()
        appFunctionRegistration =
            appFunctionManager.registerAppFunction(
                "getActiveNoteContent",
                mainExecutor,
                object : AppFunction {
                    override fun onExecuteAppFunction(
                        request: ExecuteAppFunctionRequest,
                        cancellationSignal: CancellationSignal,
                        callback:
                            OutcomeReceiver<ExecuteAppFunctionResponse, AppFunctionException>
                    ) {
                        // Implement getActiveNoteContent functionality.
                        callback.onResult(ExecuteAppFunctionResponse(...))
                    }
                })
    }

    override fun onStop() {
        appFunctionRegistration.unregister()
        super.onStop()
    }
}
```

#### Function Scopes

Functions implemented using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#registerAppFunction(java.lang.String,%20java.util.concurrent.Executor,%20android.app.appfunctions.AppFunction)` can have different
scopes, defined in their XML metadata:

- `https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata#SCOPE_ACTIVITY`: The function is tied to a specific `https://developer.android.com/reference/android/app/Activity` instance. Multiple activities can register their own version of the same function simultaneously. Agents can differentiate between them using the `https://developer.android.com/reference/android/app/appfunctions/AppFunctionActivityId`.
- `https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata#SCOPE_GLOBAL`: Only one implementation of the function can be registered at a time for the entire application. This is useful for functions that are tied to a singleton component, such as a foreground service.

Functions implemented using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionService` are always considered `https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata#SCOPE_GLOBAL`.

**IMPORTANT:** Functions provided with `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#registerAppFunction(java.lang.String,%20java.util.concurrent.Executor,%20android.app.appfunctions.AppFunction)`
called from an `https://developer.android.com/reference/android/app/Activity` context should prefer `https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata#SCOPE_ACTIVITY`. Only use `https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata#SCOPE_GLOBAL` for such
functions if you are absolutely sure there can be only one instance of that activity.

### The Agent: Discovering and Executing Functions

An agent's lifecycle with an app function typically involves three steps: discovery, state
retrieval, and execution.

#### 1. Discovering App Functions

Agents can find available functions using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#searchAppFunctions(android.app.appfunctions.AppFunctionSearchSpec,%20java.util.concurrent.Executor,%20android.os.OutcomeReceiver<java.util.List<android.app.appfunctions.AppFunctionMetadata>,java.lang.Exception>)`. This
method returns the `https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata` for functions that match the given `https://developer.android.com/reference/android/app/appfunctions/AppFunctionSearchSpec`. This metadata contains essential, non-changing information about a
function, such as its unique `https://developer.android.com/reference/android/app/appfunctions/AppFunctionName` and its execution scope.

#### 2. Retrieving Runtime State

While `https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata` is static, a function's state can change at runtime. For
example, a function might be temporarily disabled by the app, or might be registered at runtime
from one or more `https://developer.android.com/reference/android/app/Activity`s. Agents can query the current `https://developer.android.com/reference/android/app/appfunctions/AppFunctionState` using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#getAppFunctionStates(java.util.List<android.app.appfunctions.AppFunctionName>,%20java.util.concurrent.Executor,%20android.os.OutcomeReceiver<java.util.List<android.app.appfunctions.AppFunctionState>,java.lang.Exception>)`. This state indicates
whether the function is currently enabled and, for functions of `https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata#SCOPE_ACTIVITY`, which `https://developer.android.com/reference/android/app/appfunctions/AppFunctionActivityId` instances have
registered it.

Agents can also use `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#getAppFunctionActivityStates(java.util.Set<android.app.appfunctions.AppFunctionActivityId>,%20java.util.concurrent.Executor,%20android.os.OutcomeReceiver<java.util.List<android.app.appfunctions.AppFunctionActivityState>,java.lang.Exception>)` to get the list of
`https://developer.android.com/reference/android/app/appfunctions/AppFunctionName`s currently associated with a known `https://developer.android.com/reference/android/app/appfunctions/AppFunctionActivityId`. This is
useful for example for agents coming from a `https://developer.android.com/reference/android/service/voice/VoiceInteractionSession`, which they can convert to an `https://developer.android.com/reference/android/app/appfunctions/AppFunctionActivityId` using `https://developer.android.com/reference/android/service/voice/VoiceInteractionSession#getAppFunctionActivityId(android.service.voice.VoiceInteractionSession.ActivityId)`.

To keep both `https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata` and `https://developer.android.com/reference/android/app/appfunctions/AppFunctionState` up-to-date during an
agentic runtime session, agents can use `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#observeAppFunctions(java.util.concurrent.Executor,%20android.app.appfunctions.AppFunctionObserver)` to be
notified of changes to function metadata and state.

#### 3. Executing App Functions

Once an agent has the necessary metadata and confirms the function is enabled, it can execute
the function using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#executeAppFunction(android.app.AppInteractionSession,%20android.app.appfunctions.ExecuteAppFunctionRequest,%20java.util.concurrent.Executor,%20android.os.CancellationSignal,%20android.os.OutcomeReceiver<android.app.appfunctions.ExecuteAppFunctionResponse,android.app.appfunctions.AppFunctionException>)`. The agent must construct an
`https://developer.android.com/reference/android/app/appfunctions/ExecuteAppFunctionRequest`, which specifies the target function and any required
parameters.

The execution can result in a successful `https://developer.android.com/reference/android/app/appfunctions/ExecuteAppFunctionResponse` or an `https://developer.android.com/reference/android/app/appfunctions/AppFunctionException` if an error occurs.


## Interfaces

|---|---|
| [AppFunction](https://developer.android.com/reference/android/app/appfunctions/AppFunction) | An interface for implementing the logic of an app function registered at runtime using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#registerAppFunction(java.lang.String,%20java.util.concurrent.Executor,%20android.app.appfunctions.AppFunction)`. |
| [AppFunctionObservation](https://developer.android.com/reference/android/app/appfunctions/AppFunctionObservation) | Result of `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#observeAppFunctions(java.util.concurrent.Executor,%20android.app.appfunctions.AppFunctionObserver)`. |
| [AppFunctionObserver](https://developer.android.com/reference/android/app/appfunctions/AppFunctionObserver) | Interface for observing changes to app functions provided to `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#observeAppFunctions(java.util.concurrent.Executor,%20android.app.appfunctions.AppFunctionObserver)`. |
| [AppFunctionRegistration](https://developer.android.com/reference/android/app/appfunctions/AppFunctionRegistration) | Result of `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#registerAppFunction(java.lang.String,%20java.util.concurrent.Executor,%20android.app.appfunctions.AppFunction)`. |

## Classes

|---|---|
| [AppFunctionActivityId](https://developer.android.com/reference/android/app/appfunctions/AppFunctionActivityId) | An identifier of an `https://developer.android.com/reference/android/app/Activity` an app function can be associated with. |
| [AppFunctionActivityState](https://developer.android.com/reference/android/app/appfunctions/AppFunctionActivityState) | The state of an activity from the perspective of app functions, retrieved using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#getAppFunctionActivityStates(java.util.Set<android.app.appfunctions.AppFunctionActivityId>,%20java.util.concurrent.Executor,%20android.os.OutcomeReceiver<java.util.List<android.app.appfunctions.AppFunctionActivityState>,java.lang.Exception>)`. |
| [AppFunctionManager](https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager) | Provides access to App Functions. |
| [AppFunctionMetadata](https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata) | Contains an app function's metadata, essential for its invocation and discovery, retrieved using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#searchAppFunctions(android.app.appfunctions.AppFunctionSearchSpec,%20java.util.concurrent.Executor,%20android.os.OutcomeReceiver<java.util.List<android.app.appfunctions.AppFunctionMetadata>,java.lang.Exception>)`. |
| [AppFunctionName](https://developer.android.com/reference/android/app/appfunctions/AppFunctionName) | Globally unique identifier for an app function. |
| [AppFunctionPackageMetadata](https://developer.android.com/reference/android/app/appfunctions/AppFunctionPackageMetadata) | Contains metadata about a package providing app functions. |
| [AppFunctionSchemaMetadata](https://developer.android.com/reference/android/app/appfunctions/AppFunctionSchemaMetadata) | Contains identifying metadata for a predefined schema, which can describe well-known function signatures. |
| [AppFunctionSearchSpec](https://developer.android.com/reference/android/app/appfunctions/AppFunctionSearchSpec) | Filter criteria for `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#searchAppFunctions(android.app.appfunctions.AppFunctionSearchSpec,%20java.util.concurrent.Executor,%20android.os.OutcomeReceiver<java.util.List<android.app.appfunctions.AppFunctionMetadata>,java.lang.Exception>)`. |
| [AppFunctionSearchSpec.Builder](https://developer.android.com/reference/android/app/appfunctions/AppFunctionSearchSpec.Builder) | Builder for constructing `https://developer.android.com/reference/android/app/appfunctions/AppFunctionSearchSpec`. |
| [AppFunctionService](https://developer.android.com/reference/android/app/appfunctions/AppFunctionService) | Extend this class to implement app functions, that can be executed by `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#executeAppFunction(android.app.AppInteractionSession,%20android.app.appfunctions.ExecuteAppFunctionRequest,%20java.util.concurrent.Executor,%20android.os.CancellationSignal,%20android.os.OutcomeReceiver<android.app.appfunctions.ExecuteAppFunctionResponse,android.app.appfunctions.AppFunctionException>)`. |
| [AppFunctionState](https://developer.android.com/reference/android/app/appfunctions/AppFunctionState) | Runtime state of an app function, retrieved using `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#getAppFunctionStates(java.util.List<android.app.appfunctions.AppFunctionName>,%20java.util.concurrent.Executor,%20android.os.OutcomeReceiver<java.util.List<android.app.appfunctions.AppFunctionState>,java.lang.Exception>)`. |
| [AppFunctionUriGrant](https://developer.android.com/reference/android/app/appfunctions/AppFunctionUriGrant) | `https://developer.android.com/reference/android/net/Uri` for which access permission is to be granted to the caller of `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#executeAppFunction(android.app.AppInteractionSession,%20android.app.appfunctions.ExecuteAppFunctionRequest,%20java.util.concurrent.Executor,%20android.os.CancellationSignal,%20android.os.OutcomeReceiver<android.app.appfunctions.ExecuteAppFunctionResponse,android.app.appfunctions.AppFunctionException>)`, provided to `https://developer.android.com/reference/android/app/appfunctions/ExecuteAppFunctionResponse`. |
| [ExecuteAppFunctionRequest](https://developer.android.com/reference/android/app/appfunctions/ExecuteAppFunctionRequest) | A request to execute an app function, provided to `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#executeAppFunction(android.app.AppInteractionSession,%20android.app.appfunctions.ExecuteAppFunctionRequest,%20java.util.concurrent.Executor,%20android.os.CancellationSignal,%20android.os.OutcomeReceiver<android.app.appfunctions.ExecuteAppFunctionResponse,android.app.appfunctions.AppFunctionException>)`. |
| [ExecuteAppFunctionRequest.Builder](https://developer.android.com/reference/android/app/appfunctions/ExecuteAppFunctionRequest.Builder) | Builder for `https://developer.android.com/reference/android/app/appfunctions/ExecuteAppFunctionRequest`. |
| [ExecuteAppFunctionResponse](https://developer.android.com/reference/android/app/appfunctions/ExecuteAppFunctionResponse) | The response to an app function execution, returned by `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#executeAppFunction(android.app.AppInteractionSession,%20android.app.appfunctions.ExecuteAppFunctionRequest,%20java.util.concurrent.Executor,%20android.os.CancellationSignal,%20android.os.OutcomeReceiver<android.app.appfunctions.ExecuteAppFunctionResponse,android.app.appfunctions.AppFunctionException>)`. |
| [RegisterAppFunctionRequest](https://developer.android.com/reference/android/app/appfunctions/RegisterAppFunctionRequest) | A request to register an `https://developer.android.com/reference/android/app/appfunctions/AppFunction` implementation, provided to `https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager#registerAppFunctions(java.util.List<android.app.appfunctions.RegisterAppFunctionRequest>)`. |

## Exceptions

|---|---|
| [AppFunctionException](https://developer.android.com/reference/android/app/appfunctions/AppFunctionException) | App function related error. |

-

  ## Interfaces

  - [AppFunction](https://developer.android.com/reference/android/app/appfunctions/AppFunction)
  - [AppFunctionObservation](https://developer.android.com/reference/android/app/appfunctions/AppFunctionObservation)
  - [AppFunctionObserver](https://developer.android.com/reference/android/app/appfunctions/AppFunctionObserver)
  - [AppFunctionRegistration](https://developer.android.com/reference/android/app/appfunctions/AppFunctionRegistration)
-

  ## Classes

  - [AppFunctionActivityId](https://developer.android.com/reference/android/app/appfunctions/AppFunctionActivityId)
  - [AppFunctionActivityState](https://developer.android.com/reference/android/app/appfunctions/AppFunctionActivityState)
  - [AppFunctionManager](https://developer.android.com/reference/android/app/appfunctions/AppFunctionManager)
  - [AppFunctionMetadata](https://developer.android.com/reference/android/app/appfunctions/AppFunctionMetadata)
  - [AppFunctionName](https://developer.android.com/reference/android/app/appfunctions/AppFunctionName)
  - [AppFunctionPackageMetadata](https://developer.android.com/reference/android/app/appfunctions/AppFunctionPackageMetadata)
  - [AppFunctionSchemaMetadata](https://developer.android.com/reference/android/app/appfunctions/AppFunctionSchemaMetadata)
  - [AppFunctionSearchSpec](https://developer.android.com/reference/android/app/appfunctions/AppFunctionSearchSpec)
  - [AppFunctionSearchSpec.Builder](https://developer.android.com/reference/android/app/appfunctions/AppFunctionSearchSpec.Builder)
  - [AppFunctionService](https://developer.android.com/reference/android/app/appfunctions/AppFunctionService)
  - [AppFunctionState](https://developer.android.com/reference/android/app/appfunctions/AppFunctionState)
  - [AppFunctionUriGrant](https://developer.android.com/reference/android/app/appfunctions/AppFunctionUriGrant)
  - [ExecuteAppFunctionRequest](https://developer.android.com/reference/android/app/appfunctions/ExecuteAppFunctionRequest)
  - [ExecuteAppFunctionRequest.Builder](https://developer.android.com/reference/android/app/appfunctions/ExecuteAppFunctionRequest.Builder)
  - [ExecuteAppFunctionResponse](https://developer.android.com/reference/android/app/appfunctions/ExecuteAppFunctionResponse)
  - [RegisterAppFunctionRequest](https://developer.android.com/reference/android/app/appfunctions/RegisterAppFunctionRequest)
-

  ## Exceptions

  - [AppFunctionException](https://developer.android.com/reference/android/app/appfunctions/AppFunctionException)