Skip to main content
Glama

android_uiautomator_scroll_in_element

Scroll within a specific UI element on Android devices using resource ID and direction parameters to navigate content within scrollable containers.

Instructions

Scroll within a specific UI element

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
resourceIdYesResource ID of the scrollable element
directionYesDirection to scroll
distanceNoDistance to scroll in pixels (default: 500)
deviceSerialNoSpecific device serial number to target (optional)

Implementation Reference

  • Main tool handler that performs input validation and delegates to ADBWrapper.scrollInElement for execution.
    export async function uiautomatorScrollInElementHandler(
      adb: ADBWrapper,
      args: any
    ): Promise<{ content: Array<{ type: string; text: string }> }> {
      const { resourceId, direction, distance = 500, deviceSerial } = args as UIAutomatorScrollInElementArgs;
    
      if (!resourceId || typeof resourceId !== 'string') {
        throw new Error('Invalid resource ID: resourceId must be a non-empty string');
      }
    
      if (!direction || !['up', 'down', 'left', 'right'].includes(direction)) {
        throw new Error('Invalid direction: must be one of "up", "down", "left", "right"');
      }
    
      try {
        await adb.scrollInElement(resourceId, direction, distance, deviceSerial);
    
        return {
          content: [
            {
              type: 'text',
              text: `Successfully scrolled ${direction} in element with resource-id: ${resourceId}\nDistance: ${distance}px`,
            },
          ],
        };
      } catch (error) {
        throw new Error(`UIAutomator scroll in element failed: ${error instanceof Error ? error.message : String(error)}`);
      }
    }
  • Core implementation: Dumps UI hierarchy XML, parses bounds of target element, computes relative swipe start/end points from element center based on direction, performs swipe gesture.
    async scrollInElement(
      resourceId: string,
      direction: 'up' | 'down' | 'left' | 'right',
      distance: number = 500,
      deviceSerial?: string
    ): Promise<void> {
      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);
      await this.exec(['shell', 'rm', hierarchyFile], device);
      
      const boundsRegex = new RegExp(`resource-id="${resourceId}"[^>]*bounds="\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]"`);
      const match = stdout.match(boundsRegex);
      
      if (match) {
        const x1 = parseInt(match[1], 10);
        const y1 = parseInt(match[2], 10);
        const x2 = parseInt(match[3], 10);
        const y2 = parseInt(match[4], 10);
        
        const centerX = Math.floor((x1 + x2) / 2);
        const centerY = Math.floor((y1 + y2) / 2);
        
        let startX = centerX, startY = centerY, endX = centerX, endY = centerY;
        
        switch (direction) {
          case 'up':
            startY = centerY + distance;
            endY = centerY - distance;
            break;
          case 'down':
            startY = centerY - distance;
            endY = centerY + distance;
            break;
          case 'left':
            startX = centerX + distance;
            endX = centerX - distance;
            break;
          case 'right':
            startX = centerX - distance;
            endX = centerX + distance;
            break;
        }
        
        await this.swipe(startX, startY, endX, endY, 300, device);
      } else {
        throw new Error(`Element with resource-id ${resourceId} not found in UI hierarchy`);
      }
    }
  • JSON schema defining input parameters for the tool, registered in listTools response.
    inputSchema: {
      type: 'object',
      properties: {
        resourceId: {
          type: 'string',
          description: 'Resource ID of the scrollable element',
        },
        direction: {
          type: 'string',
          enum: ['up', 'down', 'left', 'right'],
          description: 'Direction to scroll',
        },
        distance: {
          type: 'number',
          description: 'Distance to scroll in pixels (default: 500)',
          default: 500,
        },
        deviceSerial: {
          type: 'string',
          description: 'Specific device serial number to target (optional)',
        },
      },
      required: ['resourceId', 'direction'],
  • src/index.ts:492-493 (registration)
    Tool name dispatch in the switch statement handling CallToolRequestSchema.
    case 'android_uiautomator_scroll_in_element':
      return await uiautomatorScrollInElementHandler(this.adb, args);
  • TypeScript interface for input argument validation in the handler.
    interface UIAutomatorScrollInElementArgs {
      resourceId: string;
      direction: 'up' | 'down' | 'left' | 'right';
      distance?: number;
      deviceSerial?: string;
    }

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/jduartedj/android-mcp-server'

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