For Each Element In Screen
Summary
- Internal name:
ForEachElementInScreen - Category: Android UI
- Purpose: Run a nested sub-workflow once per accessibility node currently on screen, exposing each node's text, content description, center position, and clickable flags in loop variables.
- Task type: Connector - see Tasks Overview > Connector Tasks for what this means before reading further.
Compatibility
- Minimum AndroMate version:
1.1.0 - Maximum AndroMate version:
1.1.0 - Minimum Android:
Android 13 (API 33) - Maximum Android tested:
Android 16 (API 36) -
Supported manufacturers:
- Samsung (One UI 6.x / 7.x / 8.x)
- Other manufacturers - not supported yet (Xiaomi HyperOS and Google Pixel are being adapted)
- Required permissions:
ACCESSIBILITY_SERVICE(plus whatever tasks are placed inside"do"require)
Detailed description
The For Each Element In Screen task walks the accessibility tree of the active window in traversal order (the same order as Get Screen Elements) and runs the sub-workflow embedded under "do" once per node - the screen-element counterpart to ForEachElement's list iteration.
Each of the six output variables is independent and optional: leave a "*_variable_input" field empty (or omit it) to skip that one - e.g. if you only care about position, don't set text_variable_input. Unlike ForEachElement, an unset variable name is never an error; it simply means "don't expose this one."
In the outer graph, ForEachElementInScreen behaves like a normal task - one incoming link, one outgoing "to" link, followed once every node has been processed.
Input parameters
| Parameter | Type | Required | Possible values | Android Compatibility | AndroMate Compatibility | Default |
|---|---|---|---|---|---|---|
text_variable_input |
String | No | A $variable name, or empty to skip |
Android 13 (API 33) -> Android 16 (API 36) | 1.1.0 -> 1.1.0 | "" |
contentDescription_variable_input |
String | No | A $variable name, or empty to skip |
Android 13 (API 33) -> Android 16 (API 36) | 1.1.0 -> 1.1.0 | "" |
x_variable_input |
String | No | A $variable name, or empty to skip |
Android 13 (API 33) -> Android 16 (API 36) | 1.1.0 -> 1.1.0 | "" |
y_variable_input |
String | No | A $variable name, or empty to skip |
Android 13 (API 33) -> Android 16 (API 36) | 1.1.0 -> 1.1.0 | "" |
isClickable_variable_input |
String | No | A $variable name, or empty to skip |
Android 13 (API 33) -> Android 16 (API 36) | 1.1.0 -> 1.1.0 | "" |
isLongClickable_variable_input |
String | No | A $variable name, or empty to skip |
Android 13 (API 33) -> Android 16 (API 36) | 1.1.0 -> 1.1.0 | "" |
do |
Object (sub-workflow) | Yes | A nested workflow object - see Iterate's The do sub-workflow for the shape (identical here) |
Android 13 (API 33) -> Android 16 (API 36) | 1.1.0 -> 1.1.0 | - |
Output parameters
The For Each Element In Screen task itself produces no outputs. Any variable written by a task inside "do" updates the shared workflow context normally, as if that task ran directly in the outer graph. The six *_variable_input fields are per-iteration loop variables (see Output parameter details), not persistent task outputs.
Exceptions
| Code | Exception Name | Description |
|---|---|---|
SCREEN-AUTOMATOR-ERROR-010 |
Screen Automator Service Not Connected | The AndroMate accessibility service isn't enabled/connected. |
CONNECTOR-TASK-ERROR-001 |
No Sub Tasks | The "do" field is missing or empty - a connector task must contain a sub-workflow to run. |
Note: an unset *_variable_input is not an error - that output is simply skipped for every iteration. An empty screen (no nodes) is also not an error - the loop simply runs zero times.
Execution flowchart
flowchart TD
Start([ForEachElementInScreen]) --> CheckConnected{Accessibility service\nconnected?}
CheckConnected -->|No| E1[SCREEN-AUTOMATOR-ERROR-010\nSERVICE_NOT_CONNECTED]
CheckConnected -->|Yes| CheckDo{do sub-workflow\npresent?}
CheckDo -->|No| E2[CONNECTOR-TASK-ERROR-001\nNO_SUB_TASKS]
CheckDo -->|Yes| Walk["Walk accessibility tree\n(traversal order)"]
Walk --> CheckNode{More nodes?}
CheckNode -->|No| Continue[Follow outer 'to' link]
CheckNode -->|Yes| SetVars[Set any defined\n*_variable_input for this node]
SetVars --> RunSub[Run do sub-workflow]
RunSub --> CheckNode
Continue --> Success([VoidResult])
E1 --> Error([Exception])
E2 --> Error
style Start fill:#e3f2fd
style Success fill:#c8e6c9
style Error fill:#ffcdd2
style RunSub fill:#fff9c4
style SetVars fill:#c8e6c9
style Walk fill:#f3e5f5
How it works:
- Check connection: fails fast with
SERVICE_NOT_CONNECTEDif the accessibility service isn't enabled. - Check
do: raisesCONNECTOR-TASK-ERROR-001if the sub-workflow is missing or empty. - Walk: visits every node of the active window, in traversal order.
- Per node: sets whichever of the six
*_variable_inputfields are non-empty (text, contentDescription, center x/y, isClickable, isLongClickable - as strings,isClickable/isLongClickableas"true"/"false"), then runs the"do"sub-workflow to completion. - Continue: once every node has been processed (or immediately, if the screen has none), the engine follows the outer
"to"link.
Code examples
Example 1 - Log every clickable element's text
{
"Start": [
{
"id": "0",
"variables": [
{ "variableName": "$text", "variableValue": "", "is_kpi": false },
{ "variableName": "$clickable", "variableValue": "", "is_kpi": false }
]
}
],
"ForEachElementInScreen": [
{
"id": "1",
"title": "Log clickable elements",
"text_variable_input": "$text",
"isClickable_variable_input": "$clickable",
"do": {
"StartSubTask": [{ "id": "sub-0" }],
"TextReport": [
{ "id": "sub-1", "texte": "$text", "texte_type": "Info Text" }
],
"End": [{ "id": "sub-100" }],
"Links": [
{ "from": "sub-0", "to": "sub-1" },
{ "from": "sub-1", "to": "sub-100" }
]
}
}
],
"End": [{ "id": "100" }],
"Links": [
{ "from": "0", "to": "1" },
{ "from": "1", "to": "100" }
]
}
Input parameter details
1-6. Input parameters: text_variable_input, contentDescription_variable_input, x_variable_input, y_variable_input, isClickable_variable_input, isLongClickable_variable_input
Each names a $variable to receive one piece of data about the current node, on every iteration. All six are independent - set only the ones you need.
Example
7. Input parameter: do
The embedded sub-workflow, run once per node. See Iterate's The do sub-workflow for its shape.
Output parameter details
This task has no persistent output of its own. Per iteration, before running "do", it writes into whichever of these variables you named:
| Variable | Value |
|---|---|
text_variable_input |
The node's visible text, or empty if none. |
contentDescription_variable_input |
The node's content description, or empty if none. |
x_variable_input |
The center X of the node's screen bounds (the point you'd feed into Click In (x, y)). |
y_variable_input |
The center Y of the node's screen bounds. |
isClickable_variable_input |
"true" or "false" (AndroMateContext has no boolean type - stored as a string). |
isLongClickable_variable_input |
"true" or "false", same as above. |
Complete JSON example
Clicks the first element whose text is exactly "Allow", found while iterating every element on screen:
{
"Start": [
{
"id": "0",
"variables": [
{ "variableName": "$text", "variableValue": "", "is_kpi": false },
{ "variableName": "$x", "variableValue": "", "is_kpi": false },
{ "variableName": "$y", "variableValue": "", "is_kpi": false }
]
}
],
"ForEachElementInScreen": [
{
"id": "1",
"title": "Find and click Allow",
"text_variable_input": "$text",
"x_variable_input": "$x",
"y_variable_input": "$y",
"do": {
"StartSubTask": [{ "id": "sub-0" }],
"CompareStrings": [
{ "id": "sub-1", "var_x": "$text", "var_y": "Allow", "compare_type": "exactText" }
],
"ClickInXY": [
{ "id": "sub-2", "ClickInXY_X": "$x", "ClickInXY_Y": "$y" }
],
"End": [{ "id": "sub-100" }],
"Links": [
{ "from": "sub-0", "to": "sub-1" },
{ "from": "sub-1", "to": "sub-2", "condition": "true" },
{ "from": "sub-1", "to": "sub-100", "condition": "false" },
{ "from": "sub-2", "to": "sub-100" }
]
}
}
],
"End": [{ "id": "100" }],
"Links": [
{ "from": "0", "to": "1" },
{ "from": "1", "to": "100" }
]
}