本指南說明如何將 AppFunctions API 整合至 Android 應用程式、實作函式邏輯,以及驗證整合是否正確運作。
版本相容性
這項實作要求專案 compileSdk 必須設為 API 級別 37 以上。專案必須使用 Android Gradle 外掛程式 9.1.0 以上版本。
應用程式不需要驗證是否支援 AppFunctions,AppFunctions Jetpack 程式庫會自動處理。如果支援該功能,AppFunctionManager 會傳回例項,否則會傳回空值。
依附元件
將必要的程式庫依附元件新增至模組的 build.gradle.kts (或 build.gradle) 檔案,並在頂層應用程式模組中設定 KSP 外掛程式,如下所示:
dependencies {
implementation("androidx.appfunctions:appfunctions:1.0.0-beta01")
// 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-beta01")
}
實作 AppFunctions 邏輯
如要為 Android 應用程式實作 AppFunction,請建立一個類別,用於實作特定的 AppFunctions 邏輯。這包括為參數和回應建立可序列化的資料類別,然後在函式方法中提供核心邏輯。
下列程式碼範例說明如何在 TODO 應用程式中建立工作,包括定義自訂參數和回應類型,以及使用存放區的主要函式邏輯。
@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. */ @AppFunctionDeclaration(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) }
程式碼重點
- 根據預設,AppFunction 實作會在 Android UI 執行緒中執行。因此,長時間執行的作業應執行下列操作:
- 將 AppFunction 宣告為暫停函式。
- 當作業可能封鎖執行緒時,請切換至合適的協同程式調度工具。
isDescribedByKDoc設為true時,函式說明或可序列化說明會編碼為AppFunctionMetadata的一部分,協助代理程式瞭解如何使用應用程式的 AppFunction。自 1.0.0-beta01 版起,isDescribedByKDoc沒有預設值,因此請明確設定。
在資訊清單中宣告 AppFunction 服務
在模組資訊清單 (例如 src/main/AndroidManifest.xml) 中,註冊 KSP 產生的服務宣告和 app_metadata 屬性。
KSP 編譯器會產生具體服務類別 (TaskAppFunctionService)
,擴充抽象進入點類別,以及 assets/ 目錄中的對應 XML
架構。
<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" />
選用:在執行階段切換 AppFunction 可用性
在限制 AppFunctions 時,請使用 AppFunctionManager API 明確啟用或停用函式。如果應用程式的某些功能不適用於所有使用者,則可使用閘控功能。動態啟用或停用 AppFunctions 後,智慧系統就能確切知道使用者在任何特定時間可使用哪些功能。
如要安全地限制需要特定帳戶狀態的 AppFunction,請按照下列兩步驟操作:
步驟 1:預設停用函式
為避免在功能旗標驗證前存取函式,請將 @AppFunctionDeclaration 註解的 isEnabled 參數設為 false。
@AppFunctionDeclaration(isEnabled = false, isDescribedByKDoc = true) suspend fun createTask( createTaskParams: CreateTaskParams, ): Task = TODO()
步驟 2:在執行階段動態啟用函式
對於每個 @AppFunctionServiceEntryPoint 類別,編譯器都會產生包含函式 ID 常數的對應類別 (使用 Ids 後置字元)。您可以將這些產生的 ID 常數與 AppFunctionManager 的 setAppFunctionEnabled 方法搭配使用,在執行階段變更函式的啟用狀態。
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 } }
提供功能類型時的考量
安全性一向是首要考量。選擇要將應用程式的哪些功能設為 AppFunctions 時,請務必注意,系統代理程式可能會在伺服器上處理使用者查詢,以便運用進階 LLM 功能。
為提供優質的使用者體驗,同時避免洩漏機密資訊,建議您遵循下列規範:
- 適合使用自然語言的功能:提供使用者更容易透過對話表達,而非手動操作 UI 的工作。
- 縮小存取範圍:建立 AppFunction,只授予代理程式執行使用者特定要求所需的資料和動作存取權。
- 非機密資訊:僅分享非高度個人或機密的資料,或使用者在動作情境中明確同意分享的資料。
- 明確確認任何破壞性動作:執行破壞性動作 (例如刪除資料) 的函式時,請務必格外謹慎。雖然代理可能會叫用這些動作,但應用程式應包含自己的確認步驟,並使用清楚明確的語言說明意圖。此外,建議您加入多個確認步驟,確保使用者確實瞭解系統要求他們執行的操作。
驗證 AppFunction 整合
如要確認是否已正確整合 AppFunctions,可以使用 adb
shell cmd app_function。
使用 adb shell cmd app_function list-app-functions --package $myPackageName 查看應用程式提供的 AppFunctions 詳細資料。
您也可以使用明確 ID ("$enclosingClassName#$methodName"),直接從指令列執行 AppFunction:
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\"}}'"
如要體驗 Android MCP 的實際運作情形,並驗證端對端工作流程,而不需任何提示,請在裝置上安裝並執行 AppFunctions 測試代理程式 Android 應用程式。
如果您使用 Android Studio 中的 Gemini 等對話式助理驗證整合,請使用 AppFunctions 開發技能,或提供類似以下的提示:
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.
Use the AppFunction descriptions to choose functions and parameters.
從較低 API 版本遷移
在 1.0.0-alpha10 版中,AppFunctions 導入了編譯時間 @AppFunctionServiceEntryPoint 架構,可整合程式庫依附元件,並取代舊版設定供應器 (AppFunctionConfiguration.Provider)。1.0.0-alpha12 版已移除舊版供應器。1.0.0-alpha13 版將 @AppFunction 註解重新命名為 @AppFunctionDeclaration,1.0.0-beta01 版則將應用程式中繼資料 XML 檔案中的 appfn:description 屬性重新命名為 appfn:instructions。
如果應用程式使用舊版 AppFunctions (例如 1.0.0-alpha09 或 1.0.0-alpha10),您可以在 AI IDE (例如 Android Studio 內建 Gemini) 中使用 AppFunctions 代理技能,自動執行遷移作業。這項技能包含專屬遷移規則,可引導代理整合建構依附元件、建立必要的 @AppFunctionServiceEntryPoint 服務包裝函式、分離內容參數、更新資訊清單宣告,以及套用 1.0.0-beta01 重新命名。
Android 技能
前往 GitHub 查看實作 AppFunctions
android skills add appfunctionsUse the AppFunctions skill to upgrade my app's AppFunctions implementation to 1.0.0-beta01.