本指南說明如何將 AppFunctions API 整合至 Android 應用程式、實作函式邏輯,以及驗證整合是否正確運作。
版本相容性
這項實作要求專案 compileSdk 必須設為 API 級別 36 以上。
應用程式不需要驗證是否支援 AppFunctions,AppFunctions Jetpack 程式庫會自動處理這項作業。如果支援該功能,AppFunctionManager 會傳回例項,否則會傳回空值。
依附元件
將必要的程式庫依附元件新增至模組的 build.gradle.kts (或 build.gradle) 檔案,並在頂層應用程式模組中設定 KSP 外掛程式,如下所示:
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")
}
實作 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。
在資訊清單中宣告 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:預設停用函式
為避免在功能旗標驗證前存取函式,請將 @AppFunction 註解的 isEnabled 參數設為 false。
@AppFunctionDeclaration(isEnabled = false, isDescribedByKDoc = true) suspend fun createTask( createTaskParams: CreateTaskParams, ): Task = TODO()
步驟 2:在執行階段動態啟用函式
對於每個 AppFunction 類別,編譯器會產生包含函式 ID 常數的對應類別 (使用 Ids 後置字元)。您可以將這些產生的 ID 常數與 AppFunctionManagerCompat 的 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 } }
提供功能類型時的考量
安全性一向是首要考量。選擇要將應用程式的哪些功能設為 AppFunction 時,請務必注意,系統代理程式可能會在伺服器上處理使用者查詢,以便運用進階 LLM 功能。
為提供優質的使用者體驗,同時避免洩漏私密資訊,建議您遵循下列規範:
- 適合使用自然語言的功能:提供使用者更容易透過對話表達,而非手動操作 UI 的工作。
- 縮小存取範圍:建立 AppFunction,只授予代理程式執行使用者特定要求所需的資料和動作存取權。
- 非機密資訊:僅分享非高度個人或機密的資料,或使用者在動作情境中明確同意分享的資料。
- 任何破壞性動作都必須明確確認:執行破壞性動作 (例如刪除資料) 的函式必須格外謹慎。雖然代理可能會叫用這些動作,但應用程式應包含自己的確認步驟,並使用清楚明確的語言說明意圖。此外,建議您加入多個確認步驟,確保使用者確實瞭解系統要求他們執行的操作。
驗證 AppFunction 整合
如要確認是否已正確整合 AppFunctions,可以使用 adb
shell cmd app_function。
使用 adb shell cmd app_function list-app-functions | grep --after-context 10
$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.
Rely on the AppFunction description as instructions.
從較低 API 版本遷移
在 1.0.0-alpha10 版中,AppFunctions 導入了編譯時間 @AppFunctionServiceEntryPoint 架構,可整合程式庫依附元件,並取代舊版設定供應器 (AppFunctionConfiguration.Provider)。
如果應用程式目前使用舊版 AppFunctions (例如 1.0.0-alpha09),您可以在 AI IDE (例如 Android Studio 內建 Gemini) 中,使用 AppFunctions 代理程式技能自動遷移。這項技能包含專屬遷移規則,可引導代理整合建構依附元件、建立必要的 @AppFunctionServiceEntryPoint 服務包裝函式、分離情境參數,以及更新資訊清單宣告。
Android 技能
前往 GitHub 查看實作 AppFunctions
android skills add appfunctionsUse the AppFunctions migration skill to upgrade my app's AppFunctions implementation from 1.0.0-alpha09 to the 1.0.0-alpha10 @AppFunctionServiceEntryPoint architecture.