android_uiautomator_find
Locate Android UI elements by resource ID or text content for automation testing and device control.
Instructions
Find UI elements by resource ID or text using UIAutomator
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| resourceId | No | Resource ID to search for (e.g., com.example.app:id/button_submit) | |
| text | No | Text content to search for | |
| deviceSerial | No | Specific device serial number to target (optional) |
Implementation Reference
- src/index.ts:168-188 (registration)Tool registration in MCP server tools array: defines name, description, and input schema for 'android_uiautomator_find'.{ name: 'android_uiautomator_find', description: 'Find UI elements by resource ID or text using UIAutomator', inputSchema: { type: 'object', properties: { resourceId: { type: 'string', description: 'Resource ID to search for (e.g., com.example.app:id/button_submit)', }, text: { type: 'string', description: 'Text content to search for', }, deviceSerial: { type: 'string', description: 'Specific device serial number to target (optional)', }, }, }, },
- src/index.ts:476-477 (registration)Tool dispatch registration in the main switch statement for handling tool calls.case 'android_uiautomator_find': return await uiautomatorFindHandler(this.adb, args);
- src/handlers.ts:285-314 (handler)Main handler function that validates input, selects the appropriate ADB method based on resourceId or text, executes it, and formats the response.export async function uiautomatorFindHandler( adb: ADBWrapper, args: any ): Promise<{ content: Array<{ type: string; text: string }> }> { const { resourceId, text, deviceSerial } = args as UIAutomatorFindArgs; if (!resourceId && !text) { throw new Error('Either resourceId or text must be provided'); } try { let result: string; if (resourceId) { result = await adb.findElementByResourceId(resourceId, deviceSerial); } else { result = await adb.findElementByText(text!, deviceSerial); } return { content: [ { type: 'text', text: result, }, ], }; } catch (error) { throw new Error(`UIAutomator find failed: ${error instanceof Error ? error.message : String(error)}`); } }
- src/adb-wrapper.ts:443-461 (helper)Core helper function that dumps UI hierarchy XML using uiautomator dump, reads it, and checks if the specified resource-id exists in the XML.async findElementByResourceId(resourceId: string, deviceSerial?: string): Promise<string> { const device = await this.getTargetDevice(deviceSerial); // Get the UI hierarchy as XML const hierarchyFile = '/sdcard/window_dump.xml'; await this.exec(['shell', 'uiautomator', 'dump', hierarchyFile], device); // Read the XML file const { stdout } = await this.exec(['shell', 'cat', hierarchyFile], device); // Clean up await this.exec(['shell', 'rm', hierarchyFile], device); // Parse and search for resource ID if (stdout.includes(`resource-id="${resourceId}"`)) { return `Found element with resource-id: ${resourceId}`; } else { return `Element with resource-id: ${resourceId} not found`; } }
- src/adb-wrapper.ts:466-482 (helper)Core helper function for text-based search: dumps UI XML and checks for matching text attribute.async findElementByText(text: string, deviceSerial?: string): Promise<string> { const device = await this.getTargetDevice(deviceSerial); const hierarchyFile = '/sdcard/window_dump.xml'; await this.exec(['shell', 'uiautomator', 'dump', hierarchyFile], device); const { stdout } = await this.exec(['shell', 'cat', hierarchyFile], device); // Clean up await this.exec(['shell', 'rm', hierarchyFile], device); // Search for text if (stdout.includes(`text="${text}"`) || stdout.includes(`>${text}</`)) { return `Found element with text: ${text}`; } else { return `Element with text: ${text} not found`; } }