Ce guide explique comment intégrer l'API AppFunctions dans votre application Android, implémenter la logique d'une fonction et vérifier que l'intégration fonctionne correctement.
Compatibilité des versions
Cette implémentation nécessite que le paramètre compileSdk de votre projet soit défini sur le niveau d'API 36 ou supérieur.
Votre application n'a pas besoin de vérifier si les AppFunctions sont compatibles. Cette opération est gérée automatiquement dans la bibliothèque Jetpack AppFunctions.
AppFunctionManager renvoie une instance si la fonctionnalité est compatible, et la valeur "null" dans le cas contraire.
Dépendances
Ajoutez les dépendances de bibliothèque requises au fichier build.gradle.kts (ou build.gradle) de votre module, puis configurez le plug-in KSP dans le module d'application de premier niveau, comme indiqué ci-dessous :
dependencies {
implementation("androidx.appfunctions:appfunctions:1.0.0-alpha10")
// If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP)
// See Add the KSP plugin to your project
ksp("androidx.appfunctions:appfunctions-compiler:1.0.0-alpha10")
}
Implémenter la logique des AppFunctions
Pour implémenter une AppFunction pour votre application Android, créez une classe qui implémente la logique AppFunctions spécifique. Cela implique de créer des classes de données sérialisables pour les paramètres et les réponses, puis de fournir la logique de base dans la méthode de la fonction.
Le code suivant montre un exemple d'implémentation pour créer une tâche dans l' application TODO, y compris la définition de paramètres et de types de réponse personnalisés, ainsi que la logique de fonction principale à l'aide d'un dépôt.
@RequiresApi(36) @AndroidEntryPoint @AppFunctionServiceEntryPoint( serviceName = "TaskAppFunctionService", appFunctionXmlFileName = "task_app_function_service", ) abstract class BaseTaskAppFunctionService : AppFunctionService() { @Inject internal lateinit var taskRepository: TaskRepository /** * Creates a task based on [createTaskParams]. * * @param createTaskParams The parameter to describe how to create the task. */ @AppFunction(isDescribedByKDoc = true) suspend fun createTask( createTaskParams: CreateTaskParams, ): Task = withContext(Dispatchers.IO) { // Developers can use predefined exceptions to let the agent know // why it failed. if (createTaskParams.title == null && createTaskParams.content == null) { throw AppFunctionInvalidArgumentException("Title or content should be non-null") } val id = taskRepository.createTask( createTaskParams.title, createTaskParams.content ) return@withContext taskRepository .getTask(id) ?.toTask() ?: throw AppFunctionElementNotFoundException("Task not found for ID = $id") } // Maps internal TaskEntity private fun TaskEntity.toTask() = Task(id = id, title = title, content = description) }
Points clés concernant le code
- Par défaut, une implémentation AppFunction s'exécute dans le thread UI Android.
Par conséquent, une opération de longue durée doit effectuer les opérations suivantes :
- Déclarer l'AppFunction comme fonction de suspension.
- Passer à un répartiteur de coroutines approprié lorsque l'opération peut bloquer le thread.
- Lorsque
isDescribedByKDocest défini surtrue, la description de la fonction ou la description sérialisable est encodée dansAppFunctionMetadatapour aider l'agent à comprendre comment utiliser l'AppFunction de l'application.
Déclarer le service AppFunction dans votre fichier manifeste
Enregistrez la déclaration de service générée par KSP et la propriété app_metadata dans le fichier manifeste de votre module, par exemple dans src/main/AndroidManifest.xml.
Le compilateur KSP génère la classe de service concrète (TaskAppFunctionService) qui étend votre classe de point d'entrée abstrait, ainsi que le schéma XML correspondant dans votre répertoire assets/.
<service android:name="com.example.snippets.ai.TaskAppFunctionService" android:permission="android.permission.BIND_APP_FUNCTION_SERVICE" android:exported="true" tools:targetApi="36"> <property android:name="android.app.appfunctions.schema" android:value="app_functions_schema.xsd" /> <property android:name="android.app.appfunctions.v2" android:value="task_app_function_service.xml" /> <intent-filter> <action android:name="android.app.appfunctions.AppFunctionService" /> </intent-filter> </service> <property android:name="android.app.appfunctions.app_metadata" android:resource="@xml/app_metadata" />
Facultatif : Activer/désactiver la disponibilité des AppFunctions lors de l'exécution
Utilisez l'API AppFunctionManager pour activer ou désactiver explicitement les fonctions lorsque vous contrôlez vos AppFunctions. Le contrôle peut être utile lorsque certaines fonctionnalités de votre application ne sont pas disponibles pour tous les utilisateurs. En activant ou en désactivant dynamiquement les AppFunctions, le système d'intelligence sait exactement quelles fonctionnalités sont disponibles pour votre utilisateur à tout moment.
Pour contrôler en toute sécurité les AppFunctions qui nécessitent un état de compte spécifique, suivez une procédure en deux étapes :
Étape 1 : Désactiver la fonction par défaut
Pour empêcher l'accès à la fonction avant la validation de votre flag de fonctionnalité, définissez le paramètre isEnabled de votre annotation @AppFunction sur false.
@AppFunction(isEnabled = false, isDescribedByKDoc = true) suspend fun createTask( createTaskParams: CreateTaskParams, ): Task = TODO()
Étape 2 : Activer dynamiquement la fonction lors de l'exécution
Pour chaque classe AppFunction, le compilateur génère une classe correspondante contenant des constantes d'ID de fonction (à l'aide du suffixe Ids). Vous pouvez utiliser ces constantes d'ID générées avec la méthode setAppFunctionEnabled de AppFunctionManagerCompat pour modifier l'état activé d'une fonction lors de l'exécution.
suspend fun onFeatureEnabled(context: Context) { try { AppFunctionManager.getInstance(context) ?.setAppFunctionEnabled( BaseTaskAppFunctionServiceIds.CREATE_TASK_ID, AppFunctionManager.APP_FUNCTION_STATE_ENABLED, ) } catch (e: Exception) { // Handle exception: AppFunctions indexation may not be fully completed // upon initial app startup. } } suspend fun onFeatureDisabled(context: Context) { try { AppFunctionManager.getInstance(context) ?.setAppFunctionEnabled( BaseTaskAppFunctionServiceIds.CREATE_TASK_ID, AppFunctionManager.APP_FUNCTION_STATE_DISABLED, ) } catch (e: Exception) { // Handle exception } }
Types de fonctionnalités à rendre disponibles
Elle demeure primordiale. Lorsque vous choisissez les fonctionnalités de votre application à rendre disponibles en tant qu'AppFunctions, il est important de vous rappeler que les agents système peuvent traiter les requêtes des utilisateurs sur le serveur pour exploiter les fonctionnalités avancées des grands modèles de langage.
Pour offrir une expérience utilisateur optimale tout en évitant d'exposer des informations sensibles, nous vous recommandons de suivre ces consignes :
- Fonctionnalité qui bénéficie du langage naturel : mettez à disposition des tâches qu'un utilisateur peut exprimer plus facilement dans une conversation que par une navigation manuelle dans l'interface utilisateur.
- Accès limité : créez des AppFunctions qui n'autorisent l'agent à accéder qu'aux données et aux actions nécessaires pour répondre à la demande spécifique de l'utilisateur.
- Informations non sensibles : ne partagez que des données qui ne sont pas hautement personnelles ou confidentielles, ou des données que l'utilisateur accepte explicitement de partager dans le contexte de l'action.
- Confirmation sans ambiguïté pour toute action destructive : soyez extrêmement prudent avec les fonctions qui effectuent des actions destructives (comme la suppression de données). Bien que l'agent puisse les appeler, votre application doit inclure sa propre étape de confirmation et utiliser un langage clair et sans ambiguïté concernant les intentions. Il est également utile d'ajouter plusieurs étapes de confirmation pour s'assurer que l'utilisateur est conscient de ce qu'il est invité à faire.
Vérifier l'intégration des AppFunctions
Pour vérifier si vous avez correctement intégré les AppFunctions, vous pouvez utiliser adb
shell cmd app_function.
Utilisez adb shell cmd app_function list-app-functions | grep --after-context 10
$myPackageName pour afficher les détails des AppFunctions fournies par votre application.
Vous pouvez également exécuter une AppFunction directement à partir de la ligne de commande à l'aide de son
identifiant explicite ("$enclosingClassName#$methodName") :
adb shell "cmd app_function execute-app-function \
--package com.example.android.appfunctions \
--function 'com.example.android.appfunctions.BaseTaskAppFunctionService#createTask' \
--parameters '{\"createTaskParams\": {\"title\": \"Buy milk\", \"content\": \"From grocery store\"}}'"
Pour découvrir Android MCP en action et vérifier les workflows de bout en bout sans avoir besoin d'aucune invite, installez et exécutez l'application Android de l'agent de test AppFunctionssur votre appareil.
Si vous vérifiez votre intégration à l'aide d'assistants basés sur la discussion tels que Gemini dans Android Studio, utilisez la compétence de développement AppFunctions ou fournissez une invite comme suit :
Execute `adb shell cmd app_function` to learn how the tool works, then act as a
chat agent aiming to invoke AppFunctions to fulfil user prompts for this app.
Rely on the AppFunction description as instructions.
Migrer depuis des versions d'API inférieures
Dans la version 1.0.0-alpha10, les AppFunctions ont introduit une architecture @AppFunctionServiceEntryPoint au moment de la compilation qui consolide les dépendances de la bibliothèque et remplace les anciens fournisseurs de configuration (AppFunctionConfiguration.Provider).
Si votre application utilise actuellement une version antérieure des AppFunctions (par exemple,
1.0.0-alpha09), vous pouvez automatiser votre migration à l'aide de la compétence
de l'agent AppFunctions dans un IDE d'IA tel que Gemini dans Android Studio. La compétence contient des règles de migration dédiées qui guident un agent pour consolider vos dépendances de compilation, créer le wrapper de service @AppFunctionServiceEntryPoint requis, dissocier les paramètres de contexte et mettre à jour vos déclarations de fichier manifeste.
Pour lancer une migration automatisée avec votre agent d'IA, utilisez une invite comme suit :
Use the AppFunctions migration skill to upgrade my app's AppFunctions implementation from 1.0.0-alpha09 to the 1.0.0-alpha10 @AppFunctionServiceEntryPoint architecture.