Skip to main content
Glama

handleIntentChooser

Manage system intent chooser dialogs by specifying preferences ('always', 'just_once', or 'custom') to streamline app selection during automation. Supports custom app package selection for tailored workflows.

Instructions

Automatically handle system intent chooser dialog with specified preferences

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
customAppPackageNoSpecific app package to select when preference is 'custom'
preferenceNoPreference for handling intent chooser (default: 'just_once')

Implementation Reference

  • Core handler implementation: detects intent chooser in view hierarchy, locates appropriate button or app based on preference, computes tap coordinates, and executes ADB tap command.
    async handleIntentChooser( viewHierarchy: ViewHierarchyResult, preference: "always" | "just_once" | "custom" = "just_once", customAppPackage?: string ): Promise<IntentChooserResult> { try { const detected = this.detectIntentChooser(viewHierarchy); if (!detected) { return { success: true, detected: false }; } logger.info(`[DeepLinkManager] Intent chooser detected, preference: ${preference}`); // Parse the view hierarchy to find buttons const rootNodes = this.elementUtils.extractRootNodes(viewHierarchy); let targetElement = null; if (preference === "always") { // Look for "Always" button for (const rootNode of rootNodes) { targetElement = this.findButtonByText(rootNode, ["Always", "ALWAYS"]); if (targetElement) {break;} } } else if (preference === "just_once") { // Look for "Just once" button for (const rootNode of rootNodes) { targetElement = this.findButtonByText(rootNode, ["Just once", "JUST ONCE", "Once"]); if (targetElement) {break;} } } else if (preference === "custom" && customAppPackage) { // Look for specific app in the list for (const rootNode of rootNodes) { targetElement = this.findAppInChooser(rootNode, customAppPackage); if (targetElement) {break;} } } if (targetElement) { // Simulate tap on the target element const center = this.elementUtils.getElementCenter(targetElement); await this.adbUtils.executeCommand(`shell input tap ${center.x} ${center.y}`); logger.info(`[DeepLinkManager] Tapped on intent chooser option at (${center.x}, ${center.y})`); return { success: true, detected: true, action: preference, appSelected: customAppPackage }; } else { return { success: false, detected: true, error: `Could not find target element for preference: ${preference}` }; } } catch (error) { logger.error(`[DeepLinkManager] Failed to handle intent chooser: ${error}`); return { success: false, detected: true, error: error instanceof Error ? error.message : String(error) }; } }
  • Registers the 'handleIntentChooser' tool with ToolRegistry, including name, description, schema, and handler function.
    ToolRegistry.registerDeviceAware( "handleIntentChooser", "Automatically handle system intent chooser dialog with specified preferences", handleIntentChooserSchema, handleIntentChooserHandler, false // Does not support progress notifications );
  • Zod schema defining optional input parameters: preference (enum) and customAppPackage (string).
    export const handleIntentChooserSchema = z.object({ preference: z.enum(["always", "just_once", "custom"]).optional().describe("Preference for handling intent chooser (default: 'just_once')"), customAppPackage: z.string().optional().describe("Specific app package to select when preference is 'custom'"), });
  • Top-level tool handler: instantiates HandleIntentChooser class, calls execute with args, formats JSON response, handles errors.
    const handleIntentChooserHandler = async (device: BootedDevice, args: HandleIntentChooserArgs) => { try { const handleIntentChooser = new HandleIntentChooser(device); const result = await handleIntentChooser.execute( args.preference || "just_once", args.customAppPackage, ); return createJSONToolResponse({ message: result.detected ? `Intent chooser handled with preference: ${args.preference || "just_once"}` : "No intent chooser detected", success: result.success, detected: result.detected, action: result.action, appSelected: result.appSelected, error: result.error, observation: result.observation }); } catch (error) { logger.error(`[handleIntentChooser] Failed to handle intent chooser: ${error}`); throw new ActionableError(`Failed to handle intent chooser: ${error}`); } };
  • Helper class extending BaseVisualChange: initializes DeepLinkManager, wraps core handler in observedInteraction for view hierarchy observation.
    export class HandleIntentChooser extends BaseVisualChange { private deepLinkManager: DeepLinkManager; /** * Create an TerminateApp instance * @param device - Optional device * @param adb - Optional AdbUtils instance for testing * @param idb - Optional IdbPython instance for testing */ constructor(device: BootedDevice, adb: AdbUtils | null = null, axe: Axe | null = null) { super(device, adb, axe); this.device = device; this.deepLinkManager = new DeepLinkManager(device); } /** * Execute intent chooser handling * @param preference - User preference for handling ("always", "just_once", or "custom") * @param customAppPackage - Optional specific app package to select for custom preference * @returns Promise with intent chooser handling results */ async execute( preference: "always" | "just_once" | "custom" = "just_once", customAppPackage?: string ): Promise<IntentChooserResult> { return this.observedInteraction( async (observeResult: ObserveResult) => { const viewHierarchy = observeResult.viewHierarchy; if (!viewHierarchy) { return { success: false, error: "View hierarchy not found" }; } return await this.deepLinkManager.handleIntentChooser( viewHierarchy, preference, customAppPackage ); }, { changeExpected: false, timeoutMs: 500, } ); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zillow/auto-mobile'

If you have feedback or need assistance with the MCP directory API, please join our Discord server