# 📱 **CyAndroEmu: Advanced Android Automation Library**
<!-- PROJECT LOGO -->
<br />
<div align="center">
<a href="https://github.com/othneildrew/Best-README-Template">
<img src="images/logo.png" alt="Logo" width="400" height="400">
</a>
<h3 align="center">Python / Cython Automation for Android Emulators</h3>
<p align="center">
Android automations without ADB - directly on emulators
</p>
</div>
## About The Project
**CyAndroEmu** is a powerful [**Python**](https://www.python.org/) library designed for advanced Android automation. For performance reasons, it’s primarily written in [**C++**](https://cplusplus.com/) and [**Cython**](https://cython.readthedocs.io/), providing multiple backends for interacting with UI elements, handling input events, and efficiently extracting screen data.
Unlike any other Android automation library, **CyAndroEmu** is designed to run **directly and independently** on the emulator or rooted device **without relying on ADB**. This architecture offers significant performance and reliability advantages.
---
## 🚀 **Why Choose CyAndroEmu?**
### ✅ **Key Advantages:**
- **No Broken Connections:**
Since it operates independently of ADB, you’ll never face issues with unstable or dropped connections.
- **Blazing Fast Automation:**
No need for slow ADB screenshot transmissions—screen data is processed directly on the device.
- **Unlimited Device Scalability:**
Run as many emulators as your hardware can handle without hitting ADB’s device limits.
- **Natural Mouse Movements:**
Supports smooth, human-like mouse movements, making it perfect for bypassing CAPTCHA and anti-bot detection systems.
- **Fingerprint Avoidance:**
Eliminate the risk of device fingerprinting. Curious about how easy it is to fingerprint your device?
👉 [Check it here](https://amiunique.org/fingerprint)
- **Direct Botting Mode with Magisk/KernelSU:**
With Magisk or KernelSU, you can start your device and go straight into botting mode—no manual intervention needed.
- **Easy Device-Wide Proxying:**
Effortlessly proxy all network traffic using tools like [**Proxifier**](https://www.proxifier.com/) or [**SocksDroid**](https://github.com/bndeff/socksdroid) for enhanced privacy and IP rotation.
---
## ⚡ **Additional Highlights:**
- **Low-Level Performance:**
Thanks to its C++ core, CyAndroEmu achieves unparalleled speed and efficiency, even in resource-intensive environments.
- **Multi-Backend Support:**
Choose from various parsers and input methods tailored to different Android environments (real devices, emulators, custom ROMs).
- **Seamless Emulator Integration:**
Designed to work flawlessly with popular emulators like **BlissOS**, **BlueStacks**, **VMware**, and more.
- **Root-Friendly:**
Full support for rooted devices, enabling deep system-level automation capabilities.
- **Magisk / KernelSU Plugins:**
Start your Python automation **automatically** when the emulator or device boots—**no human interaction needed**.
---
## Getting Started
### Installation
**1. Download and install your favorite Android emulator, and ensure it has root access. CyAndroEmu should also work on any rooted smartphone (not tested yet). A non-root version may be available in the future. CyAndroEmu has been tested with the following:**
* [BlueStacks 5](https://www.bluestacks.com/)
* [BlissOs 14, 15, 16 Go](https://blissos.org/) (on [ProxMox](https://www.proxmox.com/), [Virtual Box - Windows](https://www.virtualbox.org/) and [VMWare - Windows](https://www.vmware.com/))
* [LDPlayer](https://ldplayer.net/)
* [MeMuPlay](https://www.memuplay.com/)
* [MuMuPlayer](https://www.mumuplayer.com/)
* [GenyMotion](https://www.genymotion.com/)
* [Nox Player](https://pt.bignox.com/)
**Although neither [Magisk](https://github.com/topjohnwu/Magisk) nor [KernelSU](https://kernelsu.org/) is required, using them can significantly simplify tasks such as [running Python scripts at Android startup](https://github.com/hansalemaos/python_autostart_debug/tree/220d88549687375e53ec6cf3e7f9641553cc4375) and automatically [adding the Termux folder to the PATH when accessing the ADB shell ](https://github.com/hansalemaos/termuxtoadb/tree/bd119fd61ed8c60e399f81de26a1e202c2a5ffa3) . They also assist in hiding root access and automating actions - [writing your own Plugins is really simple](https://topjohnwu.github.io/Magisk/guides.html). [Here are some of my tutorials in Portuguese/English](https://github.com/hansalemaos/install_python_on_android_emulators) that teach you how to install them:**
| How to install Python on an emulator | |
|-----------|-----------|
| [](https://www.youtube.com/watch?v=99mOZ3nhG8I) | [](https://www.youtube.com/watch?v=tAFduUpmxnA) |
| [](https://www.youtube.com/watch?v=_mgQo6OVxYg) | [](https://www.youtube.com/watch?v=OPB7qnj70e4) |
| [](https://www.youtube.com/watch?v=GvkM1oBJR4M) | [](https://www.youtube.com/watch?v=XBH4YEZZEXI) |
| [](https://www.youtube.com/watch?v=KMPGV4d0q08) | [](https://www.youtube.com/watch?v=_j325L8wXY0) |
| [](https://www.youtube.com/watch?v=7LDgi3qS_lU) | [](https://www.youtube.com/watch?v=edHqLJot6pk) |
***
**2. Install [Termux](https://github.com/termux/termux-app) and [TermuxBoot - optional](https://github.com/termux/termux-boot)**
***
**3. Use the following command to install the required packages ([Python](https://www.python.org/), [Pandas](https://pandas.pydata.org/), [NumPy](https://numpy.org/) and some other stuff):**
* Open a [ADB shell](https://developer.android.com/tools/adb), and Termux on your emulator and copy and paste this command to the ADB shell to save some typing:
* __necessary packages:__
```sh
input text 'yes | pkg up;pkg install -y openssh;pkg install -y git;pkg install -y openssl;pkg install -y python;pkg install -y python-numpy;pkg install -y python-pip;pkg install -y clang;pkg install -y cmake;pkg install -y coreutils;pkg install -y termux-tools;pkg install -y root-repo;pkg install -y cpulimit;pkg install -y tur-repo;pkg install -y python-pandas;pkg install -y tesseract;pkg install -y imagemagick; pkg install -y imagemagick-static;yes | python -m pip install ptpython;yes | python -m pip install cyandroemu;yes | python -m pip install regex;yes | python -m pip install ptpython;yes | python -m pip install setuptools;yes | python -m pip install Cython;yes | python -m pip install requests';input keyevent KEYCODE_ENTER;input keyevent KEYCODE_ENTER
```
* __recommended packages:__
```sh
input text 'yes | pkg up;yes | pkg install -y openssh;yes | pkg install -y ripgrep;yes | pkg rei libexpat;pkg install -y git;pkg install -y openssl;pkg install -y python;pkg install -y cloneit;pkg install -y python-lxml;pkg install -y python-numpy;pkg install -y python-pillow;pkg install -y python-pip;pkg install -y python-scipy;pkg install -y vim-python;pkg install -y clang;pkg install -y cmake;pkg install -y coreutils;pkg install -y termux-exec;pkg install -y termux-tools;pkg install -y root-repo;pkg install -y matplotlib;pkg install -y cpulimit;pkg install -y tur-repo;pkg install -y python-pandas;pkg install -y tmux;pkg install -y opencv-python;pkg install -y boost;pkg install -y boost-headers;pkg install -y boost-static;pkg install -y tesseract; pkg install -y tor; pkg install -y torsocks; pkg install -y fzf; pkg install -y imagemagick; pkg install -y imagemagick-static;pkg install -y python-scikit-image; pkg install -y python-polars; pkg install -y nodejs-20; pkg install -y gcc-14; pkg install -y ffmpeg7;yes | python -m pip install ptpython;yes | python -m pip install cyandroemu;yes | python -m pip install regex;yes | python -m pip install ptpython;yes | python -m pip install setuptools;yes | python -m pip install Cython;yes | python -m pip install requests';input keyevent KEYCODE_ENTER;input keyevent KEYCODE_ENTER
```
***
**4. Accessing Python from the ADB shell. Choose one of the 3 solutions:**
1. **Recommended:** Install the [Magisk/KernelSU plugin to automatically add the Termux bin folder to the PATH](https://github.com/hansalemaos/termuxtoadb/tree/bd119fd61ed8c60e399f81de26a1e202c2a5ffa3)
2. Add `export PATH="$PATH:/data/data/com.termux/files/usr/bin"` to `/system/etc/mkshrc` (don't forget to set the correct owner/group ... afterwards)
3. Manually type `export PATH="$PATH:/data/data/com.termux/files/usr/bin"` each time you enter the **ADB su shell**.
***
***
## Writing Python scripts
### Cyandroemu will be compiled the first time you import it! Since this process is very CPU- and memory-intensive, I recommend setting the memory to 8 GB of RAM. Later on, you can reduce it. The SO files can be copied to other instances of your chosen emulator, but be careful: the CPU must be the same, as the C++ files are compiled with the flags `-march=native` and `-mtune=native` to ensure the highest possible performance."
Cyandroemu is primarily written in [C++](https://cplusplus.com/) (6 out of 7 parsers, modified sendevent, etc.) and [Cython](https://cython.readthedocs.io/) (1 parser and the Python interface), but all automation is handled using the Python class TermuxAutomation.
***
### The Constructor
#### May Look Intimidating, but It’s Easy to Understand
```py
TermuxAutomation:
parsers: dict,
parser_timeout: int = 30,
add_input_tap: bool = True,
add_sendevent_mouse_click: bool = True,
add_sendevent_tap: bool = True,
add_mouse_action: bool = True,
mouse_device: str = "/dev/input/event4",
touch_device: str = "/dev/input/event5",
keyboard_device: str = "/dev/input/event1",
touch_device_max: int = 32767,
mouse_device_max: int = 65535,
input_cmd_tap: str = "/system/bin/input tap",
input_cmd_text: str = "/system/bin/input text",
sendevent_path: str = "/system/bin/sendevent",
screen_height: int = 768,
screen_width: int = 1024,
sh_exe: str = "/bin/sh",
su_exe: str = "su",
uiautomator_dump_path: str = "/sdcard/window_dump.xml",
uiautomator_cpu_limit: int = 5,
system_bin_path: str = "/system/bin/",
path_screencap: str = "screencap",
path_exe_tesseract: str = "/data/data/com.termux/files/usr/bin/tesseract",
path_exe_imagemagick: str = "/data/data/com.termux/files/usr/bin/magick",
tesseract_args: str = '"-l por+eng --oem 3"',
imagemagick_args: object = None,
tesseract_path_outpic: str = "/sdcard/screenshot.ppm",
uiautomator2_download_link1: str = "https://github.com/hansalemaos/uiautomator2tocsv/raw/refs/heads/main/app-uiautomator-test.apk",
uiautomator2_download_link2: str = "https://github.com/hansalemaos/uiautomator2tocsv/raw/refs/heads/main/app-uiautomator.apk",
uiautomator2_save_path1: str = "/sdcard/app-uiautomator-test.apk",
uiautomator2_save_path2: str = "/sdcard/app-uiautomator.apk",
lcp_deque_size: int = 40960,
lcp_print_stdout: bool = False,
lcp_print_stderr: bool = False,
kwargs: object = None,
adb_keyboard_link="https://github.com/hansalemaos/ADBKeyBoard/raw/refs/heads/master/ADBKeyboard.apk",
adb_keyboard_save_path="/sdcard/ADBKeyboard.apk",
valid_adb_keyboards=(
"com.android.adbkeyboard/.AdbIME",
"com.github.uiautomator/.AdbKeyboard",
),
```
### Each constructor argument explained
***
#### `parsers: dict`
The heart of the library, containing all the C++ applications required to run the automation.
To obtain the dictionary, use the following command.
The first time you run it, it will take about 5 minutes as the C++ files will be downloaded and compiled using GCC.
```py
parsers = TermuxAutomation.load_parsers_or_download_and_compile("g++")
```
***
#### `parser_timeout: int = 30`
The timeout (in seconds) for `subprocess.run`.
***
#### `add_input_tap: bool = True`
Wether to add the option to `input tap` any elment.
***
#### `add_sendevent_mouse_click: bool = True`
Whether to add the option to perform mouse clicks on any element using `sendevent`.
***
#### `add_sendevent_tap: bool = True`
Whether to add the option to tap any element using `sendevent`.
***
#### `add_mouse_action: bool = True`
Whether to add the option to perform mouse actions on elements (e.g., move to, right-click, left-click, middle-click, etc.)
using [a modified version of sendevent](https://github.com/hansalemaos/mouse_sendevent_android/tree/88ce6d1a54a3fbd2389ad00c7ede20cd60197dbe).
***
#### `mouse_device: str = "/dev/input/event4"`
#### `touch_device: str = "/dev/input/event5"`
#### `keyboard_device: str = "/dev/input/event1"`
#### `touch_device_max: int = 32767`
#### `mouse_device_max: int = 65535`
The mouse/keyboard/touch devices and their corresponding device max can be identified using
```sh
getevent -lp
```
or by using the static method `find_suitable_devices_for_input_events`:
```py
df_devices = TermuxAutomation.find_suitable_devices_for_input_events() # returns a pandas DataFrame
```
***
#### `input_cmd_tap: str = "/system/bin/input tap"`
#### `input_cmd_text: str = "/system/bin/input text"`
#### `sendevent_path: str = "/system/bin/sendevent"`
These are the standard input commands. In most cases, there’s no need to modify them.
***
#### `screen_height: int = 768`
#### `screen_width: int = 1024`
Screen height and screen width, can be identified using
```sh
wm size
```
or by using the static method `get_resolution_of_screen`
```py
screen_width, screen_height = TermuxAutomation.get_resolution_of_screen()
```
> [!CAUTION]
> **MAKE SURE TO PROVIDE THE CORRECT VALUES HERE AND DO NOT ROTATE THE SCREEN DURING AUTOMATION!
> Many parsers rely on this information to function correctly.**
***
#### `sh_exe: str = "/bin/sh"`
The path to the shell executable, in most cases, there’s no need to modify it.
***
#### `su_exe: str = "su"`
The command used to enter `su` (superuser) mode. In most cases, there’s no need to modify it.
***
#### `uiautomator_dump_path: str = "/sdcard/window_dump.xml"`
Dump path for uiautomator. In most cases, there’s no need to modify it.
***
#### `uiautomator_cpu_limit: int = 5`
The CPU usage limit for the UIAutomator + cpulimit backend.
***
#### `system_bin_path: str = "/system/bin/"`
The path where system executables are stored. In most cases, there’s no need to modify it.
***
#### `path_screencap: str = "screencap"`
The command used for taking screenshots. In most cases, there’s no need to modify it.
***
#### `path_exe_tesseract: str = "/data/data/com.termux/files/usr/bin/tesseract"`
The path to the Tesseract executable. In most cases, there’s no need to modify it.
***
#### `path_exe_imagemagick: str = "/data/data/com.termux/files/usr/bin/magick"`
The path to the ImageMagick executable. Used for tesseract preprocessing. In most cases, there’s no need to modify it.
***
#### `tesseract_args: str = '"-l por+eng --oem 3"'`
Default Tesseract arguments. The default languages are Portuguese (por) and English (eng), with fully automatic page segmentation but no OSD (default).
Use `tesseract --help-extra` to view all available options. Words are grouped using pandas
**Note:
Be aware that changing the output format may cause the parser to crash, as it requires the output to be in hOCR format.**
***
#### `imagemagick_args: object = None`
Pass None if you don’t want to preprocess the screenshot before passing it to Tesseract.
If you choose to preprocess, you can provide ImageMagick command-line arguments to adjust
the image (e.g., converting to grayscale, increasing contrast) to improve OCR accuracy.
***
#### `tesseract_path_outpic: str = "/sdcard/screenshot.ppm"`
The C++ Tesseract parser captures a screenshot using screencap, converts the image to a [PPM format](https://en.wikipedia.org/wiki/Portable_Anymap), and saves the converted output to disk before invoking Tesseract. In most cases, there’s no need to modify this path.
***
#### `uiautomator2_download_link1: str = "https://github.com/hansalemaos/uiautomator2tocsv/raw/refs/heads/main/app-uiautomator-test.apk"`
#### `uiautomator2_download_link2: str = "https://github.com/hansalemaos/uiautomator2tocsv/raw/refs/heads/main/app-uiautomator.apk"`
Backups APKs from the [Uiautomator2 project](https://github.com/openatx/uiautomator2). In most cases, there’s no need to modify this url.
***
#### `uiautomator2_save_path1: str = "/sdcard/app-uiautomator-test.apk"`
#### `uiautomator2_save_path2: str = "/sdcard/app-uiautomator.apk"`
Download path for the APKs from the [Uiautomator2 project](https://github.com/openatx/uiautomator2). In most cases, there’s no need to modify them.
***
#### `lcp_deque_size: int = 40960`
The ring buffer size of the C++ vector used by the Logcat Parser backend. In most cases, there’s no need to modify it.
***
#### `lcp_print_stdout: bool = False`
#### `lcp_print_stderr: bool = False`
Debug print options for the Logcat Parser backend. These should only be enabled if you encounter issues with the Logcat Parser backend.
***
#### `kwargs: object = None`
kwargs for `subprocess.run` In most cases, there’s no need to modify it.
***
#### `adb_keyboard_link: str = "https://github.com/hansalemaos/ADBKeyBoard/raw/refs/heads/master/ADBKeyboard.apk"`
Backup APK from the [ADBKeyboard project](https://github.com/senzhk/ADBKeyBoard). It allows sending Unicode characters but may not work on all devices. In most cases, there’s no need to modify it.
***
#### `adb_keyboard_save_path: str = "/sdcard/ADBKeyboard.apk"`
The download path for the APK from the [ADBKeyboard project](https://github.com/senzhk/ADBKeyBoard) project. In most cases, there’s no need to modify it.
***
#### `valid_adb_keyboards: tuple = ("com.android.adbkeyboard/.AdbIME", "com.github.uiautomator/.AdbKeyboard",)`
Possible package names for ADBKeyboard.
* The first name is the original from the [ADBKeyboard project](https://github.com/senzhk/ADBKeyBoard) project.
* The second name is from the [Uiautomator2 project](https://github.com/openatx/uiautomator2) project.
In most cases, there’s no need to modify them.
***
***
## Creating an instance
```py
from cyandroemu import TermuxAutomation, clean_zombies
import pandas as pd
from time import sleep as timesleep
import atexit
# Ensure background parsers and shells are terminated on exit
atexit.register(clean_zombies)
# Load parsers (first time may take ~5 mins due to download and compilation)
parsers = TermuxAutomation.load_parsers_or_download_and_compile("g++")
# Detect input devices dynamically (returns a pandas DataFrame)
df_devices = TermuxAutomation.find_suitable_devices_for_input_events()
print(df_devices)
screen_width, screen_height = TermuxAutomation.get_resolution_of_screen()
# On VMware and BlissOS, device order may change after a reboot, so hardcoding is avoided.
# If device order doesn't change on your emulator, you can hardcode the path, e.g.:
# mouse_device = "/dev/input/event4"
te = TermuxAutomation(
parsers=parsers,
mouse_device=df_devices.loc[
(df_devices["max"].str.len() == 2) & (df_devices["type"] == "mouse")
]["path"].iloc[0],
keyboard_device=df_devices.loc[
(df_devices["keys_found"]) & (df_devices["type"] == "keyboard")
]["path"].iloc[0],
mouse_device_max=df_devices.loc[
(df_devices["max"].str.len() == 2) & (df_devices["type"] == "mouse")
]["max"].iloc[0][0],
screen_height=screen_height,
screen_width=screen_width,
)
# Clean up any leftover background processes (e.g., uiautomator2 server) from earlier automations.
# atexit should handle this, but "Doppelt genäht hält besser :)" (German proverb - double-stitched holds better).
te.kill_zombies()
```
***
## Automation - it's all about pandas DataFrames
Most automation tools implement their own logic for finding elements, which often looks like this:
`self.find(text="Some text").children[0].click()`
That looks beautiful and very Pythonic, but most of the time, it’s just unreliable — mainly when the attributes and positions of objects vary, or when the objects aren’t loaded on the screen yet.
Instead of bothering you with my own "great" ideas, I decided to rely on battle-tested solutions: [pandas DataFrames](https://pandas.pydata.org/).
**With DataFrames, you can leverage powerful features like:**
* Fast sorting algorithms
* All kinds of comparisons
* Regular expressions (regex)
* Custom filter functions
If you know how to work with pandas DataFrames, you basically already know everything you need to automate whatever you want.
If not, you can learn everything from the official documentation: https://pandas.pydata.org/docs/
That’s where I got 95% of my pandas knowledge from.
***
### Pretty Print
The default `__repr__` and `__str__` functions in pandas are not ideal for displaying DataFrames, which is why they’ve been monkey-patched to ensure the entire DataFrame is pretty-printed.
```py
df = te.get_df_uiautomator2(with_screenshot=True)
print(df)
```
Now, when you print the DataFrame, you’ll see the complete content neatly formatted, making it easier to analyze UI elements.
For a line-break-free experience, I recommend using the [VTM terminal](https://github.com/directvt/vtm)
***
#### Example of a pandas DataFrame in the VTM terminal
[](https://www.youtube.com/watch?v=e-lqgiDWDNQ)
***
#### Getting screenshots of each element
In the example above, the elements are very easy to locate. However, this is not always the case.
You might want to see a screenshot of each element to write your script faster. In this case, you can use the following command on the device:
```py
df.bb_save_screenshots_as_png("/sdcard/uiautomator2screenshots")
```
Then, pull the screenshots using ADB to review them on your computer:
```sh
adb -s 192.168.115.131:5555 pull /sdcard/uiautomator2screenshots
```
The screenshot filenames correspond to the location of the elements in the DataFrame.
For example, if you want to locate the third element (index 2), simply run:
```py
df.iloc[2]
```
This will extract the element’s information, allowing you to build your pandas query from there.
***
#### Example of element screenshots
[](https://www.youtube.com/watch?v=ZIs4z4xKBOU)
***
***
## The Backends
***
### [Uiautomator2 Backend](https://github.com/hansalemaos/uiautomator2tocsv/tree/d5022bd0bb5864ba3b36cfb9c444f6557c2381c8)
| **Advantages ✅** | **Disadvantages ❌** |
|------------------------------------------------|----------------------------------------------------------|
| Very fast parsing | Blocks other parsers like the Logcat parser and traditional UIAutomator |
| Never fails due to excessive screen movement (unlike UIAutomator) | Requires APKs to be installed |
| Includes both element text and description | The server needs to run in the background |
| Great for web scraping and interacting with web elements | Automation might be detected when used with installed apps |
| Runs on any emulator | Useless with specific engines like the Unreal Engine |
***
#### Video - in action
[](https://www.youtube.com/watch?v=ZeXCKHQi-bE)
***
#### Python Code
```py
from cyandroemu import TermuxAutomation, clean_zombies
import pandas as pd
from time import sleep as timesleep
import atexit
# Ensure all background processes are terminated on exit
atexit.register(clean_zombies)
# Load parsers (first time may take ~5 mins due to download/compilation)
parsers = TermuxAutomation.load_parsers_or_download_and_compile("g++")
# Detect input devices dynamically (Necessary on BlissOS 16 Go with VMWare)
df_devices = TermuxAutomation.find_suitable_devices_for_input_events()
screen_width, screen_height = TermuxAutomation.get_resolution_of_screen()
# Initialize TermuxAutomation with dynamic device paths
te = TermuxAutomation(
parsers=parsers,
mouse_device=df_devices.loc[
(df_devices["max"].str.len() == 2) & (df_devices["type"] == "mouse")
]["path"].iloc[0],
keyboard_device=df_devices.loc[
(df_devices["keys_found"]) & (df_devices["type"] == "keyboard")
]["path"].iloc[0],
mouse_device_max=df_devices.loc[
(df_devices["max"].str.len() == 2) & (df_devices["type"] == "mouse")
]["max"].iloc[0][0],
screen_height=screen_height,
screen_width=screen_width,
)
# Kill any leftover background processes
te.kill_zombies()
# You can install the APK using:
# te.download_and_install_uiautomator2_apks()
# Ensure elements are loaded on the screen instead of relying solely on sleep
df = pd.DataFrame()
while df.empty:
# First DataFrame load may take ~5 seconds (UIAutomator2 server startup)
# For production scripts, set with_screenshot=False for better performance
# You can also pass these kwargs to temporarily change the default paramenters passed to the class constructor (valid for all backends, but not recommended)
# If you pass anything else than None, it will override the default parameters once.
# add_input_tap=None,
# add_sendevent_mouse_click=None,
# add_sendevent_tap=None,
# add_mouse_action=None,
# x_column=None,
# y_column=None,
# mouse_device=None,
# touch_device=None,
# touch_device_max=None,
# mouse_device_max=None,
# input_cmd=None,
# sendevent_path=None,
# screen_height=None,
# screen_width=None,
# mouse_action_exe=None,
# sh_exe=None,
# su_exe=None,
# kwargs=None,
# timeout=None,
df = te.get_df_uiautomator2(with_screenshot=True)
# Filter elements to target the TikTok app
df = df.loc[
(df.aa_text == "TikTok")
& (df.aa_content_desc == "TikTok")
& (df.aa_clickable == 1)
]
# Click the first matching element using input tap
# Optional: Add offset like df.aa_input_tap.iloc[0](20, 40)
df.aa_input_tap.iloc[0]()
# Clear DataFrame for the next loop
df = pd.DataFrame()
# optional sleep
timesleep(2)
# Repeating the same process for other UI elements
while df.empty:
df = te.get_df_uiautomator2(with_screenshot=True)
df = df.loc[
(df.aa_text == "Already have an account? Log in")
& (df.aa_clazz == "android.widget.Button")
& (df.aa_content_desc == "")
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(2)
while df.empty:
df = te.get_df_uiautomator2(with_screenshot=True)
df = df.loc[
(df.aa_text == "Use phone / email / username")
& (df.aa_clazz == "android.widget.TextView")
& (df.aa_content_desc == "")
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(2)
while df.empty:
df = te.get_df_uiautomator2(with_screenshot=True)
df = df.loc[
(df.aa_text == "Email / Username")
& (df.aa_clazz == "android.widget.TextView")
& (df.aa_content_desc == "")
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(2)
# Send text input naturally using a lightweight Cython class
# In this example, __call__ is used directly to enter the email once
te.get_cmd_send_text_natural("myemailtest@gmail.com")()
```
***
#### Example of a Pandas DataFrame (column width cropped to 30 chars)
|**index** |**aa_index** |**aa_indent** |**aa_text** |**aa_resource_id** |**aa_clazz** |**aa_package** |**aa_content_desc** |**aa_checkable** |**aa_checked** |**aa_clickable** |**aa_enabled** |**aa_focusable** |**aa_focused** |**aa_scrollable** |**aa_long_clickable** |**aa_password** |**aa_selected** |**aa_visible_to_user** |**aa_bounds** |**aa_drawing_order** |**aa_hint** |**aa_display_id** |**aa_line_index** |**aa_children** |**aa_parents** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_center_x** |**aa_center_y** |**aa_width** |**aa_height** |**aa_area** |**aa_w_h_relation** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |
|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|
|**0** |0 |4 | |com.android.systemui:id/status|android.widget.FrameLayout |com.android.systemui | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[0,0][1024,24] |1 | |0 |1 |() |() |0 |0 |1024 |24 |512 |12 |1024 |24 |24576 |42.666668 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**1** |0 |6 |8:18 |com.android.systemui:id/clock |android.widget.TextView |com.android.systemui |8:18 PM |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[16,0][45,24] |2 | |0 |2 |() |() |16 |0 |45 |24 |30 |12 |29 |24 |696 |1.208333 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**2** |1 |6 | | |android.widget.ImageView |com.android.systemui |Termux notification: 1 session|0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[45,0][69,24] |4 | |0 |3 |() |() |45 |0 |69 |24 |57 |12 |24 |24 |576 |1.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**3** |2 |6 | | |android.widget.ImageView |com.android.systemui |Settings notification: NECVMWa|0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[69,0][93,24] |5 | |0 |4 |() |() |69 |0 |93 |24 |81 |12 |24 |24 |576 |1.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**4** |3 |6 | | |android.widget.ImageView |com.android.systemui |Ethernet. |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[959,1][978,23] |12 | |0 |5 |() |() |959 |1 |978 |23 |968 |12 |19 |22 |418 |0.863636 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**5** |4 |6 | |com.android.systemui:id/batter|android.widget.LinearLayout |com.android.systemui |Battery percentage unknown. |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[984,0][996,24] |16 | |0 |6 |() |() |984 |0 |996 |24 |990 |12 |12 |24 |288 |0.5 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**6** |0 |2 | | |android.widget.FrameLayout |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[0,0][1024,768] |0 | |0 |7 |() |() |0 |0 |1024 |768 |512 |384 |1024 |768 |786432 |1.333333 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**7** |0 |4 | |com.zhiliaoapp.musically:id/d4|android.view.ViewGroup |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[0,24][1024,736] |1 | |0 |8 |() |() |0 |24 |1024 |736 |512 |380 |1024 |712 |729088 |1.438202 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**8** |0 |6 | |com.zhiliaoapp.musically:id/r7|android.widget.ImageView |com.zhiliaoapp.musically |Report a problem |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[4,26][52,74] |3 | |0 |9 |() |() |4 |26 |52 |74 |28 |50 |48 |48 |2304 |1.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**9** |2 |6 |Skip |com.zhiliaoapp.musically:id/p6|android.widget.Button |com.zhiliaoapp.musically | |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[980,38][1008,56] |5 | |0 |10 |() |() |980 |38 |1008 |56 |994 |47 |28 |18 |504 |1.555556 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**10** |3 |6 | |com.zhiliaoapp.musically:id/tt|androidx.viewpager.widget.View|com.zhiliaoapp.musically | |0 |0 |0 |1 |1 |0 |1 |0 |0 |0 |1 |[0,77][1024,736] |2 | |0 |11 |() |() |0 |77 |1024 |736 |512 |406 |1024 |659 |674816 |1.553869 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**11** |0 |8 | |com.zhiliaoapp.musically:id/c7|androidx.recyclerview.widget.R|com.zhiliaoapp.musically | |0 |0 |0 |1 |1 |0 |0 |0 |0 |0 |1 |[267,77][758,396] |1 | |0 |12 |() |() |267 |77 |758 |396 |512 |236 |491 |319 |156629 |1.539185 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**12** |0 |10 | | |android.widget.LinearLayout |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[267,82][758,228] |1 | |0 |13 |() |() |267 |82 |758 |228 |512 |155 |491 |146 |71686 |3.363014 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**13** |0 |12 |Sign up for TikTok |com.zhiliaoapp.musically:id/ti|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |1 |0 |0 |1 |[267,122][758,150] |1 | |0 |14 |() |() |267 |122 |758 |150 |512 |136 |491 |28 |13748 |17.535715 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**14** |1 |12 |Create a profile, follow other|com.zhiliaoapp.musically:id/oe|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[267,162][758,200] |2 | |0 |15 |() |() |267 |162 |758 |200 |512 |181 |491 |38 |18658 |12.921053 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**15** |1 |10 | |com.zhiliaoapp.musically:id/cz|android.widget.Button |com.zhiliaoapp.musically |Use phone or email |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[267,228][758,272] |2 | |0 |16 |() |() |267 |228 |758 |272 |512 |250 |491 |44 |21604 |11.159091 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**16** |0 |12 |Use phone or email |com.zhiliaoapp.musically:id/c7|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[454,241][593,260] |1 | |0 |17 |() |() |454 |241 |593 |260 |523 |250 |139 |19 |2641 |7.31579 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**17** |2 |10 | |com.zhiliaoapp.musically:id/cz|android.widget.Button |com.zhiliaoapp.musically |Continue with Facebook |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[267,284][758,328] |3 | |0 |18 |() |() |267 |284 |758 |328 |512 |306 |491 |44 |21604 |11.159091 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**18** |0 |12 |Continue with Facebook |com.zhiliaoapp.musically:id/c7|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[437,297][611,316] |1 | |0 |19 |() |() |437 |297 |611 |316 |524 |306 |174 |19 |3306 |9.157895 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**19** |3 |10 | |com.zhiliaoapp.musically:id/cz|android.widget.Button |com.zhiliaoapp.musically |Continue with Google |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[267,340][758,384] |4 | |0 |20 |() |() |267 |340 |758 |384 |512 |362 |491 |44 |21604 |11.159091 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**20** |0 |12 |Continue with Google |com.zhiliaoapp.musically:id/c7|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[445,353][602,371] |1 | |0 |21 |() |() |445 |353 |602 |371 |523 |362 |157 |18 |2826 |8.722222 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**21** |1 |8 |By continuing with an account |com.zhiliaoapp.musically:id/rw|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |1 |0 |0 |0 |0 |0 |1 |[32,628][992,675] |3 | |0 |22 |() |() |32 |628 |992 |675 |512 |651 |960 |47 |45120 |20.425531 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**22** |2 |8 |Already have an account? Log i|com.zhiliaoapp.musically:id/s5|android.widget.Button |com.zhiliaoapp.musically | |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[0,676][1024,736] |7 | |0 |23 |() |() |0 |676 |1024 |736 |512 |706 |1024 |60 |61440 |17.066668 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[248 248 248] [248 248 248|
***
***
### [LogCat Parser Backend](https://github.com/hansalemaos/elparse/tree/f7256f182323d5fb74c0403c37f36fde40143d36)
| **Advantages ✅** | **Disadvantages ❌** |
|---------------------------------------------------------------|----------------------------------------------------------------|
| Very fast parsing with extremely low CPU usage | Requires interaction with elements or changes in element status |
| Detects elements that are not even visible on the screen | Requires APKs to be installed |
| Includes both element text and description | Needs to run as an Accessibility Service |
| Great for web scraping and interacting with web elements | Automation might be detected when used with installed apps |
| Doesn’t block the classic UIAutomator | Ineffective with specific engines like Unreal Engine |
| Automatically captures any element changes—perfect for crypto, sports betting | Best results achieved on emulators with a mouse device (e.g., BlissOS, BlueStacks) |
***
#### Video - in action
[](https://www.youtube.com/watch?v=DEUOs9wnufY)
***
#### Python Code
```py
# Imports and instance creation omitted for brevity
df = pd.DataFrame()
# Loop to find the TikTok element and click it
while df.empty:
# Moves the mouse horizontally and vertically to provoke interaction with all elements on the screen
# Works on BlueStacks 5 and BlissOS with VMware, and probably some other emulators
df = te.get_df_lcp_with_mouse_movement()
df = df.loc[
(df.aa_Text == "TikTok")
& (df.aa_ContentDescription == "TikTok")
& (df.aa_ClassName == "android.widget.TextView")
]
# Clear the DataFrame for the next interaction
df.aa_input_tap.iloc[0]()
timesleep(2)
df = pd.DataFrame()
while df.empty:
df = te.get_df_lcp_with_mouse_movement()
df = df.loc[
(df.aa_Text == "Already have an account? Log in")
& (df.aa_ContentDescription == "null")
& (df.aa_ClassName == "android.widget.Button")
]
df.aa_input_tap.iloc[0]()
timesleep(2)
df = pd.DataFrame()
while df.empty:
df = te.get_df_lcp_with_mouse_movement()
df = df.loc[
(df.aa_Text == "null")
& (df.aa_ContentDescription == "Use phone / email / username")
& (df.aa_ClassName == "android.widget.Button")
]
df.aa_input_tap.iloc[0]()
timesleep(2)
df = pd.DataFrame()
while df.empty:
df = te.get_df_lcp_with_mouse_movement()
df = df.loc[
(df.aa_Text == "null")
& (df.aa_ContentDescription == "Email / Username")
& (df.aa_ClassName == "android.widget.LinearLayout")
]
df.aa_input_tap.iloc[0]()
timesleep(2)
te.get_cmd_send_text_natural("myemailtest@gmail.com")()
```
***
#### Example of a Pandas DataFrame (column width cropped to 30 chars)
|**index** |**aa_Text** |**aa_ContentDescription** |**aa_StateDescription** |**aa_ClassName** |**aa_PackageName** |**aa_Error** |**aa_AccessNodeInfo** |**aa_WindowId** |**aa_WindowChanges** |**aa_WindowChangeTypes** |**aa_VirtualDescendantId** |**aa_ViewIdResName** |**aa_UniqueId** |**aa_TraversalBefore** |**aa_TraversalAfter** |**aa_TooltipText** |**aa_TimeStamp** |**aa_TimeNow** |**aa_SpeechStateChangeTypes** |**aa_SourceWindowId** |**aa_SourceNodeId** |**aa_SourceDisplayId** |**aa_Source** |**aa_Sealed** |**aa_Records** |**aa_ParentNodeId** |**aa_ParcelableData** |**aa_MovementGranularities** |**aa_HashCode** |**aa_EventType** |**aa_Actions** |**aa_ContentChangeTypes** |**aa_ConnectionId** |**aa_ChildAccessibilityIds** |**aa_BooleanProperties** |**aa_BeforeText** |**aa_Active** |**aa_AccessibilityViewId** |**aa_AccessibilityTool** |**aa_BoundsInScreen** |**aa_BoundsInParent** |**aa_UnixTimeText** |**aa_start_x_real** |**aa_start_y_real** |**aa_end_x_real** |**aa_end_y_real** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_center_x** |**aa_center_y** |**aa_width** |**aa_height** |**aa_w_h_relation** |**aa_area** |**aa_parent_start_x_real** |**aa_parent_start_y_real** |**aa_parent_end_x_real** |**aa_parent_end_y_real** |**aa_parent_start_x** |**aa_parent_start_y** |**aa_parent_end_x** |**aa_parent_end_y** |**aa_parent_center_x** |**aa_parent_center_y** |**aa_parent_width** |**aa_parent_height** |**aa_parent_w_h_relation** |**aa_parent_area** |**aa_UnixTime** |**aa_distance_from_start** |**aa_size** |**aa_Visible** |**aa_Password** |**aa_Selected** |**aa_Scrollable** |**aa_LongClickable** |**aa_Loggable** |**aa_IsTextSelectable** |**aa_ImportantForAccessibility|**aa_Enabled** |**aa_Empty** |**aa_ContextClickable** |**aa_ContentInvalid** |**aa_FullScreen** |**aa_Focused** |**aa_Focusable** |**aa_AccessibilityFocused** |**aa_AccessibilityDataSensitiv|**aa_Clickable** |**aa_Checked** |**aa_Checkable** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |
|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|
|**0** |null |null |null |android.widget.LinearLayout |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(267, 82 - 758, 228) |Rect(0, 0 - 491, 146) |02-06 20:16:04.651 |267 |82 |758 |228 |267 |82 |758 |228 |512 |155 |491 |146 |3.363013698630137 |71686 |0 |0 |491 |146 |0 |0 |491 |146 |245 |73.0 |491.0 |146.0 |3.363013698630137 |71686.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**1** |Sign up for TikTok |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(267, 122 - 758, 150) |Rect(0, 0 - 491, 28) |02-06 20:16:04.651 |267 |122 |758 |150 |267 |122 |758 |150 |512 |136 |491 |28 |17.535714285714285 |13748 |0 |0 |491 |28 |0 |0 |491 |28 |245 |14.0 |491.0 |28.0 |17.535714285714285 |13748.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**2** |null |null |null |androidx.recyclerview.widget.R|com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(267, 77 - 758, 396) |Rect(0, 0 - 491, 319) |02-06 20:16:04.651 |267 |77 |758 |396 |267 |77 |758 |396 |512 |236 |491 |319 |1.5391849529780564 |156629 |0 |0 |491 |319 |0 |0 |491 |319 |245 |159.0 |491.0 |319.0 |1.5391849529780564 |156629.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**3** |Sign up for TikTok |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(52, 24 - 201, 76) |Rect(0, 0 - 149, 52) |02-06 20:16:04.651 |52 |24 |201 |76 |52 |24 |201 |76 |126 |50 |149 |52 |2.8653846153846154 |7748 |0 |0 |149 |52 |0 |0 |149 |52 |74 |26.0 |149.0 |52.0 |2.8653846153846154 |7748.0 |1738883764651.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**4** |Skip |null |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(980, 38 - 1008, 56) |Rect(0, 0 - 28, 18) |02-06 20:16:04.651 |980 |38 |1008 |56 |980 |38 |1008 |56 |994 |47 |28 |18 |1.5555555555555556 |504 |0 |0 |28 |18 |0 |0 |28 |18 |14 |9.0 |28.0 |18.0 |1.5555555555555556 |504.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**5** |null |Report a problem |null |android.widget.ImageView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(4, 26 - 52, 74) |Rect(0, 0 - 48, 48) |02-06 20:16:04.651 |4 |26 |52 |74 |4 |26 |52 |74 |28 |50 |48 |48 |1.0 |2304 |0 |0 |48 |48 |0 |0 |48 |48 |24 |24.0 |48.0 |48.0 |1.0 |2304.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**6** |null |null |null |androidx.viewpager.widget.View|com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(0, 77 - 1024, 736) |Rect(0, 0 - 1024, 659) |02-06 20:16:04.651 |0 |77 |1024 |736 |0 |77 |1024 |736 |512 |406 |1024 |659 |1.5538694992412747 |674816 |0 |0 |1024 |659 |0 |0 |1024 |659 |512 |329.0 |1024.0 |659.0 |1.5538694992412747 |674816.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**7** |null |null |null |android.view.ViewGroup |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(0, 24 - 1024, 736) |Rect(0, 0 - 1024, 712) |02-06 20:16:04.623 |0 |24 |1024 |736 |0 |24 |1024 |736 |512 |380 |1024 |712 |1.4382022471910112 |729088 |0 |0 |1024 |712 |0 |0 |1024 |712 |512 |356.0 |1024.0 |712.0 |1.4382022471910112 |729088.0 |1738883764623.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**8** |Continue with Google |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1469, 352 - 1024, 370) |Rect(0, 0 - 157, 18) |02-06 20:16:04.622 |1469 |352 |1024 |370 |1469 |352 |1024 |370 |1246 |361 |-445 |18 |-24.72222222222222 |-8010 |0 |0 |157 |18 |0 |0 |157 |18 |78 |9.0 |157.0 |18.0 |8.722222222222221 |2826.0 |1738883764622.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**9** |By continuing with an account |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(32, 628 - 992, 675) |Rect(0, 0 - 960, 47) |02-06 20:16:04.621 |32 |628 |992 |675 |32 |628 |992 |675 |512 |651 |960 |47 |20.425531914893615 |45120 |0 |0 |960 |47 |0 |0 |960 |47 |480 |23.0 |960.0 |47.0 |20.425531914893615 |45120.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**10** |Continue with Google |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(445, 353 - 602, 371) |Rect(0, 0 - 157, 18) |02-06 20:16:04.621 |445 |353 |602 |371 |445 |353 |602 |371 |523 |362 |157 |18 |8.722222222222221 |2826 |0 |0 |157 |18 |0 |0 |157 |18 |78 |9.0 |157.0 |18.0 |8.722222222222221 |2826.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**11** |Manage your account, check not|null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1291, 162 - 1024, 199) |Rect(0, 0 - 491, 37) |02-06 20:16:04.621 |1291 |162 |1024 |199 |1291 |162 |1024 |199 |1157 |180 |-267 |37 |-7.216216216216216 |-9879 |0 |0 |491 |37 |0 |0 |491 |37 |245 |18.0 |491.0 |37.0 |13.27027027027027 |18167.0 |1738883764621.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**12** |Log in to TikTok |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1291, 122 - 1024, 150) |Rect(0, 0 - 491, 28) |02-06 20:16:04.621 |1291 |122 |1024 |150 |1291 |122 |1024 |150 |1157 |136 |-267 |28 |-9.535714285714286 |-7476 |0 |0 |491 |28 |0 |0 |491 |28 |245 |14.0 |491.0 |28.0 |17.535714285714285 |13748.0 |1738883764621.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**13** |null |null |null |android.widget.LinearLayout |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1291, 82 - 1024, 227) |Rect(0, 0 - 491, 145) |02-06 20:16:04.621 |1291 |82 |1024 |227 |1291 |82 |1024 |227 |1157 |154 |-267 |145 |-1.8413793103448275 |-38715 |0 |0 |491 |145 |0 |0 |491 |145 |245 |72.0 |491.0 |145.0 |3.386206896551724 |71195.0 |1738883764621.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**14** |null |null |null |androidx.recyclerview.widget.R|com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1291, 77 - 1024, 451) |Rect(0, 0 - 491, 374) |02-06 20:16:04.621 |1291 |77 |1024 |451 |1291 |77 |1024 |451 |1157 |264 |-267 |374 |-0.713903743315508 |-99858 |0 |0 |491 |374 |0 |0 |491 |374 |245 |187.0 |491.0 |374.0 |1.3128342245989304 |183634.0 |1738883764621.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**15** |Already have an account? Log i|null |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(0, 676 - 1024, 736) |Rect(0, 0 - 1024, 60) |02-06 20:16:04.621 |0 |676 |1024 |736 |0 |676 |1024 |736 |512 |706 |1024 |60 |17.066666666666666 |61440 |0 |0 |1024 |60 |0 |0 |1024 |60 |512 |30.0 |1024.0 |60.0 |17.066666666666666 |61440.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[248 248 248] [248 248 248|
|**16** |Create a profile, follow other|null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(267, 162 - 758, 200) |Rect(0, 0 - 491, 38) |02-06 20:16:04.621 |267 |162 |758 |200 |267 |162 |758 |200 |512 |181 |491 |38 |12.921052631578949 |18658 |0 |0 |491 |38 |0 |0 |491 |38 |245 |19.0 |491.0 |38.0 |12.921052631578949 |18658.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**17** |null |Use phone or email |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(267, 228 - 758, 272) |Rect(0, 0 - 491, 44) |02-06 20:16:04.621 |267 |228 |758 |272 |267 |228 |758 |272 |512 |250 |491 |44 |11.159090909090908 |21604 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**18** |Use phone or email |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(454, 241 - 593, 260) |Rect(0, 0 - 139, 19) |02-06 20:16:04.621 |454 |241 |593 |260 |454 |241 |593 |260 |523 |250 |139 |19 |7.315789473684211 |2641 |0 |0 |139 |19 |0 |0 |139 |19 |69 |9.0 |139.0 |19.0 |7.315789473684211 |2641.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**19** |null |Continue with Facebook |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(267, 284 - 758, 328) |Rect(0, 0 - 491, 44) |02-06 20:16:04.621 |267 |284 |758 |328 |267 |284 |758 |328 |512 |306 |491 |44 |11.159090909090908 |21604 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**20** |Continue with Facebook |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(437, 297 - 611, 316) |Rect(0, 0 - 174, 19) |02-06 20:16:04.621 |437 |297 |611 |316 |437 |297 |611 |316 |524 |306 |174 |19 |9.157894736842104 |3306 |0 |0 |174 |19 |0 |0 |174 |19 |87 |9.0 |174.0 |19.0 |9.157894736842104 |3306.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**21** |null |Continue with Google |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(267, 340 - 758, 384) |Rect(0, 0 - 491, 44) |02-06 20:16:04.621 |267 |340 |758 |384 |267 |340 |758 |384 |512 |362 |491 |44 |11.159090909090908 |21604 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**22** |null |Continue with Instagram |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1291, 395 - 1024, 439) |Rect(0, 0 - 491, 44) |02-06 20:16:04.620 |1291 |395 |1024 |439 |1291 |395 |1024 |439 |1157 |417 |-267 |44 |-6.068181818181818 |-11748 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**23** |Use phone / email / username |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1440, 240 - 1024, 259) |Rect(0, 0 - 216, 19) |02-06 20:16:04.620 |1440 |240 |1024 |259 |1440 |240 |1024 |259 |1232 |249 |-416 |19 |-21.894736842105264 |-7904 |0 |0 |216 |19 |0 |0 |216 |19 |108 |9.0 |216.0 |19.0 |11.36842105263158 |4104.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**24** |Continue with Instagram |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1459, 408 - 1024, 426) |Rect(0, 0 - 177, 18) |02-06 20:16:04.620 |1459 |408 |1024 |426 |1459 |408 |1024 |426 |1241 |417 |-435 |18 |-24.166666666666668 |-7830 |0 |0 |177 |18 |0 |0 |177 |18 |88 |9.0 |177.0 |18.0 |9.833333333333334 |3186.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**25** |null |null |null |android.widget.FrameLayout |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(0, 0 - 1024, 768) |Rect(0, 0 - 1024, 768) |02-06 20:16:04.620 |0 |0 |1024 |768 |0 |0 |1024 |768 |512 |384 |1024 |768 |1.3333333333333333 |786432 |0 |0 |1024 |768 |0 |0 |1024 |768 |512 |384.0 |1024.0 |768.0 |1.3333333333333333 |786432.0 |1738883764620.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**26** |Don’t have an account? Sign up|null |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1024, 676 - 1024, 736) |Rect(0, 0 - 1024, 60) |02-06 20:16:04.620 |1024 |676 |1024 |736 |1024 |676 |1024 |736 |1024 |706 |0 |60 |0.0 |0 |0 |0 |1024 |60 |0 |0 |1024 |60 |512 |30.0 |1024.0 |60.0 |17.066666666666666 |61440.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**27** |By continuing with an account |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1056, 628 - 1024, 675) |Rect(0, 0 - 960, 47) |02-06 20:16:04.620 |1056 |628 |1024 |675 |1056 |628 |1024 |675 |1040 |651 |-32 |47 |-0.6808510638297872 |-1504 |0 |0 |960 |47 |0 |0 |960 |47 |480 |23.0 |960.0 |47.0 |20.425531914893615 |45120.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**28** |null |Continue with Google |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1291, 339 - 1024, 383) |Rect(0, 0 - 491, 44) |02-06 20:16:04.620 |1291 |339 |1024 |383 |1291 |339 |1024 |383 |1157 |361 |-267 |44 |-6.068181818181818 |-11748 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**29** |null |Continue with Facebook |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1291, 283 - 1024, 327) |Rect(0, 0 - 491, 44) |02-06 20:16:04.620 |1291 |283 |1024 |327 |1291 |283 |1024 |327 |1157 |305 |-267 |44 |-6.068181818181818 |-11748 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[]
***
***
### [Tesseract Backend](https://github.com/hansalemaos/screencap2tesseract2csv)
| **Advantages ✅** | **Disadvantages ❌** |
|---------------------------------------------------------------|----------------------------------------------------------------|
| Detects (in theory) all text on the screen | Higher CPU usage compared to other parsers |
| Works with Unreal Engine and Roblox games | May produce inaccurate results (mostly resolved by fast C++-implemented Levenshtein distance calculation) |
| Can categorize elements (image, text, line, etc.) | Requires additional downloads |
| Undetectable | Needs a screenshot to function |
| Can be used alongside any other parser | — |
***
#### Video - in action
[](https://www.youtube.com/watch?v=bHCQjBHCEvM)
***
#### Python Code
```py
# Imports and instance creation omitted for brevity
df = pd.DataFrame()
# Loop to find the "TikTok" element and click it
while df.empty:
# word_group_limit: groups words within 40 pixels
df = te.get_df_tesseract_fast(with_screenshot=True, word_group_limit=40)
# OCR is often not 100% accurate, so we use double Damerau-Levenshtein distance
# (right-to-left and left-to-right) to improve matching accuracy.
# - First argument: list of strings to locate
# - Second argument: column where the text exists in the DataFrame
# - Third argument: new column name for matched results
# There are 3 methods to get the DataFrame:
# The first time you call one of these methods, the required models will be downloaded automatically:
# - te.get_df_tesseract_fast -> uses models from "https://github.com/tesseract-ocr/tessdata_fast"
# - te.get_df_tesseract -> uses models from "https://github.com/tesseract-ocr/tessdata"
# - te.get_df_tesseract_best -> uses models from "https://github.com/tesseract-ocr/tessdata_best"
df = df.d_fm_damerau_levenshtein_distance_2ways(
["TikTok"], "aa_text", "aa_searchfortext"
).sort_values(by=["damerau_levenshtein_distance_2ways_match"], ascending=False)
# Filter: keeping matches with a Damerau-Levenshtein distance < 2.1
df = df.loc[df["damerau_levenshtein_distance_2ways_match"] < 2.1]
# Perform the tap on the best match
df.aa_input_tap.iloc[0]()
timesleep(2)
# Clear DataFrame for the next interaction
df = pd.DataFrame()
# Loop to find the "Already have an account? Log in" button and click it
while df.empty:
df = te.get_df_tesseract_fast(with_screenshot=True, word_group_limit=40)
df = df.d_fm_damerau_levenshtein_distance_2ways(
["Already have an account? Log in"], "aa_text", "aa_searchfortext"
).sort_values(by=["damerau_levenshtein_distance_2ways_match"], ascending=False)
df = df.loc[df["damerau_levenshtein_distance_2ways_match"] < 2.1]
df.aa_input_tap.iloc[0]()
timesleep(2)
df = pd.DataFrame()
# Loop to find the "Use phone / email / username" button and click it
while df.empty:
df = te.get_df_tesseract_fast(with_screenshot=True, word_group_limit=40)
df = df.d_fm_damerau_levenshtein_distance_2ways(
["Use phone / email / username"], "aa_text", "aa_searchfortext"
).sort_values(by=["damerau_levenshtein_distance_2ways_match"], ascending=False)
df = df.loc[df["damerau_levenshtein_distance_2ways_match"] < 2.1]
df.aa_input_tap.iloc[0]()
timesleep(2)
df = pd.DataFrame()
# Loop to find the "Log in" button and click it
while df.empty:
df = te.get_df_tesseract_fast(with_screenshot=True, word_group_limit=40)
df = df.d_fm_damerau_levenshtein_distance_2ways(
["Log in"],
"aa_text",
"aa_searchfortext", # Tesseract fails to get "Email / Username" text
).sort_values(by=["damerau_levenshtein_distance_2ways_match"], ascending=False)
df = df.loc[df["damerau_levenshtein_distance_2ways_match"] < 2.1]
# Clicking with an offset (90, 50) as Tesseract may miss the light gray "Email / Username" text
df.aa_input_tap.iloc[0](90, 50)
timesleep(2)
# Sending the email input naturally
te.get_cmd_send_text_natural("myemailtest@gmail.com")()
```
***
#### Example of a Pandas DataFrame (column width cropped to 30 chars)
|**index** |**aa_text** |**aa_text_group** |**aa_word** |**aa_title** |**aa_id** |**aa_lang** |**aa_clazz** |**aa_tag** |**aa_bbox** |**aa_baseline** |**aa_poly** |**aa_x_bboxes** |**aa_x_font** |**aa_x_fsize** |**aa_x_size** |**aa_x_ascenders** |**aa_x_descenders** |**aa_x_wconf** |**aa_x_confs** |**aa_x_mpconf** |**aa_line_conf** |**aa_char_conf** |**aa_ppageno** |**aa_block_num** |**aa_par_num** |**aa_line_num** |**aa_word_num** |**aa_image** |**aa_scan_res** |**aa_rotate** |**aa_x_line_bboxes** |**aa_x_line_confs** |**aa_x_text** |**aa_line_index** |**aa_children** |**aa_parents** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_center_x** |**aa_center_y** |**aa_width** |**aa_height** |**aa_area** |**aa_w_h_relation** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |
|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|
|**21** | |-1 | |bbox 413 126 612 149baseline |line_1_5 | |ocr_line | |413 126 612 149 |0 -5 | | | | |23 |5 |5 | | | | | | | | | | | | | | | | |34 |() |() |413 |126 |612 |149 |512 |137 |199 |23 |4577 |8.652174 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**22** |Sign up for TikTok |6 |Sign |bbox 413 126 461 149x_wconf 9|word_1_7 | |ocrx_word | |413 126 461 149 | | | | |24 | | | |96 | | | | | | | | | | | | | | | |35 |() |() |413 |126 |461 |149 |437 |137 |48 |23 |1104 |2.086957 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**23** |Sign up for TikTok |6 |up |bbox 468 131 495 149x_wconf 9|word_1_8 | |ocrx_word | |468 131 495 149 | | | | |24 | | | |94 | | | | | | | | | | | | | | | |36 |() |() |468 |131 |495 |149 |481 |140 |27 |18 |486 |1.5 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[206 206 206] [147 147 147|
|**24** |Sign up for TikTok |6 |for |bbox 502 127 532 144x_wconf 9|word_1_9 | |ocrx_word | |502 127 532 144 | | | | |24 | | | |93 | | | | | | | | | | | | | | | |37 |() |() |502 |127 |532 |144 |517 |135 |30 |17 |510 |1.764706 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**25** |Sign up for TikTok |6 |TikTok |bbox 539 126 612 144x_wconf 9|word_1_10 | |ocrx_word | |539 126 612 144 | | | | |24 | | | |92 | | | | | | | | | | | | | | | |38 |() |() |539 |126 |612 |144 |575 |135 |73 |18 |1314 |4.055556 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**26** | |-1 | |bbox 500 158 742 165 |block_1_6 | |ocr_photo | |500 158 742 165 | | | | | | | | | | | | | | | | | | | | | | | | |42 |() |() |500 |158 |742 |165 |621 |161 |242 |7 |1694 |34.571429 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**27** | |-1 | |bbox 486 169 500 177 |block_1_7 | |ocr_carea | |486 169 500 177 | | | | | | | | | | | | | | | | | | | | | | | | |43 |() |() |486 |169 |500 |177 |493 |173 |14 |8 |112 |1.75 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[251 251 251] [191 191 191|
|**28** | |-1 | |bbox 486 169 500 177 |par_1_6 |eng |ocr_par | |486 169 500 177 | | | | | | | | | | | | | | | | | | | | | | | | |44 |() |() |486 |169 |500 |177 |493 |173 |14 |8 |112 |1.75 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[251 251 251] [191 191 191|
|**29** | |-1 | |bbox 486 169 500 177baseline |line_1_6 | |ocr_line | |486 169 500 177 |0 -6 | | | | |20 |5 |5 | | | | | | | | | | | | | | | | |45 |() |() |486 |169 |500 |177 |493 |173 |14 |8 |112 |1.75 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[251 251 251] [191 191 191|
|**30** |ac file, follow othe |7 |ac |bbox 486 169 500 177x_wconf 8|word_1_11 | |ocrx_word | |486 169 500 177 | | | | |21 | | | |87 | | | | | | | | | | | | | | | |46 |() |() |486 |169 |500 |177 |493 |173 |14 |8 |112 |1.75 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[251 251 251] [191 191 191|
|**31** | |-1 | |bbox 364 166 527 196 |block_1_8 | |ocr_carea | |364 166 527 196 | | | | | | | | | | | | | | | | | | | | | | | | |50 |() |() |364 |166 |527 |196 |445 |181 |163 |30 |4890 |5.433333 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [249 249 249|
|**32** | |-1 | |bbox 364 166 527 196 |par_1_7 |eng |ocr_par | |364 166 527 196 | | | | | | | | | | | | | | | | | | | | | | | | |51 |() |() |364 |166 |527 |196 |445 |181 |163 |30 |4890 |5.433333 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [249 249 249|
|**33** | |-1 | |bbox 364 166 474 177baseline |line_1_7 | |ocr_line | |364 166 474 177 |0 0 | | | | |20 |5 |5 | | | | | | | | | | | | | | | | |52 |() |() |364 |166 |474 |177 |419 |171 |110 |11 |1210 |10.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [249 249 249|
|**34** |ac file, follow othe |7 |file, |bbox 364 169 384 177x_wconf 8|word_1_12 | |ocrx_word | |364 169 384 177 | | | | |21 | | | |89 | | | | | | | | | | | | | | | |53 |() |() |364 |169 |384 |177 |374 |173 |20 |8 |160 |2.5 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[149 149 149] [133 133 133|
|**35** |ac file, follow othe |7 |follow |bbox 396 166 436 177x_wconf 9|word_1_13 | |ocrx_word | |396 166 436 177 | | | | |21 | | | |96 | | | | | | | | | | | | | | | |54 |() |() |396 |166 |436 |177 |416 |171 |40 |11 |440 |3.636364 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [215 215 215|
|**36** |ac file, follow othe |7 |othe |bbox 444 166 474 177x_wconf 9|word_1_14 | |ocrx_word | |444 166 474 177 | | | | |21 | | | |96 | | | | | | | | | | | | | | | |55 |() |() |444 |166 |474 |177 |459 |171 |30 |11 |330 |2.727273 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**37** | |-1 | |bbox 494 188 527 196baseline |line_1_8 | |ocr_line | |494 188 527 196 |0 0 | | | | |20 |5 |5 | | | | | | | | | | | | | | | | |57 |() |() |494 |188 |527 |196 |510 |192 |33 |8 |264 |4.125 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[166 166 166] [219 219 219|
***
***
### [Fragment Parser Backend](https://github.com/hansalemaos/android_fragment_parser)
| **Advantages ✅** | **Disadvantages ❌** |
|---------------------------------------------------------------|----------------------------------------------------------------|
| The fastest of all parsers | Results don’t include the element’s text |
| Very low CPU usage | Sometimes misses elements that UIAutomator-based parsers can detect |
| Can be used alongside any other parser | — |
| Provides useful additional information that other parsers don’t have | — |
| Can find elements that UIAutomator-based parsers can’t detect | — |
| Undetectable | — |
| Highly reliable—never fails | — |
***
#### Video - in action
[](https://www.youtube.com/watch?v=wp7vg15pIMA)
***
#### Python Code
```py
# Imports and instance creation omitted for brevity
df = pd.DataFrame()
# Loop to find and interact with the first target element
while df.empty:
# Many elements in the DataFrame are repeated intentionally to observe parent/child relationships.
# However, with_screenshot=True remains efficient because it crops the numpy arrays only once per element.
df = te.get_df_fragments(with_screenshot=True)
df = df.loc[
(
df.aa_classname
== "com.android.launcher3.views.DoubleShadowBubbleTextView"
)
& (df.aa_rel_width_height > 1)
& (df.aa_clickable == "C")
& (df.aa_drawn == "D")
& (df.aa_enabled == "E")
& (df.aa_focusable == "F")
& (df.aa_long_clickable == "L")
& (df.aa_visibility == "V")
& (df.aa_is_child)
& (df.aa_screenshot.str.len() > 0) # It's a numpy array, but this works as expected
].sort_values(by=["aa_start_y"])
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(10)
while df.empty:
df = te.get_df_fragments(with_screenshot=True)
df = df.loc[
(df.aa_classname == "com.bytedance.tux.input.TuxTextView")
& (df.aa_rel_width_height > 15)
& (df.aa_clickable == "C")
& (df.aa_enabled == "E")
& (df.aa_focusable == "F")
& (df.aa_visibility == "V")
& (df.aa_drawn == "D")
& (df.aa_is_child)
& (df.aa_long_clickable == ".")
& (df.aa_screenshot.str.len() > 0)
].sort_values(by=["aa_start_x", "aa_start_y_relative"])
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(3)
while df.empty:
df = te.get_df_fragments(with_screenshot=True)
df = df.loc[
(df.aa_classname == "com.bytedance.tux.input.TuxTextView")
& (df.aa_rel_width_height > 6)
& (df.aa_rel_width_height < 9)
& (df.aa_enabled == "E")
& (df.aa_visibility == "V")
& (df.aa_drawn == "D")
& (df.aa_clickable == ".")
& (df.aa_focusable == ".")
& (df.aa_is_child)
& (df.aa_long_clickable == ".")
& (df.aa_screenshot.str.len() > 0)
].sort_values(by=["aa_start_y"])
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(3)
while df.empty:
df = te.get_df_fragments(with_screenshot=True)
df = df.loc[
(df.aa_classname == "X.iti")
& (df.aa_rel_width_height > 3)
& (df.aa_rel_width_height < 6)
& (df.aa_enabled == "E")
& (df.aa_visibility == "V")
& (df.aa_drawn == ".")
& (df.aa_clickable == "C")
& (df.aa_focusable == "F")
& (~df.aa_is_child)
& (df.aa_long_clickable == ".")
& (df.aa_screenshot.str.len() > 0)
].sort_values(by=["aa_start_x"], ascending=[False])
df.aa_input_tap.iloc[0]()
timesleep(2)
# Send the email input naturally
te.get_cmd_send_text_natural("myemailtest@gmail.com")()
```
***
#### Example of a Pandas DataFrame (column width cropped to 30 chars)
|**index** |**aa_my_id** |**aa_my_group_id** |**aa_my_element_id** |**aa_my_direct_parent_id** |**aa_my_parent_ids** |**aa_original_string** |**aa_center_x** |**aa_center_y** |**aa_area** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_height** |**aa_width** |**aa_is_sqare** |**aa_rel_width_height** |**aa_hashcode_int** |**aa_mid_int** |**aa_spaces** |**aa_classname** |**aa_element_id** |**aa_hashcode** |**aa_mid** |**aa_start_x_relative** |**aa_end_x_relative** |**aa_start_y_relative** |**aa_end_y_relative** |**aa_clickable** |**aa_context_clickable** |**aa_drawn** |**aa_enabled** |**aa_focusable** |**aa_long_clickable** |**aa_pflag_activated** |**aa_pflag_dirty_mask** |**aa_pflag_focused** |**aa_pflag_hovered** |**aa_pflag_invalidated** |**aa_pflag_is_root_namespace**|**aa_pflag_prepressed** |**aa_pflag_selected** |**aa_scrollbars_horizontal** |**aa_scrollbars_vertical** |**aa_visibility** |**aa_is_child** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |
|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|
|**0** |92 |0 |0 |0 | |android.view.View{7181534 V.ED|512 |752 |32768 |0 |736 |1024 |768 |32 |1024 |0 |32.0 |119018804 |16908336 |8 |android.view.View |android:id/navigationBarBackgr|7181534 |1020030 |0 |1024 |736 |768 |. |. |D |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**1** |91 |1 |0 |0 | |android.view.View{2b0fec9 V.ED|512 |12 |24576 |0 |0 |1024 |24 |24 |1024 |0 |42.666668 |45153993 |16908335 |8 |android.view.View |android:id/statusBarBackground|2b0fec9 |102002f |0 |1024 |0 |24 |. |. |D |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**2** |0 |2 |0 |0 | |android.widget.LinearLayout{2b|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |45420503 |0 |8 |android.widget.LinearLayout | |2b50fd7 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**3** |2 |2 |1 |0 |0, | android.widget.FrameLayout{7|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |131089238 |16908290 |10 |android.widget.FrameLayout |android:id/content |7d04356 |1020002 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**4** |3 |2 |2 |2 |0,2, | X.jTV{c982971 V.E...... ..|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |211298673 |0 |12 |X.jTV | |c982971 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**5** |7 |2 |3 |3 |0,2,3, | android.widget.FrameLayo|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |53721880 |2131435664 |14 |android.widget.FrameLayout |app:id/frl |333bb18 |7f0b2090 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**6** |8 |2 |4 |7 |0,2,3,7, | X.isZ{f77efb V.E......|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |16219899 |2131432044 |16 |X.isZ |app:id/d4r |f77efb |7f0b126c |0 |1024 |24 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**7** |9 |2 |5 |8 |0,2,3,7,8, | android.widget.Relat|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |82542831 |2131446746 |18 |android.widget.RelativeLayout |app:id/nv5 |4eb80ef |7f0b4bda |0 |1024 |0 |712 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**8** |90 |2 |6 |9 |0,2,3,7,8,9 | com.bytedance.tux.|994 |47 |504 |980 |38 |1008 |56 |18 |28 |0 |1.5555556 |194303692 |2131448536 |20 |com.bytedance.tux.input.TuxTex|app:id/p6i |b94d6cc |7f0b52d8 |980 |1008 |14 |32 |C |. |D |E |F |. |. |. |. |. |. |. |. |. |. |. |V |True |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**9** |0 |3 |0 |0 | |android.widget.LinearLayout{2b|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |45420503 |0 |8 |android.widget.LinearLayout | |2b50fd7 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**10** |2 |3 |1 |0 |0, | android.widget.FrameLayout{7|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |131089238 |16908290 |10 |android.widget.FrameLayout |android:id/content |7d04356 |1020002 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**11** |3 |3 |2 |2 |0,2, | X.jTV{c982971 V.E...... ..|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |211298673 |0 |12 |X.jTV | |c982971 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**12** |7 |3 |3 |3 |0,2,3, | android.widget.FrameLayo|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |53721880 |2131435664 |14 |android.widget.FrameLayout |app:id/frl |333bb18 |7f0b2090 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**13** |8 |3 |4 |7 |0,2,3,7, | X.isZ{f77efb V.E......|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |16219899 |2131432044 |16 |X.isZ |app:id/d4r |f77efb |7f0b126c |0 |1024 |24 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**14** |9 |3 |5 |8 |0,2,3,7,8, | android.widget.Relat|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |82542831 |2131446746 |18 |android.widget.RelativeLayout |app:id/nv5 |4eb80ef |7f0b4bda |0 |1024 |0 |712 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**15** |89 |3 |6 |9 |0,2,3,7,8,9 | com.bytedance.tux.|0 |24 |0 |0 |24 |0 |24 |0 |0 |1 |0.0 |134974938 |2131451338 |20 |com.bytedance.tux.icon.TuxIcon|app:id/r8_ |80b8dda |7f0b5dca |0 |0 |0 |0 |. |. |D |E |. |. |. |. |. |. |I |. |. |. |. |. |G |True |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |
|**16** |0 |4 |0 |0 | |android.widget.LinearLayout{2b|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |45420503 |0 |8 |android.widget.LinearLayout | |2b50fd7 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**17** |2 |4 |1 |0 |0, | android.widget.FrameLayout{7|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |131089238 |16908290 |10 |android.widget.FrameLayout |android:id/content |7d04356 |1020002 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**18** |3 |4 |2 |2 |0,2, | X.jTV{c982971 V.E...... ..|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |211298673 |0 |12 |X.jTV | |c982971 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**19** |7 |4 |3 |3 |0,2,3, | android.widget.FrameLayo|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |53721880 |2131435664 |14 |android.widget.FrameLayout |app:id/frl |333bb18 |7f0b2090 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**20** |8 |4 |4 |7 |0,2,3,7, | X.isZ{f77efb V.E......|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |16219899 |2131432044 |16 |X.isZ |app:id/d4r |f77efb |7f0b126c |0 |1024 |24 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**21** |9 |4 |5 |8 |0,2,3,7,8, | android.widget.Relat|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |82542831 |2131446746 |18 |android.widget.RelativeLayout |app:id/nv5 |4eb80ef |7f0b4bda |0 |1024 |0 |712 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**22** |88 |4 |6 |9 |0,2,3,7,8,9 | com.bytedance.tux.|28 |50 |2304 |4 |26 |52 |74 |48 |48 |1 |1.0 |13215999 |2131451307 |20 |com.bytedance.tux.icon.TuxIcon|app:id/r7f |c9a8ff |7f0b5dab |4 |52 |2 |50 |C |. |D |E |F |. |. |. |. |. |. |. |. |. |. |. |V |True |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**23** |0 |5 |0 |0 | |android.widget.LinearLayout{2b|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |45420503 |0 |8 |android.widget.LinearLayout | |2b50fd7 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**24** |2 |5 |1 |0 |0, | android.widget.FrameLayout{7|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |131089238 |16908290 |10 |android.widget.FrameLayout |android:id/content |7d04356 |1020002 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**25** |3 |5 |2 |2 |0,2, | X.jTV{c982971 V.E...... ..|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |211298673 |0 |12 |X.jTV | |c982971 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**26** |7 |5 |3 |3 |0,2,3, | android.widget.FrameLayo|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |53721880 |2131435664 |14 |android.widget.FrameLayout |app:id/frl |333bb18 |7f0b2090 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**27** |8 |5 |4 |7 |0,2,3,7, | X.isZ{f77efb V.E......|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |16219899 |2131432044 |16 |X.isZ |app:id/d4r |f77efb |7f0b126c |0 |1024 |24 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**28** |9 |5 |5 |8 |0,2,3,7,8, | android.widget.Relat|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |82542831 |2131446746 |18 |android.widget.RelativeLayout |app:id/nv5 |4eb80ef |7f0b4bda |0 |1024 |0 |712 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**29** |12 |5 |6 |9 |0,2,3,7,8,9, | android.widget.Lin|512 |406 |674816 |0 |77 |1024 |736 |659 |1024 |0 |1.5538695 |219162762 |2131448421 |20 |android.widget.LinearLayout |app:id/p3e |d10288a |7f0b5265 |0 |1024 |53 |712 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
***
***
### [UIAutomator Classic Backend](https://github.com/hansalemaos/uiautomator_dump_to_csv)
| **Advantages ✅** | **Disadvantages ❌** |
|---------------------------------------------------------------|----------------------------------------------------------------|
| Includes both element text and description | Higher CPU usage compared to UIAutomator2 |
| Undetectable | May fail (idle state error) if there’s too much activity on the screen |
| Can be used alongside any other parser (except UIAutomator2) | — |
***
#### Video - in action
[](https://www.youtube.com/watch?v=B6-dOK2YiYc)
***
#### Python Code
```py
# Imports and instance creation omitted for brevity
df = pd.DataFrame()
while df.empty:
df = te.get_df_uiautomator_classic(with_screenshot=True)
df = df.loc[
(df.aa_text == "TikTok")
& (df.aa_content_desc == "TikTok")
& (df.aa_clickable == 1)
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(10)
while df.empty:
df = te.get_df_uiautomator_classic(with_screenshot=True)
df = df.loc[
(df.aa_text == "Already have an account? Log in")
& (df.aa_clazz == "android.widget.Button")
& (df.aa_content_desc == "")
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(3)
while df.empty:
df = te.get_df_uiautomator_classic(with_screenshot=True)
df = df.loc[
(df.aa_text == "Use phone / email / username")
& (df.aa_clazz == "android.widget.TextView")
& (df.aa_content_desc == "")
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(3)
while df.empty:
df = te.get_df_uiautomator_classic(with_screenshot=True)
df = df.loc[
(df.aa_text == "Email / Username")
& (df.aa_clazz == "android.widget.TextView")
& (df.aa_content_desc == "")
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(2)
te.get_cmd_send_text_natural("myemailtest@gmail.com")()
```
***
#### Example of a Pandas DataFrame (column width cropped to 30 chars)
|**index** |**aa_bounds** |**aa_text** |**aa_package** |**aa_resource_id** |**aa_clazz** |**aa_content_desc** |**aa_center_x** |**aa_center_y** |**aa_area** |**aa_width** |**aa_height** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_is_square** |**aa_w_h_relation** |**aa_checkable** |**aa_checked** |**aa_clickable** |**aa_enabled** |**aa_focusable** |**aa_focused** |**aa_index** |**aa_long_clickable** |**aa_password** |**aa_scrollable** |**aa_selected** |**aa_naf** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |
|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|
|**0** |[0,0][1024,768] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |384 |786432 |1024 |768 |0 |0 |1024 |768 |0 |1.3333334 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**1** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.LinearLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**2** |[0,0][1024,736] | |com.zhiliaoapp.musically |android:id/content |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**3** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**4** |[0,0][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/tq|android.widget.LinearLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**5** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**6** |[0,0][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/fr|android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**7** |[0,24][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/d4|android.view.ViewGroup | |512 |380 |729088 |1024 |712 |0 |24 |1024 |736 |0 |1.4382023 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**8** |[0,24][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/nv|android.widget.RelativeLayout | |512 |380 |729088 |1024 |712 |0 |24 |1024 |736 |0 |1.4382023 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**9** |[4,26][52,74] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/r7|android.widget.ImageView |Report a problem |28 |50 |2304 |48 |48 |4 |26 |52 |74 |1 |1.0 |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**10** |[980,38][1008,56] |Skip |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p6|android.widget.Button | |994 |47 |504 |28 |18 |980 |38 |1008 |56 |0 |1.5555556 |0 |0 |1 |1 |1 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**11** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p3|android.widget.LinearLayout | |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |0 |0 |4 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**12** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/tt|androidx.viewpager.widget.View| |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |1 |0 |0 |0 |0 |1 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**13** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p3|android.view.ViewGroup | |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**14** |[30,77][994,628] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.view.ViewGroup | |512 |352 |531164 |964 |551 |30 |77 |994 |628 |0 |1.7495463 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**15** |[267,77][758,396] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|androidx.recyclerview.widget.R| |512 |236 |156629 |491 |319 |267 |77 |758 |396 |0 |1.5391849 |0 |0 |0 |1 |1 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**16** |[267,82][758,228] | |com.zhiliaoapp.musically | |android.widget.LinearLayout | |512 |155 |71686 |491 |146 |267 |82 |758 |228 |0 |3.3630137 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**17** |[267,122][758,150] |Sign up for TikTok |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/ti|android.widget.TextView | |512 |136 |13748 |491 |28 |267 |122 |758 |150 |0 |17.535715 |0 |0 |0 |1 |0 |0 |0 |1 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**18** |[267,162][758,200] |Create a profile, follow other|com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/oe|android.widget.TextView | |512 |181 |18658 |491 |38 |267 |162 |758 |200 |0 |12.921053 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**19** |[267,228][758,272] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Use phone or email |512 |250 |21604 |491 |44 |267 |228 |758 |272 |0 |11.159091 |0 |0 |1 |1 |1 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**20** |[279,238][303,262] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |250 |576 |24 |24 |279 |238 |303 |262 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**21** |[454,241][593,260] |Use phone or email |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |523 |250 |2641 |139 |19 |454 |241 |593 |260 |0 |7.3157897 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**22** |[267,284][758,328] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Continue with Facebook |512 |306 |21604 |491 |44 |267 |284 |758 |328 |0 |11.159091 |0 |0 |1 |1 |1 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**23** |[279,294][303,318] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |306 |576 |24 |24 |279 |294 |303 |318 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**24** |[437,297][611,316] |Continue with Facebook |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |524 |306 |3306 |174 |19 |437 |297 |611 |316 |0 |9.157895 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**25** |[267,340][758,384] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Continue with Google |512 |362 |21604 |491 |44 |267 |340 |758 |384 |0 |11.159091 |0 |0 |1 |1 |1 |0 |3 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**26** |[279,350][303,374] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |362 |576 |24 |24 |279 |350 |303 |374 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**27** |[445,353][602,371] |Continue with Google |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |523 |362 |2826 |157 |18 |445 |353 |602 |371 |0 |8.722222 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**28** |[32,628][992,675] |By continuing with an account |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/rw|android.widget.TextView | |512 |651 |45120 |960 |47 |32 |628 |992 |675 |0 |20.425531 |0 |0 |0 |1 |1 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**29** |[0,675][1024,676] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/dx|android.view.View | |512 |675 |1024 |1024 |1 |0 |675 |1024 |676 |0 |1024.0 |0 |0 |0 |1 |0 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[228 228 229] [228 228 229|
***
***
### [UIAutomator with CPU Limit Backend](https://github.com/hansalemaos/uiautomator_dump_without_could_not_detect_idle_state)
| **Advantages ✅** | **Disadvantages ❌** |
|---------------------------------------------------------------|----------------------------------------------------------------|
| Includes both element text and description | Higher CPU usage compared to UIAutomator2 |
| Undetectable | May fail (null root node returned by UiTestAutomationBridge) if the CPU usage of the top window is limited too much |
| Can be used alongside any other parser (except UIAutomator2) | — |
| No idle state errors when used correctly | — |
***
#### Video - in action
[](https://www.youtube.com/watch?v=eEhB7U110fg)
***
#### Python Code
```py
# Imports and instance creation omitted for brevity
df = pd.DataFrame()
while df.empty:
# If cpu_limit is not passed, the value from the TermuxAutomation instance is used
df = te.get_df_uiautomator_with_cpu_limit(with_screenshot=True)
df = df.loc[
(df.aa_text == "TikTok")
& (df.aa_content_desc == "TikTok")
& (df.aa_clickable == 1)
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(10)
while df.empty:
df = te.get_df_uiautomator_with_cpu_limit(with_screenshot=True, cpu_limit=14)
df = df.loc[
(df.aa_text == "Already have an account? Log in")
& (df.aa_clazz == "android.widget.Button")
& (df.aa_content_desc == "")
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(3)
while df.empty:
df = te.get_df_uiautomator_with_cpu_limit(with_screenshot=True, cpu_limit=13)
df = df.loc[
(df.aa_text == "Use phone / email / username")
& (df.aa_clazz == "android.widget.TextView")
& (df.aa_content_desc == "")
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(3)
while df.empty:
df = te.get_df_uiautomator_with_cpu_limit(with_screenshot=True, cpu_limit=16)
df = df.loc[
(df.aa_text == "Email / Username")
& (df.aa_clazz == "android.widget.TextView")
& (df.aa_content_desc == "")
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(2)
te.get_cmd_send_text_natural("myemailtest@gmail.com")()
```
***
#### Example of a Pandas DataFrame (column width cropped to 30 chars)
|**index** |**aa_bounds** |**aa_text** |**aa_package** |**aa_resource_id** |**aa_clazz** |**aa_content_desc** |**aa_center_x** |**aa_center_y** |**aa_area** |**aa_width** |**aa_height** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_is_square** |**aa_w_h_relation** |**aa_checkable** |**aa_checked** |**aa_clickable** |**aa_enabled** |**aa_focusable** |**aa_focused** |**aa_index** |**aa_long_clickable** |**aa_password** |**aa_scrollable** |**aa_selected** |**aa_naf** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |
|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|
|**0** |[0,0][1024,768] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |384 |786432 |1024 |768 |0 |0 |1024 |768 |0 |1.3333334 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**1** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.LinearLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**2** |[0,0][1024,736] | |com.zhiliaoapp.musically |android:id/content |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**3** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**4** |[0,0][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/tq|android.widget.LinearLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**5** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**6** |[0,0][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/fr|android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**7** |[0,24][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/d4|android.view.ViewGroup | |512 |380 |729088 |1024 |712 |0 |24 |1024 |736 |0 |1.4382023 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**8** |[0,24][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/nv|android.widget.RelativeLayout | |512 |380 |729088 |1024 |712 |0 |24 |1024 |736 |0 |1.4382023 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**9** |[4,26][52,74] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/r7|android.widget.ImageView |Report a problem |28 |50 |2304 |48 |48 |4 |26 |52 |74 |1 |1.0 |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**10** |[980,38][1008,56] |Skip |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p6|android.widget.Button | |994 |47 |504 |28 |18 |980 |38 |1008 |56 |0 |1.5555556 |0 |0 |1 |1 |1 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**11** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p3|android.widget.LinearLayout | |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |0 |0 |4 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**12** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/tt|androidx.viewpager.widget.View| |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |1 |0 |0 |0 |0 |1 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**13** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p3|android.view.ViewGroup | |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**14** |[30,77][994,628] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.view.ViewGroup | |512 |352 |531164 |964 |551 |30 |77 |994 |628 |0 |1.7495463 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**15** |[267,77][758,396] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|androidx.recyclerview.widget.R| |512 |236 |156629 |491 |319 |267 |77 |758 |396 |0 |1.5391849 |0 |0 |0 |1 |1 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**16** |[267,82][758,228] | |com.zhiliaoapp.musically | |android.widget.LinearLayout | |512 |155 |71686 |491 |146 |267 |82 |758 |228 |0 |3.3630137 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**17** |[267,122][758,150] |Sign up for TikTok |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/ti|android.widget.TextView | |512 |136 |13748 |491 |28 |267 |122 |758 |150 |0 |17.535715 |0 |0 |0 |1 |0 |0 |0 |1 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**18** |[267,162][758,200] |Create a profile, follow other|com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/oe|android.widget.TextView | |512 |181 |18658 |491 |38 |267 |162 |758 |200 |0 |12.921053 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**19** |[267,228][758,272] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Use phone or email |512 |250 |21604 |491 |44 |267 |228 |758 |272 |0 |11.159091 |0 |0 |1 |1 |1 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**20** |[279,238][303,262] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |250 |576 |24 |24 |279 |238 |303 |262 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**21** |[454,241][593,260] |Use phone or email |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |523 |250 |2641 |139 |19 |454 |241 |593 |260 |0 |7.3157897 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**22** |[267,284][758,328] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Continue with Facebook |512 |306 |21604 |491 |44 |267 |284 |758 |328 |0 |11.159091 |0 |0 |1 |1 |1 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**23** |[279,294][303,318] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |306 |576 |24 |24 |279 |294 |303 |318 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**24** |[437,297][611,316] |Continue with Facebook |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |524 |306 |3306 |174 |19 |437 |297 |611 |316 |0 |9.157895 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**25** |[267,340][758,384] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Continue with Google |512 |362 |21604 |491 |44 |267 |340 |758 |384 |0 |11.159091 |0 |0 |1 |1 |1 |0 |3 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**26** |[279,350][303,374] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |362 |576 |24 |24 |279 |350 |303 |374 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**27** |[445,353][602,371] |Continue with Google |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |523 |362 |2826 |157 |18 |445 |353 |602 |371 |0 |8.722222 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**28** |[32,628][992,675] |By continuing with an account |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/rw|android.widget.TextView | |512 |651 |45120 |960 |47 |32 |628 |992 |675 |0 |20.425531 |0 |0 |0 |1 |1 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|
|**29** |[0,675][1024,676] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/dx|android.view.View | |512 |675 |1024 |1024 |1 |0 |675 |1024 |676 |0 |1024.0 |0 |0 |0 |1 |0 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[228 228 229] [228 228 229|
***
***
### Window Dump Backend
| **Advantages ✅** | **Disadvantages ❌** |
|---------------------------------------------------------------|----------------------------------------------------------------|
| Very fast parser | Results don’t include the element’s text |
| Very low CPU usage | Doesn’t work everywhere (e.g., the start page of the launcher) |
| Can be used alongside any other parser | — |
| Provides lots of additional information that other parsers don’t have | — |
| Can find elements that UIAutomator-based parsers can’t detect | — |
| Undetectable | — |
***
#### Video - in action
[](https://www.youtube.com/watch?v=gcjsfM1AJps)
***
#### Python Code
```py
# We need to open a shell and start the app using the am command because
# the parser doesn’t work on the launcher’s start page
myshell = te.open_shell()
myshell.sh_force_open_app("com.zhiliaoapp.musically", 3)
timesleep(10)
df = pd.DataFrame()
while df.empty:
df = te.get_df_window_dump(with_screenshot=True)
# Provides lots of additional information no other parser has
# (pivot points, font size, font weight, etc.)
df = df.loc[
(df["aa_text_scaledTextSize"] == 12) & (df.aa_end_x <= te.screen_width)
]
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(2)
while df.empty:
df = te.get_df_window_dump(with_screenshot=True)
df = df.loc[
(df["aa_text_scaledTextSize"] == 14) & (df.aa_end_x <= te.screen_width)
].sort_values(by=["aa_start_y"])
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(2)
while df.empty:
df = te.get_df_window_dump(with_screenshot=True)
df = df.loc[
(df["aa_accessibility_labelFor"] == -1)
& (df["aa_topMargin"] == 0)
& (df["aa_layout_gravity"] == -1)
& (df["aa_layout_left"] > 0)
& (df["aa_layout_left"] < 20)
].sort_values(by=["aa_start_x"], ascending=[False])
df.aa_input_tap.iloc[0]()
df = pd.DataFrame()
timesleep(2)
te.get_cmd_send_text_natural("myemailtest@gmail.com")()
```
***
#### Example of a Pandas DataFrame (column width cropped to 50 chars)
|**index** |**aa_window_left** |**aa_window_top** |**aa_meta___name__** |**aa_meta___hash__** |**aa_id** |**aa_misc_transformation.alpha** |**aa_misc_transitionName** |**aa_layout_left** |**aa_layout_right** |**aa_layout_top** |**aa_layout_bottom** |**aa_layout_width** |**aa_layout_height** |**aa_layout_layoutDirection** |**aa_layout_layoutRtl** |**aa_layout_hasTransientState** |**aa_layout_baseline** |**aa_layoutParams** |**aa_y** |**aa_horizontalWeight** |**aa_verticalWeight** |**aa_type** |**aa_flags** |**aa_scrolling_scrollX** |**aa_scrolling_scrollY** |**aa_padding_paddingLeft** |**aa_padding_paddingRight** |**aa_padding_paddingTop** |**aa_padding_paddingBottom** |**aa_padding_userPaddingRight** |**aa_padding_userPaddingLeft** |**aa_padding_userPaddingBottom** |**aa_padding_userPaddingStart** |**aa_padding_userPaddingEnd** |**aa_measurement_minHeight** |**aa_measurement_minWidth** |**aa_measurement_measuredWidth** |**aa_measurement_measuredHeight** |**aa_drawing_elevation** |**aa_drawing_translationX** |**aa_drawing_translationY** |**aa_drawing_translationZ** |**aa_drawing_rotation** |**aa_drawing_rotationX** |**aa_drawing_rotationY** |**aa_drawing_scaleX** |**aa_drawing_scaleY** |**aa_drawing_pivotX** |**aa_drawing_pivotY** |**aa_drawing_clipBounds** |**aa_drawing_opaque** |**aa_drawing_alpha** |**aa_drawing_transitionAlpha** |**aa_drawing_shadow** |**aa_drawing_solidColor** |**aa_drawing_layerType** |**aa_drawing_willNotDraw** |**aa_drawing_hardwareAccelerated** |**aa_drawing_willNotCacheDrawing** |**aa_drawing_drawingCacheEnabled** |**aa_drawing_overlappingRendering** |**aa_drawing_outlineAmbientShadowColor** |**aa_drawing_outlineSpotShadowColor** |**aa_focus_hasFocus** |**aa_focus_isFocused** |**aa_focus_focusable** |**aa_focus_isFocusable** |**aa_focus_isFocusableInTouchMode** |**aa_misc_clickable** |**aa_misc_pressed** |**aa_misc_selected** |**aa_misc_touchMode** |**aa_misc_hovered** |**aa_misc_activated** |**aa_misc_visibility** |**aa_misc_fitsSystemWindows** |**aa_misc_filterTouchesWhenObscured** |**aa_misc_enabled** |**aa_misc_soundEffectsEnabled** |**aa_misc_hapticFeedbackEnabled** |**aa_theme** |**aa_meta___attrCount__** |**aa_misc_scrollBarStyle** |**aa_text_textDirection** |**aa_text_textAlignment** |**aa_accessibility_labelFor** |**aa_accessibility_importantForAccessibility** |**aa_focus_descendantFocusability** |**aa_drawing_clipChildren** |**aa_drawing_clipToPadding** |**aa_drawing_childrenDrawingOrderEnabled** |**aa_drawing_persistentDrawingCache** |**aa_meta___childCount__** |**aa_CHILD_META** |**aa_aa_hashcode_int** |**aa_bottomMargin** |**aa_endMargin** |**aa_height** |**aa_layout_alignWithParent** |**aa_layout_baselineAligned** |**aa_layout_baselineAlignedChildIndex** |**aa_layout_gravity** |**aa_layout_totalLength** |**aa_layout_useLargestChild** |**aa_layout_weight** |**aa_leftMargin** |**aa_measurement_baselineChildTop** |**aa_measurement_gravity** |**aa_measurement_measureAllChildren** |**aa_measurement_orientation** |**aa_measurement_totalLength** |**aa_meta___child__0** |**aa_meta___child__1** |**aa_meta___child__2** |**aa_meta___child__3** |**aa_meta___child__4** |**aa_meta___child__5** |**aa_meta___child__6** |**aa_meta___child__7** |**aa_meta___child__8** |**aa_padding_foregroundPaddingBottom** |**aa_padding_foregroundPaddingLeft** |**aa_padding_foregroundPaddingRight** |**aa_padding_foregroundPaddingTop** |**aa_rightMargin** |**aa_startMargin** |**aa_text_curTextColor** |**aa_text_ellipsize** |**aa_text_gravity** |**aa_text_scaledTextSize** |**aa_text_selectionEnd** |**aa_text_selectionStart** |**aa_text_textSize** |**aa_text_typefaceStyle** |**aa_topMargin** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_center_x** |**aa_center_y** |**aa_window_name** |**aa_hashcode_hex** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |
|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|
|**0** |0 |0.0 |com.android.internal.policy.DecorView |192145870.0 |NO_ID |0.0 | |0 |1024 |0 |768 |1024 |768 |0 |False |False |-1 |(3, 'android.view.WindowManager$LayoutParams', 4, |0.0 |0.0 |0.0 |1.0 |-2122252030.0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |-2147483648 |-2147483648 |0 |0 |1024 |768 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |512.0 |384.0 | |False |1.0 |1.0 |False |0 |0 |True |True |False |False |True |-16777216 |-16777216 |False |False |16 |False |False |False |False |False |True |False |False |0 |False |False |True |True |True |(3, 'android.content.res.Resources$Theme', 4, 5365|0 |0 |1 |1 |-1 |1 |262144 |True |True |False |2 |3 |None |nan |nan |nan |None |None |None |nan |nan |nan |None |nan |nan |nan |nan |None |nan |nan |None |None |None |None |None |None |None |None |None |nan |nan |nan |nan |nan |nan |nan |None |nan |nan |nan |nan |nan |nan |nan |-1 |-1 |-1 |-1 |-1 |-1 |a57b656 com.zhiliaoapp.musically/com.ss.android.ug|-1 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, action=0, event_multiply=|[] |
|**1** |None |nan |None |nan |None |nan | |0 |1024 |0 |736 |1024 |736 |0 |False |False |-1 |(3, 'android.widget.FrameLayout$LayoutParams', 4, |nan |nan |nan |nan |nan |0 |0 |0 |0 |0 |0 |0 |0 |0 |-2147483648 |-2147483648 |0 |0 |1024 |736 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |512.0 |368.0 | |False |1.0 |1.0 |False |0 |0 |True |True |False |False |True |-16777216 |-16777216 |False |False |16 |False |False |False |False |False |True |False |False |0 |True |False |True |True |True |(3, 'android.content.res.Resources$Theme', 4, 1907|0 |0 |1 |1 |-1 |0 |131072 |True |True |False |2 |2 |('meta:__child__0', 3, 'android.widget.LinearLayou|45420503.0 |32.0 |-2147483648.0 |None |None |None |nan |nan |nan |None |nan |nan |nan |nan |None |nan |nan |None |None |None |None |None |None |None |None |None |nan |nan |nan |nan |0.0 |-2147483648.0 |nan |None |nan |nan |nan |nan |nan |nan |0.0 |0 |0 |1024 |736 |512 |368 |a57b656 com.zhiliaoapp.musically/com.ss.android.ug|2b50fd7 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, action=0, event_multiply=|[[[255 255 255] [255 255 255] [255 255 255] |
|**2** |None |nan |None |nan |None |nan | |0 |1024 |0 |736 |1024 |736 |0 |False |False |-1 |(3, 'android.widget.LinearLayout$LayoutParams', 4,|nan |nan |nan |nan |nan |0 |0 |0 |0 |0 |0 |0 |0 |0 |-2147483648 |-2147483648 |0 |0 |1024 |736 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |512.0 |368.0 | |False |1.0 |1.0 |False |0 |0 |True |True |False |False |True |-16777216 |-16777216 |False |False |16 |False |False |False |False |False |True |False |False |0 |False |False |True |True |True |(3, 'android.content.res.Resources$Theme', 4, 1907|0 |0 |1 |1 |-1 |0 |131072 |True |True |False |2 |1 |('meta:__child__0', 3, 'android.view.ViewStub', 4,|99812585.0 |0.0 |-2147483648.0 |None |None |None |nan |-1.0 |nan |None |0.0 |nan |nan |nan |None |nan |nan |None |(3, 'android.widget.FrameLayout', 4, 131089238, 5,|None |None |None |None |None |None |None |nan |nan |nan |nan |0.0 |-2147483648.0 |nan |None |nan |nan |nan |nan |nan |nan |0.0 |0 |0 |0 |0 |0 |0 |a57b656 com.zhiliaoapp.musically/com.ss.android.ug|5f304e9 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, action=0, event_multiply=|[] |
|**3** |None |nan |None |nan |None |nan | |0 |1024 |0 |736 |1024 |736 |0 |False |False |-1 |(3, 'android.widget.FrameLayout$LayoutParams', 4, |nan |nan |nan |nan |nan |0 |0 |0 |0 |0 |0 |0 |0 |0 |-2147483648 |-2147483648 |0 |0 |1024 |736 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |512.0 |368.0 | |False |1.0 |1.0 |False |0 |0 |True |True |False |False |True |-16777216 |-16777216 |False |False |16 |False |False |False |False |False |True |False |False |0 |False |False |True |True |True |(3, 'android.content.res.Resources$Theme', 4, 1907|0 |0 |1 |1 |-1 |0 |131072 |True |True |False |2 |2 |('meta:__child__0', 3, 'X.jTV', 4, 211298673, 5, '|211298673.0 |0.0 |-2147483648.0 |None |None |None |nan |nan |nan |None |nan |nan |nan |nan |None |nan |nan |None |None |None |None |None |None |None |None |None |nan |nan |nan |nan |0.0 |-2147483648.0 |nan |None |nan |nan |nan |nan |nan |nan |0.0 |0 |0 |1024 |736 |512 |368 |a57b656 com.zhiliaoapp.musically/com.ss.android.ug|c982971 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, action=0, event_multiply=|[[[255 255 255] [255 255 255] [255 255 255] |
***
***
## Color Search
### If you decide to add a screenshot to your DataFrame, you can perform a very fast color search (uses C++ vectors and structs for the results internally).
```py
# Pass RGB colors and the name of the column
df.bb_search_for_colors([[255, 255, 255], [0, 0, 0]], result_column="white_and_black")
# An new column will be added
df.white_and_black
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
iloc | index | white_and_black |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 | 0 | [{'x': 140, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 141, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 142, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 143, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 144, 'y': 65, 'count': 20 |
1 | 1 | [{'x': 140, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 141, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 142, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 143, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 144, 'y': 65, 'count': 20 |
2 | 2 | [{'x': 140, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 141, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 142, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 143, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 144, 'y': 65, 'count': 20 |
3 | 3 | [{'x': 128, 'y': 100, 'count': 4811, 'r': 255, 'g': 255, 'b': 255}, {'x': 129, 'y': 100, 'count': 4811, 'r': 255, 'g': 255, 'b': 255}, {'x': 130, 'y': 100, 'count': 4811, 'r': 255, 'g': 255, 'b': 255}, {'x': 131, 'y': 100, 'count': 4811, 'r': 255, 'g': 255, 'b': 255}, {'x': 132, 'y': 100, 'count': 4 |
4 | 4 | [{'x': 128, 'y': 100, 'count': 665, 'r': 255, 'g': 255, 'b': 255}, {'x': 129, 'y': 100, 'count': 665, 'r': 255, 'g': 255, 'b': 255}, {'x': 130, 'y': 100, 'count': 665, 'r': 255, 'g': 255, 'b': 255}, {'x': 131, 'y': 100, 'count': 665, 'r': 255, 'g': 255, 'b': 255}, {'x': 132, 'y': 100, 'count': 665, |
5 | 5 | [{'x': 248, 'y': 100, 'count': 1717, 'r': 255, 'g': 255, 'b': 255}, {'x': 249, 'y': 100, 'count': 1717, 'r': 255, 'g': 255, 'b': 255}, {'x': 250, 'y': 100, 'count': 1717, 'r': 255, 'g': 255, 'b': 255}, {'x': 251, 'y': 100, 'count': 1717, 'r': 255, 'g': 255, 'b': 255}, {'x': 252, 'y': 100, 'count': 1 |
6 | 6 | [{'x': 470, 'y': 100, 'count': 830, 'r': 255, 'g': 255, 'b': 255}, {'x': 471, 'y': 100, 'count': 830, 'r': 255, 'g': 255, 'b': 255}, {'x': 472, 'y': 100, 'count': 830, 'r': 255, 'g': 255, 'b': 255}, {'x': 473, 'y': 100, 'count': 830, 'r': 255, 'g': 255, 'b': 255}, {'x': 474, 'y': 100, 'count': 830, |
7 | 7 | [{'x': 117, 'y': 412, 'count': 311, 'r': 255, 'g': 255, 'b': 255}, {'x': 118, 'y': 412, 'count': 311, 'r': 255, 'g': 255, 'b': 255}, {'x': 119, 'y': 412, 'count': 311, 'r': 255, 'g': 255, 'b': 255}, {'x': 118, 'y': 413, 'count': 311, 'r': 255, 'g': 255, 'b': 255}, {'x': 119, 'y': 413, 'count': 311, |
8 | 8 | [{'x': 339, 'y': 412, 'count': 402, 'r': 255, 'g': 255, 'b': 255}, {'x': 340, 'y': 412, 'count': 402, 'r': 255, 'g': 255, 'b': 255}, {'x': 341, 'y': 412, 'count': 402, 'r': 255, 'g': 255, 'b': 255}, {'x': 340, 'y': 413, 'count': 402, 'r': 255, 'g': 255, 'b': 255}, {'x': 341, 'y': 413, 'count': 402, |
9 | 9 | [{'x': 568, 'y': 497, 'count': 62, 'r': 255, 'g': 255, 'b': 255}, {'x': 569, 'y': 497, 'count': 62, 'r': 255, 'g': 255, 'b': 255}, {'x': 580, 'y': 497, 'count': 62, 'r': 255, 'g': 255, 'b': 255}, {'x': 589, 'y': 497, 'count': 62, 'r': 255, 'g': 255, 'b': 255}, {'x': 597, 'y': 497, 'count': 62, 'r': |
10 | 10 | [{'x': 151, 'y': 729, 'count': 197, 'r': 255, 'g': 255, 'b': 255}, {'x': 152, 'y': 729, 'count': 197, 'r': 255, 'g': 255, 'b': 255}, {'x': 85, 'y': 730, 'count': 197, 'r': 255, 'g': 255, 'b': 255}, {'x': 86, 'y': 730, 'count': 197, 'r': 255, 'g': 255, 'b': 255}, {'x': 149, 'y': 730, 'count': 197, 'r |
11 | 11 | [{'x': 362, 'y': 638, 'count': 627, 'r': 255, 'g': 255, 'b': 255}, {'x': 363, 'y': 638, 'count': 627, 'r': 255, 'g': 255, 'b': 255}, {'x': 364, 'y': 638, 'count': 627, 'r': 255, 'g': 255, 'b': 255}, {'x': 365, 'y': 638, 'count': 627, 'r': 255, 'g': 255, 'b': 255}, {'x': 366, 'y': 638, 'count': 627, |
12 | 12 | [{'x': 140, 'y': 65, 'count': 17610, 'r': 255, 'g': 255, 'b': 255}, {'x': 141, 'y': 65, 'count': 17610, 'r': 255, 'g': 255, 'b': 255}, {'x': 142, 'y': 65, 'count': 17610, 'r': 255, 'g': 255, 'b': 255}, {'x': 143, 'y': 65, 'count': 17610, 'r': 255, 'g': 255, 'b': 255}, {'x': 144, 'y': 65, 'count': 17 |
13 | 13 | [{'x': 136, 'y': 77, 'count': 100, 'r': 255, 'g': 255, 'b': 255}, {'x': 141, 'y': 77, 'count': 100, 'r': 255, 'g': 255, 'b': 255}, {'x': 142, 'y': 77, 'count': 100, 'r': 255, 'g': 255, 'b': 255}, {'x': 143, 'y': 77, 'count': 100, 'r': 255, 'g': 255, 'b': 255}, {'x': 144, 'y': 77, 'count': 100, 'r': |
14 | 14 | [{'x': 150, 'y': 65, 'count': 15852, 'r': 255, 'g': 255, 'b': 255}, {'x': 151, 'y': 65, 'count': 15852, 'r': 255, 'g': 255, 'b': 255}, {'x': 152, 'y': 65, 'count': 15852, 'r': 255, 'g': 255, 'b': 255}, {'x': 153, 'y': 65, 'count': 15852, 'r': 255, 'g': 255, 'b': 255}, {'x': 154, 'y': 65, 'count': 15 |
15 | 15 | [{'x': 568, 'y': 77, 'count': 177, 'r': 255, 'g': 255, 'b': 255}, {'x': 569, 'y': 77, 'count': 177, 'r': 255, 'g': 255, 'b': 255}, {'x': 570, 'y': 77, 'count': 177, 'r': 255, 'g': 255, 'b': 255}, {'x': 571, 'y': 77, 'count': 177, 'r': 255, 'g': 255, 'b': 255}, {'x': 572, 'y': 77, 'count': 177, 'r': |
16 | 16 | [] |
17 | 17 | [] |
18 | 18 | [] |
19 | 19 | [{'x': 344, 'y': 1129, 'count': 250, 'r': 0, 'g': 0, 'b': 0}, {'x': 333, 'y': 1130, 'count': 250, 'r': 0, 'g': 0, 'b': 0}, {'x': 334, 'y': 1130, 'count': 250, 'r': 0, 'g': 0, 'b': 0}, {'x': 331, 'y': 1131, 'count': 250, 'r': 0, 'g': 0, 'b': 0}, {'x': 334, 'y': 1131, 'count': 250, 'r': 0, 'g': 0, 'b' |
20 | 20 | [] |
21 | 21 | [{'x': 599, 'y': 1147, 'count': 1, 'r': 255, 'g': 255, 'b': 255}] |
22 | 22 | []
```
## HDBSCAN
HDBSCAN of the color search results is also possible. It should not be done with a large number of colors.
Even though it is a fast [C++ implementation](https://github.com/rohanmohapatra/hdbscan-cpp), it can take quite some time on an emulator.
```py
# Use your favorite method to get the elements
df = te.get_df_uiautomator2(with_screenshot=True)
# Search for colors
df.bb_search_for_colors([[0, 0, 0]], result_column="black_color")
# Clustering the color search results from the first element found
clustered = df["black_color"][:1].s_cluster_values(min_points=50, min_cluster_size=50)
# Displaying the first 20 results
clustered[:20]
-----------------------------------------------------------------------------------------------------------------------
iloc | index | original_data | label | membership_probability | outlier_score | outlier_id | dfiloc |
-----------------------------------------------------------------------------------------------------------------------
0 | 0 | [106.0, 388.0] | 2 | 0.05719095841793657 | 0.0 | 424 | 0 |
1 | 1 | [107.0, 388.0] | 2 | 0.10247253214424938 | 0.0 | 425 | 0 |
2 | 2 | [108.0, 388.0] | 2 | 0.10247253214424938 | 0.0 | 426 | 0 |
3 | 3 | [109.0, 388.0] | 2 | 0.10247253214424938 | 0.0 | 427 | 0 |
4 | 4 | [110.0, 388.0] | 2 | 0.10247253214424938 | 0.0 | 428 | 0 |
5 | 5 | [111.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 429 | 0 |
6 | 6 | [112.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 430 | 0 |
7 | 7 | [113.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 431 | 0 |
8 | 8 | [114.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 432 | 0 |
9 | 9 | [115.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 433 | 0 |
10 | 10 | [116.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 434 | 0 |
11 | 11 | [117.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 435 | 0 |
12 | 12 | [118.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 436 | 0 |
13 | 13 | [119.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 437 | 0 |
14 | 14 | [120.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 438 | 0 |
15 | 15 | [121.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 439 | 0 |
16 | 16 | [122.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 440 | 0 |
17 | 17 | [123.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 441 | 0 |
18 | 18 | [124.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 442 | 0 |
19 | 19 | [125.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 443 | 0 |
```
## 🎯 **Input Events Without Element Parsing**
To interact with elements—such as clicking, tapping, scrolling, writing text, or pressing keys—you can create instances of a collection of input classes. The advantage is that these instances are **callable** and can be **reused**, which saves overhead.
Most of these classes are implemented in **Cython** using low-overhead `cdef` classes for maximum performance.
***
### ⚡ **[Modified C++ Version of `sendevent` (Specifically for Keyboard Events)](https://github.com/hansalemaos/sendevent_multicommands_type_text)**
#### ✅ **Very Reliable, Natural `sendevent` Input**
```python
cmd_sendkeys = te.get_cmd_sendkeys(
text="Hi there my friend",
min_press=1,
max_press=4
)
# Just call the instance to execute the command
cmd_sendkeys()
```
***
### 🖱️ Using the System's `sendevent` Command
```py
cmd_sendevent_tap = te.get_cmd_sendevent_tap(100, 100)
cmd_sendevent_tap()
cmd_sendevent_click = te.get_cmd_sendevent_click(100, 100)
cmd_sendevent_click()
```
***
### 📱 Using the System's `input` Command
```py
cmd_input_tap = te.get_cmd_input_tap(100, 100)
cmd_input_tap()
```
***
### [Another Modified C++ Version of sendevent (Specifically for Mouse/Touch Events)](https://github.com/hansalemaos/mouse_sendevent_android)
```py
cmd_mouse_action = te.get_cmd_mouse_action(500, 500)
# The __call__ method accepts the following arguments:
cmd_mouse_action(
int offset_x=0,
int offset_y=0,
int action=0,
int event_multiply=1,
int natural_movement=1,
int use_every_n_element=10,
int min_x_variation=0,
int max_x_variation=0,
int min_y_variation=0,
int max_y_variation=0,
int sleep_time=0,
int debug=0,
int print_device_info=0,
)
# Check out the documentation for details on each parameter:
# https://github.com/hansalemaos/mouse_sendevent_android
```
***
### ✍️ Using the System's `input` Command (Latin Letters with Accents Normalized)
```py
# Sends the whole text
cmd_send_text = te.get_cmd_send_text("Hi there m'y frönd")
cmd_send_text()
# sends each text
cmd_send_text_natural = te.get_cmd_send_text_natural("Hi there my frönd")
cmd_send_text_natural()
```
***
### ⌨️ Keycodes (Using the System's input Command)
```py
te.KeyCodes.long_press_KEYCODE_BACKSLASH()
te.KeyCodes.short_press_KEYCODE_BACKSLASH()
```
***
### [🌐 ADBKeyboard - For Unicode Text (Not Supported on Every Device)](https://github.com/senzhk/ADBKeyBoard)
```py
te.adb_keyboard.download_adbkeyboard_apk()
te.adb_keyboard.install_adbkeyboard_apk()
te.adb_keyboard.activate_adb_keyboard()
te.adb_keyboard.send_unicode_text_with_delay(
text="Hello myç friend",
delay_range=(0.05, 0.3),
)
te.adb_keyboard.send_unicode_text("Hello myç friend")
te.disable_adb_keyboard()
```
## 🖥️ **The Interactive Shell**
Sometimes, you need to do more than just parse and interact with elements on the screen—you need to execute commands directly on the device.
**CyAndroEmu** provides an interactive shell that doesn’t rely on either the Python `subprocess` module or Python threads.
This shell is implemented **100% in C++**, runs in **nogil mode**, and offers **excellent reaction times**, making it perfect for high-performance automation tasks.
***
### 🚀 Key Benefits of the Interactive Shell:
1. **Real-Time Interaction:** Fast command execution with immediate feedback.
2. **Root Access Control:** Easily switch between normal and superuser modes.
3. **DataFrame Integration:** Collect system data in a structured format for automation workflows.
4. **Optimized for Performance:** Runs in C++ with nogil mode for high responsiveness.
***
### 🚀 **Starting an Interactive Shell**
#### To start a shell, simply use:
```python
myshell = te.open_shell(
buffer_size=40960, # The max size of the C++ vector—works like collections.deque (ring buffer)
exit_command=b"exit", # The command to exit the shell, required by the C++ destructor.
# Executed automatically when 'myshell' goes out of scope.
print_stdout=False, # Prints stdout to the screen—useful for debugging purposes
print_stderr=False # Prints stderr to the screen—useful for debugging purposes
)
```
***
***
## ⚡ **Interacting Directly with the Shell**
Once the interactive shell is running, you can execute commands directly and capture their output effortlessly.
***
### 📋 **Executing Commands**
```python
>>> stdout, stderr = myshell.write_and_wait("ls -lZ")
# stdout and stderr contain the command’s output in bytes.
# Use .decode() to convert the output to a human-readable string.
>>> print(stdout.decode())
total 48
-rw-r--r-- 1 root root u:object_r:app_data_file:s0 12264 2025-02-06 20:29 None
drwxr-x--- 16 root root u:object_r:app_data_file:s0 4096 2025-02-04 22:57 cyandroemu
-rw-r--r-- 1 root root u:object_r:app_data_file:s0 0 2025-02-02 01:40 pckldf.pkl
-rw-r----- 1 root root u:object_r:app_data_file:s0 17446 2025-02-04 22:51 pyshell.py
drwx------ 5 u0_a286 u0_a286 u:object_r:app_data_file:s0:c30,c257,c512,c768 4096 2025-02-01 23:45 tessdata
drwxr-xr-x 5 root root u:object_r:app_data_file:s0 4096 2025-02-02 00:13 tessdata_best
drwxr-xr-x 5 root root u:object_r:app_data_file:s0 4096 2025-02-02 00:11 tessdata_fast
```
***
#### Entering SU (Superuser) Mode
```py
# To gain root access within the shell:
>>> myshell.su()
# This elevates the shell session, allowing privileged commands to be executed seamlessly.
```
***
***
## Predefined Shell Commands
### The shell comes with a variety of predefined commands to simplify common tasks.
#### These commands follow two naming conventions:
1. get_df_* → Returns data as a pandas DataFrame for easy analysis.
2. sh_* → Executes shell commands and usually returns a tuple[bytes, bytes] containing stdout and stderr,
but not always—some commands may return different structures.
### ✅ Example: Checking the Current User
```py
# This command checks the current user, and the result is returned in byte format (b'root').
>>> myshell.sh_whoami()
b'root'
```
***
### ✅ Example: Getting the build props as a pandas DataFrame
```py
>>> buildprops=myshell.get_df_build_props()
>>> print(buildprops)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
iloc | index | aa_file | aa_line | aa_line_content |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 | 0 | '/data/adb/modules/make_writeable/system.prop' | 0 | b'# This file will be read by resetprop' |
1 | 1 | '/data/adb/modules/make_writeable/system.prop' | 1 | b'# Example: Change dpi' |
2 | 2 | '/data/adb/modules/make_writeable/system.prop' | 2 | b'# ro.sf.lcd_density=320' |
3 | 3 | '/data/adb/modules/make_writeable/module.prop' | 0 | b'id=make_writeable' |
4 | 4 | '/data/adb/modules/make_writeable/module.prop' | 1 | b'name=Make Writeable' |
5 | 5 | '/data/adb/modules/make_writeable/module.prop' | 2 | b'version=1.0' |
6 | 6 | '/data/adb/modules/make_writeable/module.prop' | 3 | b'versionCode=01' |
7 | 7 | '/data/adb/modules/make_writeable/module.prop' | 4 | b'author=hansalemao'
...
```
## ⚡ **List of Implemented Shell Methods**
CyAndroEmu provides a wide range of shell methods to control Android devices efficiently. These methods are optimized for speed and reliability.
## 📦 **Some of the Implemented Shell Methods**
### 🔍 **Check Out the Source Code for More Details**
```py
sh_save_sed_replace(self, file_path, string2replace, replacement, timeout=1000)
sh_svc_enable_wifi(self, timeout=10)
sh_svc_disable_wifi(self, timeout=10)
sh_trim_cache(self, timeout=10)
sh_force_open_app(self, package_name, sleep_time, timeout=3)
sh_get_main_activity(self, package_name, timeout=3)
sh_svc_power_shutdown(self, timeout=3)
sh_svc_power_reboot(self, timeout=3)
sh_dumpsys_dropbox(self, timeout=3)
sh_set_new_launcher(self, package_name, timeout=3)
sh_tar_folder(self, src, dst, timeout=1000000)
sh_extract_tar_zip(self, src_file, dst_folder, timeout=1000000)
sh_get_user_rotation(self, timeout=10)
sh_copy_dir_recursive(self, src, dst, timeout=1000)
sh_backup_file(self, src, timeout=1000)
sh_remove_folder(self, folder, timeout=1000)
sh_get_pid_of_shell(self, int64_t timeout=3)
sh_whoami(self, int64_t timeout=10)
sh_dumpsys_package(self, package, timeout=1000, bint convert_to_dict=True)
sh_get_all_wanted_permissions_from_package(self, package, timeout=1000)
sh_grant_permission(self, package, permission, timeout=10)
sh_grant_permission(self, package, permission, timeout=10)
sh_grant_all_wanted_permissions(self, package, timeout=1000)
sh_revoke_all_wanted_permissions(self, package, timeout=1000)
sh_parse_whole_dumpsys_to_dict(self, timeout=100,convert_to_dict=False)
sh_parse_dumpsys_to_dict(self, subcmd, timeout=100,convert_to_dict=False)
sh_get_available_keyboards(self, timeout=10)
sh_get_active_keyboard(self, timeout=10)
sh_get_all_information_about_all_keyboards(self, timeout=10,convert_to_dict=False)
sh_enable_keyboard(self, keyboard, timeout=10)
sh_disable_keyboard(self, keyboard, timeout=10)
sh_is_keyboard_shown(self, timeout=10)
sh_set_keyboard(self, keyboard, timeout=10)
sh_show_touches(self, timeout=10)
sh_dont_show_touches(self, timeout=10)
sh_show_pointer_location(self, timeout=10)
sh_dont_show_pointer_location(self, timeout=10)
sh_input_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_tap(self, x, y, timeout=10)
sh_clear_file_content(self, file_path, timeout=10)
sh_makedirs(self, folder, timeout=10)
sh_touch(self, file_path, timeout=10)
sh_mv(self, src, dst, timeout=10)
sh_open_accessibility_settings(self, timeout=10)
sh_open_advanced_memory_protection_settings(self, timeout=10)
sh_open_airplane_mode_settings(self, timeout=10)
sh_open_all_apps_notification_settings(self, timeout=10)
sh_open_apn_settings(self, timeout=10)
sh_open_application_details_settings(self, timeout=10)
sh_open_application_development_settings(self, timeout=10)
sh_open_application_settings(self, timeout=10)
sh_open_app_locale_settings(self, timeout=10)
sh_open_app_notification_bubble_settings(self, timeout=10)
sh_open_app_notification_settings(self, timeout=10)
sh_open_app_open_by_default_settings(self, timeout=10)
sh_open_app_search_settings(self, timeout=10)
sh_open_app_usage_settings(self, timeout=10)
sh_open_automatic_zen_rule_settings(self, timeout=10)
sh_open_auto_rotate_settings(self, timeout=10)
sh_open_battery_saver_settings(self, timeout=10)
sh_open_bluetooth_settings(self, timeout=10)
sh_open_captioning_settings(self, timeout=10)
sh_open_cast_settings(self, timeout=10)
sh_open_channel_notification_settings(self, timeout=10)
sh_open_condition_provider_settings(self, timeout=10)
sh_open_data_roaming_settings(self, timeout=10)
sh_open_data_usage_settings(self, timeout=10)
sh_open_date_settings(self, timeout=10)
sh_open_device_info_settings(self, timeout=10)
sh_open_display_settings(self, timeout=10)
sh_open_dream_settings(self, timeout=10)
sh_open_hard_keyboard_settings(self, timeout=10)
sh_open_home_settings(self, timeout=10)
sh_open_ignore_background_data_restrictions_settings(self, timeout=10)
sh_open_ignore_battery_optimization_settings(self, timeout=10)
sh_open_input_method_settings(self, timeout=10)
sh_open_input_method_subtype_settings(self, timeout=10)
sh_open_internal_storage_settings(self, timeout=10)
sh_open_locale_settings(self, timeout=10)
sh_open_location_source_settings(self, timeout=10)
sh_open_manage_all_applications_settings(self, timeout=10)
sh_open_manage_all_sim_profiles_settings(self, timeout=10)
sh_open_manage_applications_settings(self, timeout=10)
sh_open_manage_default_apps_settings(self, timeout=10)
sh_open_manage_supervisor_restricted_setting(self, timeout=10)
sh_open_manage_write_settings(self, timeout=10)
sh_open_memory_card_settings(self, timeout=10)
sh_open_network_operator_settings(self, timeout=10)
sh_open_nfcsharing_settings(self, timeout=10)
sh_open_nfc_payment_settings(self, timeout=10)
sh_open_nfc_settings(self, timeout=10)
sh_open_night_display_settings(self, timeout=10)
sh_open_notification_assistant_settings(self, timeout=10)
sh_open_notification_listener_detail_settings(self, timeout=10)
sh_open_notification_listener_settings(self, timeout=10)
sh_open_notification_policy_access_settings(self, timeout=10)
sh_open_print_settings(self, timeout=10)
sh_open_privacy_settings(self, timeout=10)
sh_open_quick_access_wallet_settings(self, timeout=10)
sh_open_quick_launch_settings(self, timeout=10)
sh_open_regional_preferences_settings(self, timeout=10)
sh_open_satellite_setting(self, timeout=10)
sh_open_search_settings(self, timeout=10)
sh_open_security_settings(self, timeout=10)
sh_open_settings(self, timeout=10)
sh_open_settings(self, timeout=10)
sh_open_sound_settings(self, timeout=10)
sh_open_storage_volume_access_settings(self, timeout=10)
sh_open_sync_settings(self, timeout=10)
sh_open_usage_access_settings(self, timeout=10)
sh_open_user_dictionary_settings(self, timeout=10)
sh_open_voice_input_settings(self, timeout=10)
sh_open_vpn_settings(self, timeout=10)
sh_open_vr_listener_settings(self, timeout=10)
sh_open_webview_settings(self, timeout=10)
sh_open_wifi_ip_settings(self, timeout=10)
sh_open_wifi_settings(self, timeout=10)
sh_open_wireless_settings(self, timeout=10)
sh_open_zen_mode_priority_settings(self, timeout=10)
sh_open_developer_settings(self, timeout=10)
sh_rescan_media_folder(self, folder, timeout=10)
sh_rescan_media_file(self, file_path, timeout=10)
sh_dump_process_memory_to_sdcard(self, pid, timeout=100000)
sh_pm_clear(self, package, timeout=10)
sh_wm_change_size(self, width, height, timeout=10)
sh_wm_reset_size(self, timeout=10)
sh_wm_get_density(self, timeout=10)
sh_wm_change_density(self, density, timeout=10)
sh_wm_reset_density(self, timeout=10)
sh_am_screen_compat_on(self, package, timeout=10)
sh_am_screen_compat_off(self, package, timeout=10)
sh_enable_notifications(self, timeout=10)
sh_disable_notifications(self, timeout=10)
sh_still_image_camera(self, timeout=10)
sh_disable_network_interface(self, nic, timeout=10)
sh_enable_network_interface(self, nic, timeout=10)
sh_get_linux_version(self, timeout=10)
sh_expand_notifications(self, timeout=10)
sh_expand_settings(self, timeout=10)
sh_list_permission_groups(self, timeout=10)
sh_input_dpad_tap(self, x, y, timeout=10)
sh_input_keyboard_tap(self, x, y, timeout=10)
sh_input_mouse_tap(self, x, y, timeout=10)
sh_input_touchpad_tap(self, x, y, timeout=10)
sh_input_gamepad_tap(self, x, y, timeout=10)
sh_input_touchnavigation_tap(self, x, y, timeout=10)
sh_input_joystick_tap(self, x, y, timeout=10)
sh_input_touchscreen_tap(self, x, y, timeout=10)
sh_input_stylus_tap(self, x, y, timeout=10)
sh_input_trackball_tap(self, x, y, timeout=10)
sh_input_dpad_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_dpad_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_dpad_roll(self, x, y, timeout=10)
sh_input_keyboard_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_keyboard_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_keyboard_roll(self, x, y, timeout=10)
sh_input_mouse_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_mouse_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_mouse_roll(self, x, y, timeout=10)
sh_input_touchpad_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_touchpad_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_touchpad_roll(self, x, y, timeout=10)
sh_input_gamepad_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_gamepad_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_gamepad_roll(self, x, y, timeout=10)
sh_input_touchnavigation_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_touchnavigation_roll(self, x, y, timeout=10)
sh_input_joystick_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_joystick_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_joystick_roll(self, x, y, timeout=10)
sh_input_touchscreen_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_touchscreen_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_touchscreen_roll(self, x, y, timeout=10)
sh_input_stylus_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_stylus_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_stylus_roll(self, x, y, timeout=10)
sh_input_trackball_swipe(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_trackball_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)
sh_input_trackball_roll(self, x, y, timeout=10)
sh_open_url(self, url, timeout=10)
sh_get_bios_information(self, timeout=10)
sh_printenv(self, timeout=10)
sh_freeze_proc(self, pid, timeout=10)
sh_unfreeze_proc(self, pid, timeout=10)
sh_show_fragments_on_screen_enable(self, timeout=10)
sh_show_fragments_on_screen_disable(self, timeout=10)
sh_read_write_remount(self, methods, timeout=100)
```
## 📊 Methods That Return Pandas DataFrames
Some shell methods are designed to return data as pandas DataFrames for easy analysis and manipulation.
```py
get_df_files_with_context_printf(self, object folders, int64_t max_depth=1, int64_t timeout=10)
get_df_build_props(self, int64_t timeout=10)
get_df_files_with_ending(self, object folders, object endings, int64_t max_depth=10000, int64_t timeout=10)
get_df_top_procs(self, timeout=1000)
get_df_users(self, start=0, end=2000, timeout=10000)
get_df_groups_of_user(self, start=0, end=2000, timeout=10000)
get_df_netstat_tlnp(self, timeout=100)
get_df_mounts(self, timeout=100)
get_df_ps_el(self, timeout=1000)
get_df_packages(self, timeout=10)
get_df_netstat_connections_of_apps(self, resolve_names=True, timeout=10)
get_df_lsmod(self, timeout=1000)
get_df_lsof(self, timeout=1000000)
```
<!-- ROADMAP -->
## Roadmap
- [ ] Add template matching using https://www.fftw.org/ without other dependencies, something like [needlefinder]
(https://github.com/hansalemaos/needlefinder) but without scipy
- [ ] Add more useful commands to the interactive shell
- [ ] Support for Accelerated [Hierarchical Density Clustering in C++](https://github.com/rohanmohapatra/hdbscan-cpp/issues/11)
See the [open issues](https://github.com/hansalemaos/cyandroemu) for a full list of proposed features (and known issues).
## Contributing
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
Don't forget to give the project a star! Thanks again!
1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## License
Distributed under the MIT License. See `LICENSE` for more information.
## Contact
If you’re interested in private classes with me to learn strategies for automating anything, or if you have an automation project (within legal boundaries!) that you’d like to bring to life, feel free to contact me. I speak German, English, and Portuguese fluently, and Spanish proficiently.
[WhatsApp](https://api.whatsapp.com/send?phone=%205511989782756&text=Question+about+CyAndroEmu)
[Discord](https://discord.com/invite/ckhnJ3PxEP)
[Portuguese YouTube Channel](https://www.youtube.com/channel/UC3DeX0cPlJaLSD254T7fpdA)
[English YouTube Channel](https://youtube.com/channel/UCgIfJ0iFUXGfq-G4zkPXGyw)
[GitHub](https://github.com/hansalemaos)
[PIP](https://pypi.org/user/hansalemao)
<!-- MARKDOWN LINKS & IMAGES -->
[product-screenshot]: images/screenshot.png
Raw data
{
"_id": null,
"home_page": "https://github.com/hansalemaos/cyandroemu",
"name": "cyandroemu",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "android, bot, uiautomator, magisk, kernelsu",
"author": "Johannes Fischer",
"author_email": "aulasparticularesdealemaosp@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/dc/7d/2ce8b3099f9133e72a76c2241432b5f8b387012348dd07683e926dce26fd/cyandroemu-1.0.0.tar.gz",
"platform": null,
"description": "\r\n# \ud83d\udcf1 **CyAndroEmu: Advanced Android Automation Library**\r\n\r\n<!-- PROJECT LOGO -->\r\n<br />\r\n<div align=\"center\">\r\n <a href=\"https://github.com/othneildrew/Best-README-Template\">\r\n <img src=\"images/logo.png\" alt=\"Logo\" width=\"400\" height=\"400\">\r\n </a>\r\n\r\n <h3 align=\"center\">Python / Cython Automation for Android Emulators</h3>\r\n\r\n <p align=\"center\">\r\n Android automations without ADB - directly on emulators\r\n </p>\r\n</div>\r\n\r\n\r\n## About The Project\r\n\r\n**CyAndroEmu** is a powerful [**Python**](https://www.python.org/) library designed for advanced Android automation. For performance reasons, it\u2019s primarily written in [**C++**](https://cplusplus.com/) and [**Cython**](https://cython.readthedocs.io/), providing multiple backends for interacting with UI elements, handling input events, and efficiently extracting screen data.\r\n\r\nUnlike any other Android automation library, **CyAndroEmu** is designed to run **directly and independently** on the emulator or rooted device **without relying on ADB**. This architecture offers significant performance and reliability advantages.\r\n\r\n---\r\n\r\n## \ud83d\ude80 **Why Choose CyAndroEmu?**\r\n\r\n### \u2705 **Key Advantages:**\r\n\r\n- **No Broken Connections:**\r\n Since it operates independently of ADB, you\u2019ll never face issues with unstable or dropped connections.\r\n\r\n- **Blazing Fast Automation:**\r\n No need for slow ADB screenshot transmissions\u2014screen data is processed directly on the device.\r\n\r\n- **Unlimited Device Scalability:**\r\n Run as many emulators as your hardware can handle without hitting ADB\u2019s device limits.\r\n\r\n- **Natural Mouse Movements:**\r\n Supports smooth, human-like mouse movements, making it perfect for bypassing CAPTCHA and anti-bot detection systems.\r\n\r\n- **Fingerprint Avoidance:**\r\n Eliminate the risk of device fingerprinting. Curious about how easy it is to fingerprint your device?\r\n \ud83d\udc49 [Check it here](https://amiunique.org/fingerprint)\r\n\r\n- **Direct Botting Mode with Magisk/KernelSU:**\r\n With Magisk or KernelSU, you can start your device and go straight into botting mode\u2014no manual intervention needed.\r\n\r\n- **Easy Device-Wide Proxying:**\r\n Effortlessly proxy all network traffic using tools like [**Proxifier**](https://www.proxifier.com/) or [**SocksDroid**](https://github.com/bndeff/socksdroid) for enhanced privacy and IP rotation.\r\n\r\n---\r\n\r\n## \u26a1 **Additional Highlights:**\r\n\r\n- **Low-Level Performance:**\r\n Thanks to its C++ core, CyAndroEmu achieves unparalleled speed and efficiency, even in resource-intensive environments.\r\n\r\n- **Multi-Backend Support:**\r\n Choose from various parsers and input methods tailored to different Android environments (real devices, emulators, custom ROMs).\r\n\r\n- **Seamless Emulator Integration:**\r\n Designed to work flawlessly with popular emulators like **BlissOS**, **BlueStacks**, **VMware**, and more.\r\n\r\n- **Root-Friendly:**\r\n Full support for rooted devices, enabling deep system-level automation capabilities.\r\n\r\n- **Magisk / KernelSU Plugins:**\r\n Start your Python automation **automatically** when the emulator or device boots\u2014**no human interaction needed**.\r\n\r\n---\r\n\r\n## Getting Started\r\n\r\n### Installation\r\n\r\n**1. Download and install your favorite Android emulator, and ensure it has root access. CyAndroEmu should also work on any rooted smartphone (not tested yet). A non-root version may be available in the future. CyAndroEmu has been tested with the following:**\r\n * [BlueStacks 5](https://www.bluestacks.com/)\r\n * [BlissOs 14, 15, 16 Go](https://blissos.org/) (on [ProxMox](https://www.proxmox.com/), [Virtual Box - Windows](https://www.virtualbox.org/) and [VMWare - Windows](https://www.vmware.com/))\r\n * [LDPlayer](https://ldplayer.net/)\r\n * [MeMuPlay](https://www.memuplay.com/)\r\n * [MuMuPlayer](https://www.mumuplayer.com/)\r\n * [GenyMotion](https://www.genymotion.com/)\r\n * [Nox Player](https://pt.bignox.com/)\r\n\r\n**Although neither [Magisk](https://github.com/topjohnwu/Magisk) nor [KernelSU](https://kernelsu.org/) is required, using them can significantly simplify tasks such as [running Python scripts at Android startup](https://github.com/hansalemaos/python_autostart_debug/tree/220d88549687375e53ec6cf3e7f9641553cc4375) and automatically [adding the Termux folder to the PATH when accessing the ADB shell ](https://github.com/hansalemaos/termuxtoadb/tree/bd119fd61ed8c60e399f81de26a1e202c2a5ffa3) . They also assist in hiding root access and automating actions - [writing your own Plugins is really simple](https://topjohnwu.github.io/Magisk/guides.html). [Here are some of my tutorials in Portuguese/English](https://github.com/hansalemaos/install_python_on_android_emulators) that teach you how to install them:**\r\n\r\n| How to install Python on an emulator | |\r\n|-----------|-----------|\r\n| [](https://www.youtube.com/watch?v=99mOZ3nhG8I) | [](https://www.youtube.com/watch?v=tAFduUpmxnA) |\r\n| [](https://www.youtube.com/watch?v=_mgQo6OVxYg) | [](https://www.youtube.com/watch?v=OPB7qnj70e4) |\r\n| [](https://www.youtube.com/watch?v=GvkM1oBJR4M) | [](https://www.youtube.com/watch?v=XBH4YEZZEXI) |\r\n| [](https://www.youtube.com/watch?v=KMPGV4d0q08) | [](https://www.youtube.com/watch?v=_j325L8wXY0) |\r\n| [](https://www.youtube.com/watch?v=7LDgi3qS_lU) | [](https://www.youtube.com/watch?v=edHqLJot6pk) |\r\n\r\n\r\n\r\n***\r\n\r\n**2. Install [Termux](https://github.com/termux/termux-app) and [TermuxBoot - optional](https://github.com/termux/termux-boot)**\r\n\r\n***\r\n\r\n**3. Use the following command to install the required packages ([Python](https://www.python.org/), [Pandas](https://pandas.pydata.org/), [NumPy](https://numpy.org/) and some other stuff):**\r\n * Open a [ADB shell](https://developer.android.com/tools/adb), and Termux on your emulator and copy and paste this command to the ADB shell to save some typing:\r\n * __necessary packages:__\r\n ```sh\r\n input text 'yes | pkg up;pkg install -y openssh;pkg install -y git;pkg install -y openssl;pkg install -y python;pkg install -y python-numpy;pkg install -y python-pip;pkg install -y clang;pkg install -y cmake;pkg install -y coreutils;pkg install -y termux-tools;pkg install -y root-repo;pkg install -y cpulimit;pkg install -y tur-repo;pkg install -y python-pandas;pkg install -y tesseract;pkg install -y imagemagick; pkg install -y imagemagick-static;yes | python -m pip install ptpython;yes | python -m pip install cyandroemu;yes | python -m pip install regex;yes | python -m pip install ptpython;yes | python -m pip install setuptools;yes | python -m pip install Cython;yes | python -m pip install requests';input keyevent KEYCODE_ENTER;input keyevent KEYCODE_ENTER\r\n ```\r\n\r\n * __recommended packages:__\r\n\r\n ```sh\r\n input text 'yes | pkg up;yes | pkg install -y openssh;yes | pkg install -y ripgrep;yes | pkg rei libexpat;pkg install -y git;pkg install -y openssl;pkg install -y python;pkg install -y cloneit;pkg install -y python-lxml;pkg install -y python-numpy;pkg install -y python-pillow;pkg install -y python-pip;pkg install -y python-scipy;pkg install -y vim-python;pkg install -y clang;pkg install -y cmake;pkg install -y coreutils;pkg install -y termux-exec;pkg install -y termux-tools;pkg install -y root-repo;pkg install -y matplotlib;pkg install -y cpulimit;pkg install -y tur-repo;pkg install -y python-pandas;pkg install -y tmux;pkg install -y opencv-python;pkg install -y boost;pkg install -y boost-headers;pkg install -y boost-static;pkg install -y tesseract; pkg install -y tor; pkg install -y torsocks; pkg install -y fzf; pkg install -y imagemagick; pkg install -y imagemagick-static;pkg install -y python-scikit-image; pkg install -y python-polars; pkg install -y nodejs-20; pkg install -y gcc-14; pkg install -y ffmpeg7;yes | python -m pip install ptpython;yes | python -m pip install cyandroemu;yes | python -m pip install regex;yes | python -m pip install ptpython;yes | python -m pip install setuptools;yes | python -m pip install Cython;yes | python -m pip install requests';input keyevent KEYCODE_ENTER;input keyevent KEYCODE_ENTER\r\n ```\r\n\r\n***\r\n\r\n\r\n**4. Accessing Python from the ADB shell. Choose one of the 3 solutions:**\r\n 1. **Recommended:** Install the [Magisk/KernelSU plugin to automatically add the Termux bin folder to the PATH](https://github.com/hansalemaos/termuxtoadb/tree/bd119fd61ed8c60e399f81de26a1e202c2a5ffa3)\r\n 2. Add `export PATH=\"$PATH:/data/data/com.termux/files/usr/bin\"` to `/system/etc/mkshrc` (don't forget to set the correct owner/group ... afterwards)\r\n\r\n 3. Manually type `export PATH=\"$PATH:/data/data/com.termux/files/usr/bin\"` each time you enter the **ADB su shell**.\r\n\r\n\r\n***\r\n***\r\n\r\n\r\n## Writing Python scripts\r\n\r\n### Cyandroemu will be compiled the first time you import it! Since this process is very CPU- and memory-intensive, I recommend setting the memory to 8 GB of RAM. Later on, you can reduce it. The SO files can be copied to other instances of your chosen emulator, but be careful: the CPU must be the same, as the C++ files are compiled with the flags `-march=native` and `-mtune=native` to ensure the highest possible performance.\"\r\n\r\nCyandroemu is primarily written in [C++](https://cplusplus.com/) (6 out of 7 parsers, modified sendevent, etc.) and [Cython](https://cython.readthedocs.io/) (1 parser and the Python interface), but all automation is handled using the Python class TermuxAutomation.\r\n\r\n***\r\n\r\n### The Constructor\r\n\r\n#### May Look Intimidating, but It\u2019s Easy to Understand\r\n\r\n```py\r\nTermuxAutomation:\r\n parsers: dict,\r\n parser_timeout: int = 30,\r\n add_input_tap: bool = True,\r\n add_sendevent_mouse_click: bool = True,\r\n add_sendevent_tap: bool = True,\r\n add_mouse_action: bool = True,\r\n mouse_device: str = \"/dev/input/event4\",\r\n touch_device: str = \"/dev/input/event5\",\r\n keyboard_device: str = \"/dev/input/event1\",\r\n touch_device_max: int = 32767,\r\n mouse_device_max: int = 65535,\r\n input_cmd_tap: str = \"/system/bin/input tap\",\r\n input_cmd_text: str = \"/system/bin/input text\",\r\n sendevent_path: str = \"/system/bin/sendevent\",\r\n screen_height: int = 768,\r\n screen_width: int = 1024,\r\n sh_exe: str = \"/bin/sh\",\r\n su_exe: str = \"su\",\r\n uiautomator_dump_path: str = \"/sdcard/window_dump.xml\",\r\n uiautomator_cpu_limit: int = 5,\r\n system_bin_path: str = \"/system/bin/\",\r\n path_screencap: str = \"screencap\",\r\n path_exe_tesseract: str = \"/data/data/com.termux/files/usr/bin/tesseract\",\r\n path_exe_imagemagick: str = \"/data/data/com.termux/files/usr/bin/magick\",\r\n tesseract_args: str = '\"-l por+eng --oem 3\"',\r\n imagemagick_args: object = None,\r\n tesseract_path_outpic: str = \"/sdcard/screenshot.ppm\",\r\n uiautomator2_download_link1: str = \"https://github.com/hansalemaos/uiautomator2tocsv/raw/refs/heads/main/app-uiautomator-test.apk\",\r\n uiautomator2_download_link2: str = \"https://github.com/hansalemaos/uiautomator2tocsv/raw/refs/heads/main/app-uiautomator.apk\",\r\n uiautomator2_save_path1: str = \"/sdcard/app-uiautomator-test.apk\",\r\n uiautomator2_save_path2: str = \"/sdcard/app-uiautomator.apk\",\r\n lcp_deque_size: int = 40960,\r\n lcp_print_stdout: bool = False,\r\n lcp_print_stderr: bool = False,\r\n kwargs: object = None,\r\n adb_keyboard_link=\"https://github.com/hansalemaos/ADBKeyBoard/raw/refs/heads/master/ADBKeyboard.apk\",\r\n adb_keyboard_save_path=\"/sdcard/ADBKeyboard.apk\",\r\n valid_adb_keyboards=(\r\n \"com.android.adbkeyboard/.AdbIME\",\r\n \"com.github.uiautomator/.AdbKeyboard\",\r\n ),\r\n```\r\n### Each constructor argument explained\r\n\r\n***\r\n\r\n#### `parsers: dict`\r\n\r\nThe heart of the library, containing all the C++ applications required to run the automation.\r\nTo obtain the dictionary, use the following command.\r\nThe first time you run it, it will take about 5 minutes as the C++ files will be downloaded and compiled using GCC.\r\n\r\n```py\r\nparsers = TermuxAutomation.load_parsers_or_download_and_compile(\"g++\")\r\n```\r\n\r\n***\r\n\r\n#### `parser_timeout: int = 30`\r\n\r\nThe timeout (in seconds) for `subprocess.run`.\r\n\r\n***\r\n\r\n#### `add_input_tap: bool = True`\r\n\r\nWether to add the option to `input tap` any elment.\r\n\r\n***\r\n\r\n#### `add_sendevent_mouse_click: bool = True`\r\n\r\nWhether to add the option to perform mouse clicks on any element using `sendevent`.\r\n\r\n***\r\n\r\n\r\n#### `add_sendevent_tap: bool = True`\r\n\r\nWhether to add the option to tap any element using `sendevent`.\r\n\r\n***\r\n\r\n\r\n#### `add_mouse_action: bool = True`\r\n\r\nWhether to add the option to perform mouse actions on elements (e.g., move to, right-click, left-click, middle-click, etc.)\r\nusing [a modified version of sendevent](https://github.com/hansalemaos/mouse_sendevent_android/tree/88ce6d1a54a3fbd2389ad00c7ede20cd60197dbe).\r\n\r\n***\r\n\r\n\r\n#### `mouse_device: str = \"/dev/input/event4\"`\r\n#### `touch_device: str = \"/dev/input/event5\"`\r\n#### `keyboard_device: str = \"/dev/input/event1\"`\r\n#### `touch_device_max: int = 32767`\r\n#### `mouse_device_max: int = 65535`\r\n\r\nThe mouse/keyboard/touch devices and their corresponding device max can be identified using\r\n```sh\r\ngetevent -lp\r\n```\r\nor by using the static method `find_suitable_devices_for_input_events`:\r\n\r\n```py\r\ndf_devices = TermuxAutomation.find_suitable_devices_for_input_events() # returns a pandas DataFrame\r\n```\r\n\r\n***\r\n\r\n\r\n#### `input_cmd_tap: str = \"/system/bin/input tap\"`\r\n#### `input_cmd_text: str = \"/system/bin/input text\"`\r\n#### `sendevent_path: str = \"/system/bin/sendevent\"`\r\n\r\nThese are the standard input commands. In most cases, there\u2019s no need to modify them.\r\n\r\n***\r\n\r\n#### `screen_height: int = 768`\r\n#### `screen_width: int = 1024`\r\n\r\nScreen height and screen width, can be identified using\r\n```sh\r\nwm size\r\n```\r\n\r\nor by using the static method `get_resolution_of_screen`\r\n```py\r\nscreen_width, screen_height = TermuxAutomation.get_resolution_of_screen()\r\n```\r\n> [!CAUTION]\r\n> **MAKE SURE TO PROVIDE THE CORRECT VALUES HERE AND DO NOT ROTATE THE SCREEN DURING AUTOMATION!\r\n> Many parsers rely on this information to function correctly.**\r\n\r\n***\r\n\r\n#### `sh_exe: str = \"/bin/sh\"`\r\n\r\nThe path to the shell executable, in most cases, there\u2019s no need to modify it.\r\n\r\n***\r\n\r\n#### `su_exe: str = \"su\"`\r\n\r\nThe command used to enter `su` (superuser) mode. In most cases, there\u2019s no need to modify it.\r\n\r\n***\r\n\r\n#### `uiautomator_dump_path: str = \"/sdcard/window_dump.xml\"`\r\n\r\nDump path for uiautomator. In most cases, there\u2019s no need to modify it.\r\n\r\n***\r\n\r\n\r\n\r\n#### `uiautomator_cpu_limit: int = 5`\r\n\r\nThe CPU usage limit for the UIAutomator + cpulimit backend.\r\n\r\n***\r\n\r\n\r\n\r\n#### `system_bin_path: str = \"/system/bin/\"`\r\n\r\nThe path where system executables are stored. In most cases, there\u2019s no need to modify it.\r\n\r\n***\r\n\r\n\r\n\r\n#### `path_screencap: str = \"screencap\"`\r\n\r\nThe command used for taking screenshots. In most cases, there\u2019s no need to modify it.\r\n\r\n\r\n***\r\n\r\n\r\n#### `path_exe_tesseract: str = \"/data/data/com.termux/files/usr/bin/tesseract\"`\r\n\r\nThe path to the Tesseract executable. In most cases, there\u2019s no need to modify it.\r\n\r\n***\r\n\r\n\r\n\r\n#### `path_exe_imagemagick: str = \"/data/data/com.termux/files/usr/bin/magick\"`\r\n\r\nThe path to the ImageMagick executable. Used for tesseract preprocessing. In most cases, there\u2019s no need to modify it.\r\n\r\n***\r\n\r\n\r\n#### `tesseract_args: str = '\"-l por+eng --oem 3\"'`\r\n\r\nDefault Tesseract arguments. The default languages are Portuguese (por) and English (eng), with fully automatic page segmentation but no OSD (default).\r\nUse `tesseract --help-extra` to view all available options. Words are grouped using pandas\r\n\r\n**Note:\r\nBe aware that changing the output format may cause the parser to crash, as it requires the output to be in hOCR format.**\r\n\r\n***\r\n\r\n\r\n#### `imagemagick_args: object = None`\r\n\r\nPass None if you don\u2019t want to preprocess the screenshot before passing it to Tesseract.\r\nIf you choose to preprocess, you can provide ImageMagick command-line arguments to adjust\r\nthe image (e.g., converting to grayscale, increasing contrast) to improve OCR accuracy.\r\n\r\n***\r\n\r\n\r\n#### `tesseract_path_outpic: str = \"/sdcard/screenshot.ppm\"`\r\n\r\nThe C++ Tesseract parser captures a screenshot using screencap, converts the image to a [PPM format](https://en.wikipedia.org/wiki/Portable_Anymap), and saves the converted output to disk before invoking Tesseract. In most cases, there\u2019s no need to modify this path.\r\n\r\n\r\n***\r\n\r\n\r\n#### `uiautomator2_download_link1: str = \"https://github.com/hansalemaos/uiautomator2tocsv/raw/refs/heads/main/app-uiautomator-test.apk\"`\r\n#### `uiautomator2_download_link2: str = \"https://github.com/hansalemaos/uiautomator2tocsv/raw/refs/heads/main/app-uiautomator.apk\"`\r\n\r\nBackups APKs from the [Uiautomator2 project](https://github.com/openatx/uiautomator2). In most cases, there\u2019s no need to modify this url.\r\n\r\n\r\n***\r\n\r\n\r\n#### `uiautomator2_save_path1: str = \"/sdcard/app-uiautomator-test.apk\"`\r\n#### `uiautomator2_save_path2: str = \"/sdcard/app-uiautomator.apk\"`\r\n\r\nDownload path for the APKs from the [Uiautomator2 project](https://github.com/openatx/uiautomator2). In most cases, there\u2019s no need to modify them.\r\n\r\n***\r\n\r\n\r\n#### `lcp_deque_size: int = 40960`\r\n\r\nThe ring buffer size of the C++ vector used by the Logcat Parser backend. In most cases, there\u2019s no need to modify it.\r\n\r\n***\r\n\r\n\r\n#### `lcp_print_stdout: bool = False`\r\n#### `lcp_print_stderr: bool = False`\r\n\r\nDebug print options for the Logcat Parser backend. These should only be enabled if you encounter issues with the Logcat Parser backend.\r\n\r\n***\r\n\r\n\r\n#### `kwargs: object = None`\r\n\r\nkwargs for `subprocess.run` In most cases, there\u2019s no need to modify it.\r\n\r\n\r\n***\r\n\r\n\r\n#### `adb_keyboard_link: str = \"https://github.com/hansalemaos/ADBKeyBoard/raw/refs/heads/master/ADBKeyboard.apk\"`\r\n\r\nBackup APK from the [ADBKeyboard project](https://github.com/senzhk/ADBKeyBoard). It allows sending Unicode characters but may not work on all devices. In most cases, there\u2019s no need to modify it.\r\n\r\n***\r\n\r\n\r\n#### `adb_keyboard_save_path: str = \"/sdcard/ADBKeyboard.apk\"`\r\n\r\nThe download path for the APK from the [ADBKeyboard project](https://github.com/senzhk/ADBKeyBoard) project. In most cases, there\u2019s no need to modify it.\r\n\r\n***\r\n\r\n\r\n#### `valid_adb_keyboards: tuple = (\"com.android.adbkeyboard/.AdbIME\", \"com.github.uiautomator/.AdbKeyboard\",)`\r\n\r\nPossible package names for ADBKeyboard.\r\n\r\n* The first name is the original from the [ADBKeyboard project](https://github.com/senzhk/ADBKeyBoard) project.\r\n* The second name is from the [Uiautomator2 project](https://github.com/openatx/uiautomator2) project.\r\n\r\nIn most cases, there\u2019s no need to modify them.\r\n\r\n***\r\n***\r\n\r\n\r\n## Creating an instance\r\n\r\n```py\r\nfrom cyandroemu import TermuxAutomation, clean_zombies\r\n\r\nimport pandas as pd\r\nfrom time import sleep as timesleep\r\nimport atexit\r\n\r\n# Ensure background parsers and shells are terminated on exit\r\natexit.register(clean_zombies)\r\n\r\n# Load parsers (first time may take ~5 mins due to download and compilation)\r\nparsers = TermuxAutomation.load_parsers_or_download_and_compile(\"g++\")\r\n\r\n# Detect input devices dynamically (returns a pandas DataFrame)\r\ndf_devices = TermuxAutomation.find_suitable_devices_for_input_events()\r\nprint(df_devices)\r\nscreen_width, screen_height = TermuxAutomation.get_resolution_of_screen()\r\n\r\n# On VMware and BlissOS, device order may change after a reboot, so hardcoding is avoided.\r\n# If device order doesn't change on your emulator, you can hardcode the path, e.g.:\r\n# mouse_device = \"/dev/input/event4\"\r\n\r\nte = TermuxAutomation(\r\n parsers=parsers,\r\n mouse_device=df_devices.loc[\r\n (df_devices[\"max\"].str.len() == 2) & (df_devices[\"type\"] == \"mouse\")\r\n ][\"path\"].iloc[0],\r\n keyboard_device=df_devices.loc[\r\n (df_devices[\"keys_found\"]) & (df_devices[\"type\"] == \"keyboard\")\r\n ][\"path\"].iloc[0],\r\n mouse_device_max=df_devices.loc[\r\n (df_devices[\"max\"].str.len() == 2) & (df_devices[\"type\"] == \"mouse\")\r\n ][\"max\"].iloc[0][0],\r\n screen_height=screen_height,\r\n screen_width=screen_width,\r\n)\r\n# Clean up any leftover background processes (e.g., uiautomator2 server) from earlier automations.\r\n# atexit should handle this, but \"Doppelt gen\u00e4ht h\u00e4lt besser :)\" (German proverb - double-stitched holds better).\r\n\r\nte.kill_zombies()\r\n```\r\n***\r\n\r\n## Automation - it's all about pandas DataFrames\r\n\r\nMost automation tools implement their own logic for finding elements, which often looks like this:\r\n\r\n`self.find(text=\"Some text\").children[0].click()`\r\n\r\nThat looks beautiful and very Pythonic, but most of the time, it\u2019s just unreliable \u2014 mainly when the attributes and positions of objects vary, or when the objects aren\u2019t loaded on the screen yet.\r\n\r\nInstead of bothering you with my own \"great\" ideas, I decided to rely on battle-tested solutions: [pandas DataFrames](https://pandas.pydata.org/). \r\n\r\n**With DataFrames, you can leverage powerful features like:**\r\n\r\n* Fast sorting algorithms\r\n* All kinds of comparisons\r\n* Regular expressions (regex)\r\n* Custom filter functions\r\n\r\nIf you know how to work with pandas DataFrames, you basically already know everything you need to automate whatever you want.\r\nIf not, you can learn everything from the official documentation: https://pandas.pydata.org/docs/\r\nThat\u2019s where I got 95% of my pandas knowledge from.\r\n\r\n***\r\n\r\n### Pretty Print\r\n\r\n\r\nThe default `__repr__` and `__str__` functions in pandas are not ideal for displaying DataFrames, which is why they\u2019ve been monkey-patched to ensure the entire DataFrame is pretty-printed.\r\n\r\n```py\r\ndf = te.get_df_uiautomator2(with_screenshot=True)\r\nprint(df)\r\n```\r\n\r\nNow, when you print the DataFrame, you\u2019ll see the complete content neatly formatted, making it easier to analyze UI elements.\r\nFor a line-break-free experience, I recommend using the [VTM terminal](https://github.com/directvt/vtm)\r\n\r\n***\r\n\r\n#### Example of a pandas DataFrame in the VTM terminal\r\n\r\n[](https://www.youtube.com/watch?v=e-lqgiDWDNQ)\r\n\r\n***\r\n\r\n#### Getting screenshots of each element\r\n\r\nIn the example above, the elements are very easy to locate. However, this is not always the case.\r\nYou might want to see a screenshot of each element to write your script faster. In this case, you can use the following command on the device:\r\n\r\n```py\r\ndf.bb_save_screenshots_as_png(\"/sdcard/uiautomator2screenshots\")\r\n```\r\n\r\nThen, pull the screenshots using ADB to review them on your computer:\r\n\r\n```sh\r\nadb -s 192.168.115.131:5555 pull /sdcard/uiautomator2screenshots\r\n```\r\n\r\nThe screenshot filenames correspond to the location of the elements in the DataFrame.\r\nFor example, if you want to locate the third element (index 2), simply run:\r\n\r\n```py\r\ndf.iloc[2]\r\n```\r\nThis will extract the element\u2019s information, allowing you to build your pandas query from there.\r\n\r\n***\r\n\r\n#### Example of element screenshots\r\n\r\n\r\n[](https://www.youtube.com/watch?v=ZIs4z4xKBOU)\r\n\r\n***\r\n***\r\n\r\n## The Backends\r\n\r\n***\r\n\r\n### [Uiautomator2 Backend](https://github.com/hansalemaos/uiautomator2tocsv/tree/d5022bd0bb5864ba3b36cfb9c444f6557c2381c8)\r\n\r\n| **Advantages \u2705** | **Disadvantages \u274c** |\r\n|------------------------------------------------|----------------------------------------------------------|\r\n| Very fast parsing | Blocks other parsers like the Logcat parser and traditional UIAutomator |\r\n| Never fails due to excessive screen movement (unlike UIAutomator) | Requires APKs to be installed |\r\n| Includes both element text and description | The server needs to run in the background |\r\n| Great for web scraping and interacting with web elements | Automation might be detected when used with installed apps |\r\n| Runs on any emulator | Useless with specific engines like the Unreal Engine |\r\n\r\n***\r\n\r\n#### Video - in action\r\n\r\n[](https://www.youtube.com/watch?v=ZeXCKHQi-bE)\r\n\r\n***\r\n\r\n#### Python Code\r\n\r\n\r\n```py\r\nfrom cyandroemu import TermuxAutomation, clean_zombies\r\nimport pandas as pd\r\nfrom time import sleep as timesleep\r\nimport atexit\r\n\r\n# Ensure all background processes are terminated on exit\r\natexit.register(clean_zombies)\r\n\r\n# Load parsers (first time may take ~5 mins due to download/compilation)\r\nparsers = TermuxAutomation.load_parsers_or_download_and_compile(\"g++\")\r\n\r\n# Detect input devices dynamically (Necessary on BlissOS 16 Go with VMWare)\r\ndf_devices = TermuxAutomation.find_suitable_devices_for_input_events()\r\nscreen_width, screen_height = TermuxAutomation.get_resolution_of_screen()\r\n\r\n\r\n\r\n# Initialize TermuxAutomation with dynamic device paths\r\nte = TermuxAutomation(\r\n parsers=parsers,\r\n mouse_device=df_devices.loc[\r\n (df_devices[\"max\"].str.len() == 2) & (df_devices[\"type\"] == \"mouse\")\r\n ][\"path\"].iloc[0],\r\n keyboard_device=df_devices.loc[\r\n (df_devices[\"keys_found\"]) & (df_devices[\"type\"] == \"keyboard\")\r\n ][\"path\"].iloc[0],\r\n mouse_device_max=df_devices.loc[\r\n (df_devices[\"max\"].str.len() == 2) & (df_devices[\"type\"] == \"mouse\")\r\n ][\"max\"].iloc[0][0],\r\n screen_height=screen_height,\r\n screen_width=screen_width,\r\n)\r\n\r\n# Kill any leftover background processes\r\nte.kill_zombies()\r\n\r\n# You can install the APK using:\r\n# te.download_and_install_uiautomator2_apks()\r\n\r\n# Ensure elements are loaded on the screen instead of relying solely on sleep\r\ndf = pd.DataFrame()\r\nwhile df.empty:\r\n # First DataFrame load may take ~5 seconds (UIAutomator2 server startup)\r\n # For production scripts, set with_screenshot=False for better performance\r\n # You can also pass these kwargs to temporarily change the default paramenters passed to the class constructor (valid for all backends, but not recommended)\r\n # If you pass anything else than None, it will override the default parameters once.\r\n # add_input_tap=None,\r\n # add_sendevent_mouse_click=None,\r\n # add_sendevent_tap=None,\r\n # add_mouse_action=None,\r\n # x_column=None,\r\n # y_column=None,\r\n # mouse_device=None,\r\n # touch_device=None,\r\n # touch_device_max=None,\r\n # mouse_device_max=None,\r\n # input_cmd=None,\r\n # sendevent_path=None,\r\n # screen_height=None,\r\n # screen_width=None,\r\n # mouse_action_exe=None,\r\n # sh_exe=None,\r\n # su_exe=None,\r\n # kwargs=None,\r\n # timeout=None,\r\n df = te.get_df_uiautomator2(with_screenshot=True)\r\n # Filter elements to target the TikTok app\r\n df = df.loc[\r\n (df.aa_text == \"TikTok\")\r\n & (df.aa_content_desc == \"TikTok\")\r\n & (df.aa_clickable == 1)\r\n ]\r\n\r\n# Click the first matching element using input tap\r\n# Optional: Add offset like df.aa_input_tap.iloc[0](20, 40)\r\n\r\ndf.aa_input_tap.iloc[0]()\r\n\r\n# Clear DataFrame for the next loop\r\n\r\ndf = pd.DataFrame()\r\n\r\n# optional sleep\r\ntimesleep(2)\r\n\r\n# Repeating the same process for other UI elements\r\nwhile df.empty:\r\n df = te.get_df_uiautomator2(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_text == \"Already have an account? Log in\")\r\n & (df.aa_clazz == \"android.widget.Button\")\r\n & (df.aa_content_desc == \"\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(2)\r\nwhile df.empty:\r\n df = te.get_df_uiautomator2(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_text == \"Use phone / email / username\")\r\n & (df.aa_clazz == \"android.widget.TextView\")\r\n & (df.aa_content_desc == \"\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(2)\r\nwhile df.empty:\r\n df = te.get_df_uiautomator2(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_text == \"Email / Username\")\r\n & (df.aa_clazz == \"android.widget.TextView\")\r\n & (df.aa_content_desc == \"\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(2)\r\n\r\n# Send text input naturally using a lightweight Cython class\r\n# In this example, __call__ is used directly to enter the email once\r\n\r\nte.get_cmd_send_text_natural(\"myemailtest@gmail.com\")()\r\n```\r\n\r\n***\r\n\r\n#### Example of a Pandas DataFrame (column width cropped to 30 chars)\r\n\r\n|**index** |**aa_index** |**aa_indent** |**aa_text** |**aa_resource_id** |**aa_clazz** |**aa_package** |**aa_content_desc** |**aa_checkable** |**aa_checked** |**aa_clickable** |**aa_enabled** |**aa_focusable** |**aa_focused** |**aa_scrollable** |**aa_long_clickable** |**aa_password** |**aa_selected** |**aa_visible_to_user** |**aa_bounds** |**aa_drawing_order** |**aa_hint** |**aa_display_id** |**aa_line_index** |**aa_children** |**aa_parents** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_center_x** |**aa_center_y** |**aa_width** |**aa_height** |**aa_area** |**aa_w_h_relation** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |\r\n|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|\r\n|**0** |0 |4 | |com.android.systemui:id/status|android.widget.FrameLayout |com.android.systemui | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[0,0][1024,24] |1 | |0 |1 |() |() |0 |0 |1024 |24 |512 |12 |1024 |24 |24576 |42.666668 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**1** |0 |6 |8:18 |com.android.systemui:id/clock |android.widget.TextView |com.android.systemui |8:18 PM |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[16,0][45,24] |2 | |0 |2 |() |() |16 |0 |45 |24 |30 |12 |29 |24 |696 |1.208333 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**2** |1 |6 | | |android.widget.ImageView |com.android.systemui |Termux notification: 1 session|0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[45,0][69,24] |4 | |0 |3 |() |() |45 |0 |69 |24 |57 |12 |24 |24 |576 |1.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**3** |2 |6 | | |android.widget.ImageView |com.android.systemui |Settings notification: NECVMWa|0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[69,0][93,24] |5 | |0 |4 |() |() |69 |0 |93 |24 |81 |12 |24 |24 |576 |1.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**4** |3 |6 | | |android.widget.ImageView |com.android.systemui |Ethernet. |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[959,1][978,23] |12 | |0 |5 |() |() |959 |1 |978 |23 |968 |12 |19 |22 |418 |0.863636 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**5** |4 |6 | |com.android.systemui:id/batter|android.widget.LinearLayout |com.android.systemui |Battery percentage unknown. |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[984,0][996,24] |16 | |0 |6 |() |() |984 |0 |996 |24 |990 |12 |12 |24 |288 |0.5 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**6** |0 |2 | | |android.widget.FrameLayout |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[0,0][1024,768] |0 | |0 |7 |() |() |0 |0 |1024 |768 |512 |384 |1024 |768 |786432 |1.333333 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**7** |0 |4 | |com.zhiliaoapp.musically:id/d4|android.view.ViewGroup |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[0,24][1024,736] |1 | |0 |8 |() |() |0 |24 |1024 |736 |512 |380 |1024 |712 |729088 |1.438202 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**8** |0 |6 | |com.zhiliaoapp.musically:id/r7|android.widget.ImageView |com.zhiliaoapp.musically |Report a problem |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[4,26][52,74] |3 | |0 |9 |() |() |4 |26 |52 |74 |28 |50 |48 |48 |2304 |1.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**9** |2 |6 |Skip |com.zhiliaoapp.musically:id/p6|android.widget.Button |com.zhiliaoapp.musically | |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[980,38][1008,56] |5 | |0 |10 |() |() |980 |38 |1008 |56 |994 |47 |28 |18 |504 |1.555556 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**10** |3 |6 | |com.zhiliaoapp.musically:id/tt|androidx.viewpager.widget.View|com.zhiliaoapp.musically | |0 |0 |0 |1 |1 |0 |1 |0 |0 |0 |1 |[0,77][1024,736] |2 | |0 |11 |() |() |0 |77 |1024 |736 |512 |406 |1024 |659 |674816 |1.553869 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**11** |0 |8 | |com.zhiliaoapp.musically:id/c7|androidx.recyclerview.widget.R|com.zhiliaoapp.musically | |0 |0 |0 |1 |1 |0 |0 |0 |0 |0 |1 |[267,77][758,396] |1 | |0 |12 |() |() |267 |77 |758 |396 |512 |236 |491 |319 |156629 |1.539185 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**12** |0 |10 | | |android.widget.LinearLayout |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[267,82][758,228] |1 | |0 |13 |() |() |267 |82 |758 |228 |512 |155 |491 |146 |71686 |3.363014 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**13** |0 |12 |Sign up for TikTok |com.zhiliaoapp.musically:id/ti|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |1 |0 |0 |1 |[267,122][758,150] |1 | |0 |14 |() |() |267 |122 |758 |150 |512 |136 |491 |28 |13748 |17.535715 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**14** |1 |12 |Create a profile, follow other|com.zhiliaoapp.musically:id/oe|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[267,162][758,200] |2 | |0 |15 |() |() |267 |162 |758 |200 |512 |181 |491 |38 |18658 |12.921053 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**15** |1 |10 | |com.zhiliaoapp.musically:id/cz|android.widget.Button |com.zhiliaoapp.musically |Use phone or email |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[267,228][758,272] |2 | |0 |16 |() |() |267 |228 |758 |272 |512 |250 |491 |44 |21604 |11.159091 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**16** |0 |12 |Use phone or email |com.zhiliaoapp.musically:id/c7|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[454,241][593,260] |1 | |0 |17 |() |() |454 |241 |593 |260 |523 |250 |139 |19 |2641 |7.31579 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**17** |2 |10 | |com.zhiliaoapp.musically:id/cz|android.widget.Button |com.zhiliaoapp.musically |Continue with Facebook |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[267,284][758,328] |3 | |0 |18 |() |() |267 |284 |758 |328 |512 |306 |491 |44 |21604 |11.159091 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**18** |0 |12 |Continue with Facebook |com.zhiliaoapp.musically:id/c7|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[437,297][611,316] |1 | |0 |19 |() |() |437 |297 |611 |316 |524 |306 |174 |19 |3306 |9.157895 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**19** |3 |10 | |com.zhiliaoapp.musically:id/cz|android.widget.Button |com.zhiliaoapp.musically |Continue with Google |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[267,340][758,384] |4 | |0 |20 |() |() |267 |340 |758 |384 |512 |362 |491 |44 |21604 |11.159091 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**20** |0 |12 |Continue with Google |com.zhiliaoapp.musically:id/c7|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |1 |[445,353][602,371] |1 | |0 |21 |() |() |445 |353 |602 |371 |523 |362 |157 |18 |2826 |8.722222 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**21** |1 |8 |By continuing with an account |com.zhiliaoapp.musically:id/rw|android.widget.TextView |com.zhiliaoapp.musically | |0 |0 |0 |1 |1 |0 |0 |0 |0 |0 |1 |[32,628][992,675] |3 | |0 |22 |() |() |32 |628 |992 |675 |512 |651 |960 |47 |45120 |20.425531 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**22** |2 |8 |Already have an account? Log i|com.zhiliaoapp.musically:id/s5|android.widget.Button |com.zhiliaoapp.musically | |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |1 |[0,676][1024,736] |7 | |0 |23 |() |() |0 |676 |1024 |736 |512 |706 |1024 |60 |61440 |17.066668 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[248 248 248] [248 248 248|\r\n\r\n***\r\n***\r\n\r\n### [LogCat Parser Backend](https://github.com/hansalemaos/elparse/tree/f7256f182323d5fb74c0403c37f36fde40143d36)\r\n\r\n| **Advantages \u2705** | **Disadvantages \u274c** |\r\n|---------------------------------------------------------------|----------------------------------------------------------------|\r\n| Very fast parsing with extremely low CPU usage | Requires interaction with elements or changes in element status |\r\n| Detects elements that are not even visible on the screen | Requires APKs to be installed |\r\n| Includes both element text and description | Needs to run as an Accessibility Service |\r\n| Great for web scraping and interacting with web elements | Automation might be detected when used with installed apps |\r\n| Doesn\u2019t block the classic UIAutomator | Ineffective with specific engines like Unreal Engine |\r\n| Automatically captures any element changes\u2014perfect for crypto, sports betting | Best results achieved on emulators with a mouse device (e.g., BlissOS, BlueStacks) |\r\n\r\n***\r\n\r\n#### Video - in action\r\n\r\n\r\n[](https://www.youtube.com/watch?v=DEUOs9wnufY)\r\n\r\n\r\n***\r\n\r\n#### Python Code\r\n\r\n\r\n```py\r\n\r\n# Imports and instance creation omitted for brevity\r\n\r\ndf = pd.DataFrame()\r\n# Loop to find the TikTok element and click it\r\n\r\nwhile df.empty:\r\n # Moves the mouse horizontally and vertically to provoke interaction with all elements on the screen\r\n # Works on BlueStacks 5 and BlissOS with VMware, and probably some other emulators\r\n df = te.get_df_lcp_with_mouse_movement()\r\n df = df.loc[\r\n (df.aa_Text == \"TikTok\")\r\n & (df.aa_ContentDescription == \"TikTok\")\r\n & (df.aa_ClassName == \"android.widget.TextView\")\r\n ]\r\n\r\n# Clear the DataFrame for the next interaction\r\ndf.aa_input_tap.iloc[0]()\r\ntimesleep(2)\r\ndf = pd.DataFrame()\r\nwhile df.empty:\r\n df = te.get_df_lcp_with_mouse_movement()\r\n df = df.loc[\r\n (df.aa_Text == \"Already have an account? Log in\")\r\n & (df.aa_ContentDescription == \"null\")\r\n & (df.aa_ClassName == \"android.widget.Button\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ntimesleep(2)\r\ndf = pd.DataFrame()\r\nwhile df.empty:\r\n df = te.get_df_lcp_with_mouse_movement()\r\n df = df.loc[\r\n (df.aa_Text == \"null\")\r\n & (df.aa_ContentDescription == \"Use phone / email / username\")\r\n & (df.aa_ClassName == \"android.widget.Button\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ntimesleep(2)\r\ndf = pd.DataFrame()\r\nwhile df.empty:\r\n df = te.get_df_lcp_with_mouse_movement()\r\n df = df.loc[\r\n (df.aa_Text == \"null\")\r\n & (df.aa_ContentDescription == \"Email / Username\")\r\n & (df.aa_ClassName == \"android.widget.LinearLayout\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ntimesleep(2)\r\nte.get_cmd_send_text_natural(\"myemailtest@gmail.com\")()\r\n```\r\n\r\n***\r\n\r\n#### Example of a Pandas DataFrame (column width cropped to 30 chars)\r\n\r\n|**index** |**aa_Text** |**aa_ContentDescription** |**aa_StateDescription** |**aa_ClassName** |**aa_PackageName** |**aa_Error** |**aa_AccessNodeInfo** |**aa_WindowId** |**aa_WindowChanges** |**aa_WindowChangeTypes** |**aa_VirtualDescendantId** |**aa_ViewIdResName** |**aa_UniqueId** |**aa_TraversalBefore** |**aa_TraversalAfter** |**aa_TooltipText** |**aa_TimeStamp** |**aa_TimeNow** |**aa_SpeechStateChangeTypes** |**aa_SourceWindowId** |**aa_SourceNodeId** |**aa_SourceDisplayId** |**aa_Source** |**aa_Sealed** |**aa_Records** |**aa_ParentNodeId** |**aa_ParcelableData** |**aa_MovementGranularities** |**aa_HashCode** |**aa_EventType** |**aa_Actions** |**aa_ContentChangeTypes** |**aa_ConnectionId** |**aa_ChildAccessibilityIds** |**aa_BooleanProperties** |**aa_BeforeText** |**aa_Active** |**aa_AccessibilityViewId** |**aa_AccessibilityTool** |**aa_BoundsInScreen** |**aa_BoundsInParent** |**aa_UnixTimeText** |**aa_start_x_real** |**aa_start_y_real** |**aa_end_x_real** |**aa_end_y_real** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_center_x** |**aa_center_y** |**aa_width** |**aa_height** |**aa_w_h_relation** |**aa_area** |**aa_parent_start_x_real** |**aa_parent_start_y_real** |**aa_parent_end_x_real** |**aa_parent_end_y_real** |**aa_parent_start_x** |**aa_parent_start_y** |**aa_parent_end_x** |**aa_parent_end_y** |**aa_parent_center_x** |**aa_parent_center_y** |**aa_parent_width** |**aa_parent_height** |**aa_parent_w_h_relation** |**aa_parent_area** |**aa_UnixTime** |**aa_distance_from_start** |**aa_size** |**aa_Visible** |**aa_Password** |**aa_Selected** |**aa_Scrollable** |**aa_LongClickable** |**aa_Loggable** |**aa_IsTextSelectable** |**aa_ImportantForAccessibility|**aa_Enabled** |**aa_Empty** |**aa_ContextClickable** |**aa_ContentInvalid** |**aa_FullScreen** |**aa_Focused** |**aa_Focusable** |**aa_AccessibilityFocused** |**aa_AccessibilityDataSensitiv|**aa_Clickable** |**aa_Checked** |**aa_Checkable** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |\r\n|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|\r\n|**0** |null |null |null |android.widget.LinearLayout |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(267, 82 - 758, 228) |Rect(0, 0 - 491, 146) |02-06 20:16:04.651 |267 |82 |758 |228 |267 |82 |758 |228 |512 |155 |491 |146 |3.363013698630137 |71686 |0 |0 |491 |146 |0 |0 |491 |146 |245 |73.0 |491.0 |146.0 |3.363013698630137 |71686.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**1** |Sign up for TikTok |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(267, 122 - 758, 150) |Rect(0, 0 - 491, 28) |02-06 20:16:04.651 |267 |122 |758 |150 |267 |122 |758 |150 |512 |136 |491 |28 |17.535714285714285 |13748 |0 |0 |491 |28 |0 |0 |491 |28 |245 |14.0 |491.0 |28.0 |17.535714285714285 |13748.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**2** |null |null |null |androidx.recyclerview.widget.R|com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(267, 77 - 758, 396) |Rect(0, 0 - 491, 319) |02-06 20:16:04.651 |267 |77 |758 |396 |267 |77 |758 |396 |512 |236 |491 |319 |1.5391849529780564 |156629 |0 |0 |491 |319 |0 |0 |491 |319 |245 |159.0 |491.0 |319.0 |1.5391849529780564 |156629.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**3** |Sign up for TikTok |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(52, 24 - 201, 76) |Rect(0, 0 - 149, 52) |02-06 20:16:04.651 |52 |24 |201 |76 |52 |24 |201 |76 |126 |50 |149 |52 |2.8653846153846154 |7748 |0 |0 |149 |52 |0 |0 |149 |52 |74 |26.0 |149.0 |52.0 |2.8653846153846154 |7748.0 |1738883764651.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**4** |Skip |null |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(980, 38 - 1008, 56) |Rect(0, 0 - 28, 18) |02-06 20:16:04.651 |980 |38 |1008 |56 |980 |38 |1008 |56 |994 |47 |28 |18 |1.5555555555555556 |504 |0 |0 |28 |18 |0 |0 |28 |18 |14 |9.0 |28.0 |18.0 |1.5555555555555556 |504.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**5** |null |Report a problem |null |android.widget.ImageView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(4, 26 - 52, 74) |Rect(0, 0 - 48, 48) |02-06 20:16:04.651 |4 |26 |52 |74 |4 |26 |52 |74 |28 |50 |48 |48 |1.0 |2304 |0 |0 |48 |48 |0 |0 |48 |48 |24 |24.0 |48.0 |48.0 |1.0 |2304.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**6** |null |null |null |androidx.viewpager.widget.View|com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(0, 77 - 1024, 736) |Rect(0, 0 - 1024, 659) |02-06 20:16:04.651 |0 |77 |1024 |736 |0 |77 |1024 |736 |512 |406 |1024 |659 |1.5538694992412747 |674816 |0 |0 |1024 |659 |0 |0 |1024 |659 |512 |329.0 |1024.0 |659.0 |1.5538694992412747 |674816.0 |1738883764651.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**7** |null |null |null |android.view.ViewGroup |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(0, 24 - 1024, 736) |Rect(0, 0 - 1024, 712) |02-06 20:16:04.623 |0 |24 |1024 |736 |0 |24 |1024 |736 |512 |380 |1024 |712 |1.4382022471910112 |729088 |0 |0 |1024 |712 |0 |0 |1024 |712 |512 |356.0 |1024.0 |712.0 |1.4382022471910112 |729088.0 |1738883764623.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**8** |Continue with Google |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1469, 352 - 1024, 370) |Rect(0, 0 - 157, 18) |02-06 20:16:04.622 |1469 |352 |1024 |370 |1469 |352 |1024 |370 |1246 |361 |-445 |18 |-24.72222222222222 |-8010 |0 |0 |157 |18 |0 |0 |157 |18 |78 |9.0 |157.0 |18.0 |8.722222222222221 |2826.0 |1738883764622.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**9** |By continuing with an account |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(32, 628 - 992, 675) |Rect(0, 0 - 960, 47) |02-06 20:16:04.621 |32 |628 |992 |675 |32 |628 |992 |675 |512 |651 |960 |47 |20.425531914893615 |45120 |0 |0 |960 |47 |0 |0 |960 |47 |480 |23.0 |960.0 |47.0 |20.425531914893615 |45120.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**10** |Continue with Google |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(445, 353 - 602, 371) |Rect(0, 0 - 157, 18) |02-06 20:16:04.621 |445 |353 |602 |371 |445 |353 |602 |371 |523 |362 |157 |18 |8.722222222222221 |2826 |0 |0 |157 |18 |0 |0 |157 |18 |78 |9.0 |157.0 |18.0 |8.722222222222221 |2826.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**11** |Manage your account, check not|null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1291, 162 - 1024, 199) |Rect(0, 0 - 491, 37) |02-06 20:16:04.621 |1291 |162 |1024 |199 |1291 |162 |1024 |199 |1157 |180 |-267 |37 |-7.216216216216216 |-9879 |0 |0 |491 |37 |0 |0 |491 |37 |245 |18.0 |491.0 |37.0 |13.27027027027027 |18167.0 |1738883764621.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**12** |Log in to TikTok |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1291, 122 - 1024, 150) |Rect(0, 0 - 491, 28) |02-06 20:16:04.621 |1291 |122 |1024 |150 |1291 |122 |1024 |150 |1157 |136 |-267 |28 |-9.535714285714286 |-7476 |0 |0 |491 |28 |0 |0 |491 |28 |245 |14.0 |491.0 |28.0 |17.535714285714285 |13748.0 |1738883764621.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**13** |null |null |null |android.widget.LinearLayout |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1291, 82 - 1024, 227) |Rect(0, 0 - 491, 145) |02-06 20:16:04.621 |1291 |82 |1024 |227 |1291 |82 |1024 |227 |1157 |154 |-267 |145 |-1.8413793103448275 |-38715 |0 |0 |491 |145 |0 |0 |491 |145 |245 |72.0 |491.0 |145.0 |3.386206896551724 |71195.0 |1738883764621.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**14** |null |null |null |androidx.recyclerview.widget.R|com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1291, 77 - 1024, 451) |Rect(0, 0 - 491, 374) |02-06 20:16:04.621 |1291 |77 |1024 |451 |1291 |77 |1024 |451 |1157 |264 |-267 |374 |-0.713903743315508 |-99858 |0 |0 |491 |374 |0 |0 |491 |374 |245 |187.0 |491.0 |374.0 |1.3128342245989304 |183634.0 |1738883764621.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**15** |Already have an account? Log i|null |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(0, 676 - 1024, 736) |Rect(0, 0 - 1024, 60) |02-06 20:16:04.621 |0 |676 |1024 |736 |0 |676 |1024 |736 |512 |706 |1024 |60 |17.066666666666666 |61440 |0 |0 |1024 |60 |0 |0 |1024 |60 |512 |30.0 |1024.0 |60.0 |17.066666666666666 |61440.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[248 248 248] [248 248 248|\r\n|**16** |Create a profile, follow other|null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(267, 162 - 758, 200) |Rect(0, 0 - 491, 38) |02-06 20:16:04.621 |267 |162 |758 |200 |267 |162 |758 |200 |512 |181 |491 |38 |12.921052631578949 |18658 |0 |0 |491 |38 |0 |0 |491 |38 |245 |19.0 |491.0 |38.0 |12.921052631578949 |18658.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**17** |null |Use phone or email |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(267, 228 - 758, 272) |Rect(0, 0 - 491, 44) |02-06 20:16:04.621 |267 |228 |758 |272 |267 |228 |758 |272 |512 |250 |491 |44 |11.159090909090908 |21604 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**18** |Use phone or email |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(454, 241 - 593, 260) |Rect(0, 0 - 139, 19) |02-06 20:16:04.621 |454 |241 |593 |260 |454 |241 |593 |260 |523 |250 |139 |19 |7.315789473684211 |2641 |0 |0 |139 |19 |0 |0 |139 |19 |69 |9.0 |139.0 |19.0 |7.315789473684211 |2641.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**19** |null |Continue with Facebook |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(267, 284 - 758, 328) |Rect(0, 0 - 491, 44) |02-06 20:16:04.621 |267 |284 |758 |328 |267 |284 |758 |328 |512 |306 |491 |44 |11.159090909090908 |21604 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**20** |Continue with Facebook |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(437, 297 - 611, 316) |Rect(0, 0 - 174, 19) |02-06 20:16:04.621 |437 |297 |611 |316 |437 |297 |611 |316 |524 |306 |174 |19 |9.157894736842104 |3306 |0 |0 |174 |19 |0 |0 |174 |19 |87 |9.0 |174.0 |19.0 |9.157894736842104 |3306.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**21** |null |Continue with Google |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(267, 340 - 758, 384) |Rect(0, 0 - 491, 44) |02-06 20:16:04.621 |267 |340 |758 |384 |267 |340 |758 |384 |512 |362 |491 |44 |11.159090909090908 |21604 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764621.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**22** |null |Continue with Instagram |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1291, 395 - 1024, 439) |Rect(0, 0 - 491, 44) |02-06 20:16:04.620 |1291 |395 |1024 |439 |1291 |395 |1024 |439 |1157 |417 |-267 |44 |-6.068181818181818 |-11748 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**23** |Use phone / email / username |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1440, 240 - 1024, 259) |Rect(0, 0 - 216, 19) |02-06 20:16:04.620 |1440 |240 |1024 |259 |1440 |240 |1024 |259 |1232 |249 |-416 |19 |-21.894736842105264 |-7904 |0 |0 |216 |19 |0 |0 |216 |19 |108 |9.0 |216.0 |19.0 |11.36842105263158 |4104.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**24** |Continue with Instagram |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(1459, 408 - 1024, 426) |Rect(0, 0 - 177, 18) |02-06 20:16:04.620 |1459 |408 |1024 |426 |1459 |408 |1024 |426 |1241 |417 |-435 |18 |-24.166666666666668 |-7830 |0 |0 |177 |18 |0 |0 |177 |18 |88 |9.0 |177.0 |18.0 |9.833333333333334 |3186.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**25** |null |null |null |android.widget.FrameLayout |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_S| | | | | | | | |Rect(0, 0 - 1024, 768) |Rect(0, 0 - 1024, 768) |02-06 20:16:04.620 |0 |0 |1024 |768 |0 |0 |1024 |768 |512 |384 |1024 |768 |1.3333333333333333 |786432 |0 |0 |1024 |768 |0 |0 |1024 |768 |512 |384.0 |1024.0 |768.0 |1.3333333333333333 |786432.0 |1738883764620.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**26** |Don\u2019t have an account? Sign up|null |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1024, 676 - 1024, 736) |Rect(0, 0 - 1024, 60) |02-06 20:16:04.620 |1024 |676 |1024 |736 |1024 |676 |1024 |736 |1024 |706 |0 |60 |0.0 |0 |0 |0 |1024 |60 |0 |0 |1024 |60 |512 |30.0 |1024.0 |60.0 |17.066666666666666 |61440.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**27** |By continuing with an account |null |null |android.widget.TextView |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1056, 628 - 1024, 675) |Rect(0, 0 - 960, 47) |02-06 20:16:04.620 |1056 |628 |1024 |675 |1056 |628 |1024 |675 |1040 |651 |-32 |47 |-0.6808510638297872 |-1504 |0 |0 |960 |47 |0 |0 |960 |47 |480 |23.0 |960.0 |47.0 |20.425531914893615 |45120.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**28** |null |Continue with Google |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1291, 339 - 1024, 383) |Rect(0, 0 - 491, 44) |02-06 20:16:04.620 |1291 |339 |1024 |383 |1291 |339 |1024 |383 |1157 |361 |-267 |44 |-6.068181818181818 |-11748 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**29** |null |Continue with Facebook |null |android.widget.Button |com.zhiliaoapp.musically |null |android.view.accessibility.Acc| | | | |null |null | | |null | | | | | | | | | | | | | | |[AccessibilityAction: ACTION_F| | | | | | | | |Rect(1291, 283 - 1024, 327) |Rect(0, 0 - 491, 44) |02-06 20:16:04.620 |1291 |283 |1024 |327 |1291 |283 |1024 |327 |1157 |305 |-267 |44 |-6.068181818181818 |-11748 |0 |0 |491 |44 |0 |0 |491 |44 |245 |22.0 |491.0 |44.0 |11.159090909090908 |21604.0 |1738883764620.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |0.0 |0.0 |1.0 |0.0 |0.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[]\r\n\r\n***\r\n***\r\n\r\n### [Tesseract Backend](https://github.com/hansalemaos/screencap2tesseract2csv)\r\n\r\n| **Advantages \u2705** | **Disadvantages \u274c** |\r\n|---------------------------------------------------------------|----------------------------------------------------------------|\r\n| Detects (in theory) all text on the screen | Higher CPU usage compared to other parsers |\r\n| Works with Unreal Engine and Roblox games | May produce inaccurate results (mostly resolved by fast C++-implemented Levenshtein distance calculation) |\r\n| Can categorize elements (image, text, line, etc.) | Requires additional downloads |\r\n| Undetectable | Needs a screenshot to function |\r\n| Can be used alongside any other parser | \u2014 |\r\n\r\n***\r\n\r\n#### Video - in action\r\n\r\n\r\n[](https://www.youtube.com/watch?v=bHCQjBHCEvM)\r\n\r\n***\r\n\r\n#### Python Code\r\n\r\n\r\n```py\r\n\r\n# Imports and instance creation omitted for brevity\r\n\r\ndf = pd.DataFrame()\r\n# Loop to find the \"TikTok\" element and click it\r\n\r\nwhile df.empty:\r\n # word_group_limit: groups words within 40 pixels\r\n df = te.get_df_tesseract_fast(with_screenshot=True, word_group_limit=40)\r\n # OCR is often not 100% accurate, so we use double Damerau-Levenshtein distance\r\n # (right-to-left and left-to-right) to improve matching accuracy.\r\n # - First argument: list of strings to locate\r\n # - Second argument: column where the text exists in the DataFrame\r\n # - Third argument: new column name for matched results\r\n\r\n # There are 3 methods to get the DataFrame:\r\n # The first time you call one of these methods, the required models will be downloaded automatically:\r\n # - te.get_df_tesseract_fast -> uses models from \"https://github.com/tesseract-ocr/tessdata_fast\"\r\n # - te.get_df_tesseract -> uses models from \"https://github.com/tesseract-ocr/tessdata\"\r\n # - te.get_df_tesseract_best -> uses models from \"https://github.com/tesseract-ocr/tessdata_best\"\r\n\r\n df = df.d_fm_damerau_levenshtein_distance_2ways(\r\n [\"TikTok\"], \"aa_text\", \"aa_searchfortext\"\r\n ).sort_values(by=[\"damerau_levenshtein_distance_2ways_match\"], ascending=False)\r\n\r\n # Filter: keeping matches with a Damerau-Levenshtein distance < 2.1\r\n df = df.loc[df[\"damerau_levenshtein_distance_2ways_match\"] < 2.1]\r\n\r\n# Perform the tap on the best match\r\ndf.aa_input_tap.iloc[0]()\r\ntimesleep(2)\r\n\r\n# Clear DataFrame for the next interaction\r\ndf = pd.DataFrame()\r\n\r\n# Loop to find the \"Already have an account? Log in\" button and click it\r\nwhile df.empty:\r\n df = te.get_df_tesseract_fast(with_screenshot=True, word_group_limit=40)\r\n df = df.d_fm_damerau_levenshtein_distance_2ways(\r\n [\"Already have an account? Log in\"], \"aa_text\", \"aa_searchfortext\"\r\n ).sort_values(by=[\"damerau_levenshtein_distance_2ways_match\"], ascending=False)\r\n df = df.loc[df[\"damerau_levenshtein_distance_2ways_match\"] < 2.1]\r\n\r\ndf.aa_input_tap.iloc[0]()\r\ntimesleep(2)\r\n\r\ndf = pd.DataFrame()\r\n# Loop to find the \"Use phone / email / username\" button and click it\r\nwhile df.empty:\r\n df = te.get_df_tesseract_fast(with_screenshot=True, word_group_limit=40)\r\n df = df.d_fm_damerau_levenshtein_distance_2ways(\r\n [\"Use phone / email / username\"], \"aa_text\", \"aa_searchfortext\"\r\n ).sort_values(by=[\"damerau_levenshtein_distance_2ways_match\"], ascending=False)\r\n df = df.loc[df[\"damerau_levenshtein_distance_2ways_match\"] < 2.1]\r\n\r\ndf.aa_input_tap.iloc[0]()\r\ntimesleep(2)\r\n\r\ndf = pd.DataFrame()\r\n# Loop to find the \"Log in\" button and click it\r\n\r\nwhile df.empty:\r\n df = te.get_df_tesseract_fast(with_screenshot=True, word_group_limit=40)\r\n df = df.d_fm_damerau_levenshtein_distance_2ways(\r\n [\"Log in\"],\r\n \"aa_text\",\r\n \"aa_searchfortext\", # Tesseract fails to get \"Email / Username\" text\r\n ).sort_values(by=[\"damerau_levenshtein_distance_2ways_match\"], ascending=False)\r\n df = df.loc[df[\"damerau_levenshtein_distance_2ways_match\"] < 2.1]\r\n\r\n# Clicking with an offset (90, 50) as Tesseract may miss the light gray \"Email / Username\" text\r\ndf.aa_input_tap.iloc[0](90, 50)\r\ntimesleep(2)\r\n\r\n# Sending the email input naturally\r\nte.get_cmd_send_text_natural(\"myemailtest@gmail.com\")()\r\n```\r\n\r\n***\r\n\r\n#### Example of a Pandas DataFrame (column width cropped to 30 chars)\r\n\r\n|**index** |**aa_text** |**aa_text_group** |**aa_word** |**aa_title** |**aa_id** |**aa_lang** |**aa_clazz** |**aa_tag** |**aa_bbox** |**aa_baseline** |**aa_poly** |**aa_x_bboxes** |**aa_x_font** |**aa_x_fsize** |**aa_x_size** |**aa_x_ascenders** |**aa_x_descenders** |**aa_x_wconf** |**aa_x_confs** |**aa_x_mpconf** |**aa_line_conf** |**aa_char_conf** |**aa_ppageno** |**aa_block_num** |**aa_par_num** |**aa_line_num** |**aa_word_num** |**aa_image** |**aa_scan_res** |**aa_rotate** |**aa_x_line_bboxes** |**aa_x_line_confs** |**aa_x_text** |**aa_line_index** |**aa_children** |**aa_parents** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_center_x** |**aa_center_y** |**aa_width** |**aa_height** |**aa_area** |**aa_w_h_relation** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |\r\n|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|\r\n|**21** | |-1 | |bbox 413 126 612 149baseline |line_1_5 | |ocr_line | |413 126 612 149 |0 -5 | | | | |23 |5 |5 | | | | | | | | | | | | | | | | |34 |() |() |413 |126 |612 |149 |512 |137 |199 |23 |4577 |8.652174 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**22** |Sign up for TikTok |6 |Sign |bbox 413 126 461 149x_wconf 9|word_1_7 | |ocrx_word | |413 126 461 149 | | | | |24 | | | |96 | | | | | | | | | | | | | | | |35 |() |() |413 |126 |461 |149 |437 |137 |48 |23 |1104 |2.086957 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**23** |Sign up for TikTok |6 |up |bbox 468 131 495 149x_wconf 9|word_1_8 | |ocrx_word | |468 131 495 149 | | | | |24 | | | |94 | | | | | | | | | | | | | | | |36 |() |() |468 |131 |495 |149 |481 |140 |27 |18 |486 |1.5 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[206 206 206] [147 147 147|\r\n|**24** |Sign up for TikTok |6 |for |bbox 502 127 532 144x_wconf 9|word_1_9 | |ocrx_word | |502 127 532 144 | | | | |24 | | | |93 | | | | | | | | | | | | | | | |37 |() |() |502 |127 |532 |144 |517 |135 |30 |17 |510 |1.764706 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**25** |Sign up for TikTok |6 |TikTok |bbox 539 126 612 144x_wconf 9|word_1_10 | |ocrx_word | |539 126 612 144 | | | | |24 | | | |92 | | | | | | | | | | | | | | | |38 |() |() |539 |126 |612 |144 |575 |135 |73 |18 |1314 |4.055556 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**26** | |-1 | |bbox 500 158 742 165 |block_1_6 | |ocr_photo | |500 158 742 165 | | | | | | | | | | | | | | | | | | | | | | | | |42 |() |() |500 |158 |742 |165 |621 |161 |242 |7 |1694 |34.571429 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**27** | |-1 | |bbox 486 169 500 177 |block_1_7 | |ocr_carea | |486 169 500 177 | | | | | | | | | | | | | | | | | | | | | | | | |43 |() |() |486 |169 |500 |177 |493 |173 |14 |8 |112 |1.75 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[251 251 251] [191 191 191|\r\n|**28** | |-1 | |bbox 486 169 500 177 |par_1_6 |eng |ocr_par | |486 169 500 177 | | | | | | | | | | | | | | | | | | | | | | | | |44 |() |() |486 |169 |500 |177 |493 |173 |14 |8 |112 |1.75 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[251 251 251] [191 191 191|\r\n|**29** | |-1 | |bbox 486 169 500 177baseline |line_1_6 | |ocr_line | |486 169 500 177 |0 -6 | | | | |20 |5 |5 | | | | | | | | | | | | | | | | |45 |() |() |486 |169 |500 |177 |493 |173 |14 |8 |112 |1.75 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[251 251 251] [191 191 191|\r\n|**30** |ac file, follow othe |7 |ac |bbox 486 169 500 177x_wconf 8|word_1_11 | |ocrx_word | |486 169 500 177 | | | | |21 | | | |87 | | | | | | | | | | | | | | | |46 |() |() |486 |169 |500 |177 |493 |173 |14 |8 |112 |1.75 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[251 251 251] [191 191 191|\r\n|**31** | |-1 | |bbox 364 166 527 196 |block_1_8 | |ocr_carea | |364 166 527 196 | | | | | | | | | | | | | | | | | | | | | | | | |50 |() |() |364 |166 |527 |196 |445 |181 |163 |30 |4890 |5.433333 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [249 249 249|\r\n|**32** | |-1 | |bbox 364 166 527 196 |par_1_7 |eng |ocr_par | |364 166 527 196 | | | | | | | | | | | | | | | | | | | | | | | | |51 |() |() |364 |166 |527 |196 |445 |181 |163 |30 |4890 |5.433333 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [249 249 249|\r\n|**33** | |-1 | |bbox 364 166 474 177baseline |line_1_7 | |ocr_line | |364 166 474 177 |0 0 | | | | |20 |5 |5 | | | | | | | | | | | | | | | | |52 |() |() |364 |166 |474 |177 |419 |171 |110 |11 |1210 |10.0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [249 249 249|\r\n|**34** |ac file, follow othe |7 |file, |bbox 364 169 384 177x_wconf 8|word_1_12 | |ocrx_word | |364 169 384 177 | | | | |21 | | | |89 | | | | | | | | | | | | | | | |53 |() |() |364 |169 |384 |177 |374 |173 |20 |8 |160 |2.5 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[149 149 149] [133 133 133|\r\n|**35** |ac file, follow othe |7 |follow |bbox 396 166 436 177x_wconf 9|word_1_13 | |ocrx_word | |396 166 436 177 | | | | |21 | | | |96 | | | | | | | | | | | | | | | |54 |() |() |396 |166 |436 |177 |416 |171 |40 |11 |440 |3.636364 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [215 215 215|\r\n|**36** |ac file, follow othe |7 |othe |bbox 444 166 474 177x_wconf 9|word_1_14 | |ocrx_word | |444 166 474 177 | | | | |21 | | | |96 | | | | | | | | | | | | | | | |55 |() |() |444 |166 |474 |177 |459 |171 |30 |11 |330 |2.727273 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**37** | |-1 | |bbox 494 188 527 196baseline |line_1_8 | |ocr_line | |494 188 527 196 |0 0 | | | | |20 |5 |5 | | | | | | | | | | | | | | | | |57 |() |() |494 |188 |527 |196 |510 |192 |33 |8 |264 |4.125 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[166 166 166] [219 219 219|\r\n\r\n***\r\n***\r\n\r\n### [Fragment Parser Backend](https://github.com/hansalemaos/android_fragment_parser)\r\n\r\n| **Advantages \u2705** | **Disadvantages \u274c** |\r\n|---------------------------------------------------------------|----------------------------------------------------------------|\r\n| The fastest of all parsers | Results don\u2019t include the element\u2019s text |\r\n| Very low CPU usage | Sometimes misses elements that UIAutomator-based parsers can detect |\r\n| Can be used alongside any other parser | \u2014 |\r\n| Provides useful additional information that other parsers don\u2019t have | \u2014 |\r\n| Can find elements that UIAutomator-based parsers can\u2019t detect | \u2014 |\r\n| Undetectable | \u2014 |\r\n| Highly reliable\u2014never fails | \u2014 |\r\n\r\n\r\n***\r\n\r\n#### Video - in action\r\n\r\n\r\n[](https://www.youtube.com/watch?v=wp7vg15pIMA)\r\n\r\n***\r\n\r\n#### Python Code\r\n\r\n\r\n\r\n```py\r\n\r\n# Imports and instance creation omitted for brevity\r\n\r\n\r\ndf = pd.DataFrame()\r\n# Loop to find and interact with the first target element\r\n\r\nwhile df.empty:\r\n # Many elements in the DataFrame are repeated intentionally to observe parent/child relationships.\r\n # However, with_screenshot=True remains efficient because it crops the numpy arrays only once per element.\r\n df = te.get_df_fragments(with_screenshot=True)\r\n df = df.loc[\r\n (\r\n df.aa_classname\r\n == \"com.android.launcher3.views.DoubleShadowBubbleTextView\"\r\n )\r\n & (df.aa_rel_width_height > 1)\r\n & (df.aa_clickable == \"C\")\r\n & (df.aa_drawn == \"D\")\r\n & (df.aa_enabled == \"E\")\r\n & (df.aa_focusable == \"F\")\r\n & (df.aa_long_clickable == \"L\")\r\n & (df.aa_visibility == \"V\")\r\n & (df.aa_is_child)\r\n & (df.aa_screenshot.str.len() > 0) # It's a numpy array, but this works as expected\r\n ].sort_values(by=[\"aa_start_y\"])\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(10)\r\n\r\n\r\nwhile df.empty:\r\n df = te.get_df_fragments(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_classname == \"com.bytedance.tux.input.TuxTextView\")\r\n & (df.aa_rel_width_height > 15)\r\n & (df.aa_clickable == \"C\")\r\n & (df.aa_enabled == \"E\")\r\n & (df.aa_focusable == \"F\")\r\n & (df.aa_visibility == \"V\")\r\n & (df.aa_drawn == \"D\")\r\n & (df.aa_is_child)\r\n & (df.aa_long_clickable == \".\")\r\n & (df.aa_screenshot.str.len() > 0)\r\n ].sort_values(by=[\"aa_start_x\", \"aa_start_y_relative\"])\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(3)\r\n\r\n\r\nwhile df.empty:\r\n df = te.get_df_fragments(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_classname == \"com.bytedance.tux.input.TuxTextView\")\r\n & (df.aa_rel_width_height > 6)\r\n & (df.aa_rel_width_height < 9)\r\n & (df.aa_enabled == \"E\")\r\n & (df.aa_visibility == \"V\")\r\n & (df.aa_drawn == \"D\")\r\n & (df.aa_clickable == \".\")\r\n & (df.aa_focusable == \".\")\r\n & (df.aa_is_child)\r\n & (df.aa_long_clickable == \".\")\r\n & (df.aa_screenshot.str.len() > 0)\r\n ].sort_values(by=[\"aa_start_y\"])\r\ndf.aa_input_tap.iloc[0]()\r\n\r\ndf = pd.DataFrame()\r\ntimesleep(3)\r\nwhile df.empty:\r\n df = te.get_df_fragments(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_classname == \"X.iti\")\r\n & (df.aa_rel_width_height > 3)\r\n & (df.aa_rel_width_height < 6)\r\n & (df.aa_enabled == \"E\")\r\n & (df.aa_visibility == \"V\")\r\n & (df.aa_drawn == \".\")\r\n & (df.aa_clickable == \"C\")\r\n & (df.aa_focusable == \"F\")\r\n & (~df.aa_is_child)\r\n & (df.aa_long_clickable == \".\")\r\n & (df.aa_screenshot.str.len() > 0)\r\n ].sort_values(by=[\"aa_start_x\"], ascending=[False])\r\ndf.aa_input_tap.iloc[0]()\r\ntimesleep(2)\r\n# Send the email input naturally\r\nte.get_cmd_send_text_natural(\"myemailtest@gmail.com\")()\r\n\r\n\r\n```\r\n\r\n***\r\n\r\n#### Example of a Pandas DataFrame (column width cropped to 30 chars)\r\n\r\n|**index** |**aa_my_id** |**aa_my_group_id** |**aa_my_element_id** |**aa_my_direct_parent_id** |**aa_my_parent_ids** |**aa_original_string** |**aa_center_x** |**aa_center_y** |**aa_area** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_height** |**aa_width** |**aa_is_sqare** |**aa_rel_width_height** |**aa_hashcode_int** |**aa_mid_int** |**aa_spaces** |**aa_classname** |**aa_element_id** |**aa_hashcode** |**aa_mid** |**aa_start_x_relative** |**aa_end_x_relative** |**aa_start_y_relative** |**aa_end_y_relative** |**aa_clickable** |**aa_context_clickable** |**aa_drawn** |**aa_enabled** |**aa_focusable** |**aa_long_clickable** |**aa_pflag_activated** |**aa_pflag_dirty_mask** |**aa_pflag_focused** |**aa_pflag_hovered** |**aa_pflag_invalidated** |**aa_pflag_is_root_namespace**|**aa_pflag_prepressed** |**aa_pflag_selected** |**aa_scrollbars_horizontal** |**aa_scrollbars_vertical** |**aa_visibility** |**aa_is_child** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |\r\n|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|\r\n|**0** |92 |0 |0 |0 | |android.view.View{7181534 V.ED|512 |752 |32768 |0 |736 |1024 |768 |32 |1024 |0 |32.0 |119018804 |16908336 |8 |android.view.View |android:id/navigationBarBackgr|7181534 |1020030 |0 |1024 |736 |768 |. |. |D |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**1** |91 |1 |0 |0 | |android.view.View{2b0fec9 V.ED|512 |12 |24576 |0 |0 |1024 |24 |24 |1024 |0 |42.666668 |45153993 |16908335 |8 |android.view.View |android:id/statusBarBackground|2b0fec9 |102002f |0 |1024 |0 |24 |. |. |D |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**2** |0 |2 |0 |0 | |android.widget.LinearLayout{2b|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |45420503 |0 |8 |android.widget.LinearLayout | |2b50fd7 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**3** |2 |2 |1 |0 |0, | android.widget.FrameLayout{7|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |131089238 |16908290 |10 |android.widget.FrameLayout |android:id/content |7d04356 |1020002 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**4** |3 |2 |2 |2 |0,2, | X.jTV{c982971 V.E...... ..|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |211298673 |0 |12 |X.jTV | |c982971 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**5** |7 |2 |3 |3 |0,2,3, | android.widget.FrameLayo|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |53721880 |2131435664 |14 |android.widget.FrameLayout |app:id/frl |333bb18 |7f0b2090 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**6** |8 |2 |4 |7 |0,2,3,7, | X.isZ{f77efb V.E......|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |16219899 |2131432044 |16 |X.isZ |app:id/d4r |f77efb |7f0b126c |0 |1024 |24 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**7** |9 |2 |5 |8 |0,2,3,7,8, | android.widget.Relat|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |82542831 |2131446746 |18 |android.widget.RelativeLayout |app:id/nv5 |4eb80ef |7f0b4bda |0 |1024 |0 |712 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**8** |90 |2 |6 |9 |0,2,3,7,8,9 | com.bytedance.tux.|994 |47 |504 |980 |38 |1008 |56 |18 |28 |0 |1.5555556 |194303692 |2131448536 |20 |com.bytedance.tux.input.TuxTex|app:id/p6i |b94d6cc |7f0b52d8 |980 |1008 |14 |32 |C |. |D |E |F |. |. |. |. |. |. |. |. |. |. |. |V |True |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**9** |0 |3 |0 |0 | |android.widget.LinearLayout{2b|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |45420503 |0 |8 |android.widget.LinearLayout | |2b50fd7 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**10** |2 |3 |1 |0 |0, | android.widget.FrameLayout{7|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |131089238 |16908290 |10 |android.widget.FrameLayout |android:id/content |7d04356 |1020002 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**11** |3 |3 |2 |2 |0,2, | X.jTV{c982971 V.E...... ..|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |211298673 |0 |12 |X.jTV | |c982971 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**12** |7 |3 |3 |3 |0,2,3, | android.widget.FrameLayo|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |53721880 |2131435664 |14 |android.widget.FrameLayout |app:id/frl |333bb18 |7f0b2090 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**13** |8 |3 |4 |7 |0,2,3,7, | X.isZ{f77efb V.E......|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |16219899 |2131432044 |16 |X.isZ |app:id/d4r |f77efb |7f0b126c |0 |1024 |24 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**14** |9 |3 |5 |8 |0,2,3,7,8, | android.widget.Relat|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |82542831 |2131446746 |18 |android.widget.RelativeLayout |app:id/nv5 |4eb80ef |7f0b4bda |0 |1024 |0 |712 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**15** |89 |3 |6 |9 |0,2,3,7,8,9 | com.bytedance.tux.|0 |24 |0 |0 |24 |0 |24 |0 |0 |1 |0.0 |134974938 |2131451338 |20 |com.bytedance.tux.icon.TuxIcon|app:id/r8_ |80b8dda |7f0b5dca |0 |0 |0 |0 |. |. |D |E |. |. |. |. |. |. |I |. |. |. |. |. |G |True |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[] |\r\n|**16** |0 |4 |0 |0 | |android.widget.LinearLayout{2b|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |45420503 |0 |8 |android.widget.LinearLayout | |2b50fd7 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**17** |2 |4 |1 |0 |0, | android.widget.FrameLayout{7|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |131089238 |16908290 |10 |android.widget.FrameLayout |android:id/content |7d04356 |1020002 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**18** |3 |4 |2 |2 |0,2, | X.jTV{c982971 V.E...... ..|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |211298673 |0 |12 |X.jTV | |c982971 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**19** |7 |4 |3 |3 |0,2,3, | android.widget.FrameLayo|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |53721880 |2131435664 |14 |android.widget.FrameLayout |app:id/frl |333bb18 |7f0b2090 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**20** |8 |4 |4 |7 |0,2,3,7, | X.isZ{f77efb V.E......|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |16219899 |2131432044 |16 |X.isZ |app:id/d4r |f77efb |7f0b126c |0 |1024 |24 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**21** |9 |4 |5 |8 |0,2,3,7,8, | android.widget.Relat|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |82542831 |2131446746 |18 |android.widget.RelativeLayout |app:id/nv5 |4eb80ef |7f0b4bda |0 |1024 |0 |712 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**22** |88 |4 |6 |9 |0,2,3,7,8,9 | com.bytedance.tux.|28 |50 |2304 |4 |26 |52 |74 |48 |48 |1 |1.0 |13215999 |2131451307 |20 |com.bytedance.tux.icon.TuxIcon|app:id/r7f |c9a8ff |7f0b5dab |4 |52 |2 |50 |C |. |D |E |F |. |. |. |. |. |. |. |. |. |. |. |V |True |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**23** |0 |5 |0 |0 | |android.widget.LinearLayout{2b|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |45420503 |0 |8 |android.widget.LinearLayout | |2b50fd7 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**24** |2 |5 |1 |0 |0, | android.widget.FrameLayout{7|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |131089238 |16908290 |10 |android.widget.FrameLayout |android:id/content |7d04356 |1020002 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**25** |3 |5 |2 |2 |0,2, | X.jTV{c982971 V.E...... ..|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |211298673 |0 |12 |X.jTV | |c982971 | |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**26** |7 |5 |3 |3 |0,2,3, | android.widget.FrameLayo|512 |368 |753664 |0 |0 |1024 |736 |736 |1024 |0 |1.3913044 |53721880 |2131435664 |14 |android.widget.FrameLayout |app:id/frl |333bb18 |7f0b2090 |0 |1024 |0 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**27** |8 |5 |4 |7 |0,2,3,7, | X.isZ{f77efb V.E......|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |16219899 |2131432044 |16 |X.isZ |app:id/d4r |f77efb |7f0b126c |0 |1024 |24 |736 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**28** |9 |5 |5 |8 |0,2,3,7,8, | android.widget.Relat|512 |380 |729088 |0 |24 |1024 |736 |712 |1024 |0 |1.4382023 |82542831 |2131446746 |18 |android.widget.RelativeLayout |app:id/nv5 |4eb80ef |7f0b4bda |0 |1024 |0 |712 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**29** |12 |5 |6 |9 |0,2,3,7,8,9, | android.widget.Lin|512 |406 |674816 |0 |77 |1024 |736 |659 |1024 |0 |1.5538695 |219162762 |2131448421 |20 |android.widget.LinearLayout |app:id/p3e |d10288a |7f0b5265 |0 |1024 |53 |712 |. |. |. |E |. |. |. |. |. |. |. |. |. |. |. |. |V |False |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n\r\n***\r\n***\r\n\r\n### [UIAutomator Classic Backend](https://github.com/hansalemaos/uiautomator_dump_to_csv)\r\n\r\n| **Advantages \u2705** | **Disadvantages \u274c** |\r\n|---------------------------------------------------------------|----------------------------------------------------------------|\r\n| Includes both element text and description | Higher CPU usage compared to UIAutomator2 |\r\n| Undetectable | May fail (idle state error) if there\u2019s too much activity on the screen |\r\n| Can be used alongside any other parser (except UIAutomator2) | \u2014 |\r\n\r\n***\r\n\r\n#### Video - in action\r\n\r\n\r\n[](https://www.youtube.com/watch?v=B6-dOK2YiYc)\r\n\r\n***\r\n\r\n#### Python Code\r\n\r\n\r\n```py\r\n\r\n# Imports and instance creation omitted for brevity\r\n\r\ndf = pd.DataFrame()\r\nwhile df.empty:\r\n df = te.get_df_uiautomator_classic(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_text == \"TikTok\")\r\n & (df.aa_content_desc == \"TikTok\")\r\n & (df.aa_clickable == 1)\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(10)\r\nwhile df.empty:\r\n df = te.get_df_uiautomator_classic(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_text == \"Already have an account? Log in\")\r\n & (df.aa_clazz == \"android.widget.Button\")\r\n & (df.aa_content_desc == \"\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(3)\r\nwhile df.empty:\r\n df = te.get_df_uiautomator_classic(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_text == \"Use phone / email / username\")\r\n & (df.aa_clazz == \"android.widget.TextView\")\r\n & (df.aa_content_desc == \"\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(3)\r\nwhile df.empty:\r\n df = te.get_df_uiautomator_classic(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_text == \"Email / Username\")\r\n & (df.aa_clazz == \"android.widget.TextView\")\r\n & (df.aa_content_desc == \"\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(2)\r\nte.get_cmd_send_text_natural(\"myemailtest@gmail.com\")()\r\n```\r\n***\r\n\r\n#### Example of a Pandas DataFrame (column width cropped to 30 chars)\r\n\r\n|**index** |**aa_bounds** |**aa_text** |**aa_package** |**aa_resource_id** |**aa_clazz** |**aa_content_desc** |**aa_center_x** |**aa_center_y** |**aa_area** |**aa_width** |**aa_height** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_is_square** |**aa_w_h_relation** |**aa_checkable** |**aa_checked** |**aa_clickable** |**aa_enabled** |**aa_focusable** |**aa_focused** |**aa_index** |**aa_long_clickable** |**aa_password** |**aa_scrollable** |**aa_selected** |**aa_naf** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |\r\n|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|\r\n|**0** |[0,0][1024,768] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |384 |786432 |1024 |768 |0 |0 |1024 |768 |0 |1.3333334 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**1** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.LinearLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**2** |[0,0][1024,736] | |com.zhiliaoapp.musically |android:id/content |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**3** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**4** |[0,0][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/tq|android.widget.LinearLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**5** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**6** |[0,0][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/fr|android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**7** |[0,24][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/d4|android.view.ViewGroup | |512 |380 |729088 |1024 |712 |0 |24 |1024 |736 |0 |1.4382023 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**8** |[0,24][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/nv|android.widget.RelativeLayout | |512 |380 |729088 |1024 |712 |0 |24 |1024 |736 |0 |1.4382023 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**9** |[4,26][52,74] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/r7|android.widget.ImageView |Report a problem |28 |50 |2304 |48 |48 |4 |26 |52 |74 |1 |1.0 |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**10** |[980,38][1008,56] |Skip |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p6|android.widget.Button | |994 |47 |504 |28 |18 |980 |38 |1008 |56 |0 |1.5555556 |0 |0 |1 |1 |1 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**11** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p3|android.widget.LinearLayout | |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |0 |0 |4 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**12** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/tt|androidx.viewpager.widget.View| |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |1 |0 |0 |0 |0 |1 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**13** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p3|android.view.ViewGroup | |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**14** |[30,77][994,628] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.view.ViewGroup | |512 |352 |531164 |964 |551 |30 |77 |994 |628 |0 |1.7495463 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**15** |[267,77][758,396] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|androidx.recyclerview.widget.R| |512 |236 |156629 |491 |319 |267 |77 |758 |396 |0 |1.5391849 |0 |0 |0 |1 |1 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**16** |[267,82][758,228] | |com.zhiliaoapp.musically | |android.widget.LinearLayout | |512 |155 |71686 |491 |146 |267 |82 |758 |228 |0 |3.3630137 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**17** |[267,122][758,150] |Sign up for TikTok |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/ti|android.widget.TextView | |512 |136 |13748 |491 |28 |267 |122 |758 |150 |0 |17.535715 |0 |0 |0 |1 |0 |0 |0 |1 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**18** |[267,162][758,200] |Create a profile, follow other|com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/oe|android.widget.TextView | |512 |181 |18658 |491 |38 |267 |162 |758 |200 |0 |12.921053 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**19** |[267,228][758,272] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Use phone or email |512 |250 |21604 |491 |44 |267 |228 |758 |272 |0 |11.159091 |0 |0 |1 |1 |1 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**20** |[279,238][303,262] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |250 |576 |24 |24 |279 |238 |303 |262 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**21** |[454,241][593,260] |Use phone or email |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |523 |250 |2641 |139 |19 |454 |241 |593 |260 |0 |7.3157897 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**22** |[267,284][758,328] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Continue with Facebook |512 |306 |21604 |491 |44 |267 |284 |758 |328 |0 |11.159091 |0 |0 |1 |1 |1 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**23** |[279,294][303,318] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |306 |576 |24 |24 |279 |294 |303 |318 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**24** |[437,297][611,316] |Continue with Facebook |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |524 |306 |3306 |174 |19 |437 |297 |611 |316 |0 |9.157895 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**25** |[267,340][758,384] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Continue with Google |512 |362 |21604 |491 |44 |267 |340 |758 |384 |0 |11.159091 |0 |0 |1 |1 |1 |0 |3 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**26** |[279,350][303,374] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |362 |576 |24 |24 |279 |350 |303 |374 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**27** |[445,353][602,371] |Continue with Google |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |523 |362 |2826 |157 |18 |445 |353 |602 |371 |0 |8.722222 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**28** |[32,628][992,675] |By continuing with an account |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/rw|android.widget.TextView | |512 |651 |45120 |960 |47 |32 |628 |992 |675 |0 |20.425531 |0 |0 |0 |1 |1 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**29** |[0,675][1024,676] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/dx|android.view.View | |512 |675 |1024 |1024 |1 |0 |675 |1024 |676 |0 |1024.0 |0 |0 |0 |1 |0 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[228 228 229] [228 228 229|\r\n\r\n***\r\n***\r\n\r\n### [UIAutomator with CPU Limit Backend](https://github.com/hansalemaos/uiautomator_dump_without_could_not_detect_idle_state)\r\n\r\n| **Advantages \u2705** | **Disadvantages \u274c** |\r\n|---------------------------------------------------------------|----------------------------------------------------------------|\r\n| Includes both element text and description | Higher CPU usage compared to UIAutomator2 |\r\n| Undetectable | May fail (null root node returned by UiTestAutomationBridge) if the CPU usage of the top window is limited too much |\r\n| Can be used alongside any other parser (except UIAutomator2) | \u2014 |\r\n| No idle state errors when used correctly | \u2014 |\r\n\r\n***\r\n\r\n#### Video - in action\r\n\r\n\r\n[](https://www.youtube.com/watch?v=eEhB7U110fg)\r\n\r\n***\r\n\r\n#### Python Code\r\n\r\n\r\n```py\r\n# Imports and instance creation omitted for brevity\r\n\r\ndf = pd.DataFrame()\r\nwhile df.empty:\r\n # If cpu_limit is not passed, the value from the TermuxAutomation instance is used\r\n df = te.get_df_uiautomator_with_cpu_limit(with_screenshot=True)\r\n df = df.loc[\r\n (df.aa_text == \"TikTok\")\r\n & (df.aa_content_desc == \"TikTok\")\r\n & (df.aa_clickable == 1)\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(10)\r\nwhile df.empty:\r\n df = te.get_df_uiautomator_with_cpu_limit(with_screenshot=True, cpu_limit=14)\r\n df = df.loc[\r\n (df.aa_text == \"Already have an account? Log in\")\r\n & (df.aa_clazz == \"android.widget.Button\")\r\n & (df.aa_content_desc == \"\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(3)\r\nwhile df.empty:\r\n df = te.get_df_uiautomator_with_cpu_limit(with_screenshot=True, cpu_limit=13)\r\n df = df.loc[\r\n (df.aa_text == \"Use phone / email / username\")\r\n & (df.aa_clazz == \"android.widget.TextView\")\r\n & (df.aa_content_desc == \"\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(3)\r\nwhile df.empty:\r\n df = te.get_df_uiautomator_with_cpu_limit(with_screenshot=True, cpu_limit=16)\r\n df = df.loc[\r\n (df.aa_text == \"Email / Username\")\r\n & (df.aa_clazz == \"android.widget.TextView\")\r\n & (df.aa_content_desc == \"\")\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(2)\r\nte.get_cmd_send_text_natural(\"myemailtest@gmail.com\")()\r\n```\r\n***\r\n\r\n#### Example of a Pandas DataFrame (column width cropped to 30 chars)\r\n\r\n|**index** |**aa_bounds** |**aa_text** |**aa_package** |**aa_resource_id** |**aa_clazz** |**aa_content_desc** |**aa_center_x** |**aa_center_y** |**aa_area** |**aa_width** |**aa_height** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_is_square** |**aa_w_h_relation** |**aa_checkable** |**aa_checked** |**aa_clickable** |**aa_enabled** |**aa_focusable** |**aa_focused** |**aa_index** |**aa_long_clickable** |**aa_password** |**aa_scrollable** |**aa_selected** |**aa_naf** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |\r\n|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|------------------------------|\r\n|**0** |[0,0][1024,768] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |384 |786432 |1024 |768 |0 |0 |1024 |768 |0 |1.3333334 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**1** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.LinearLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**2** |[0,0][1024,736] | |com.zhiliaoapp.musically |android:id/content |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**3** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**4** |[0,0][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/tq|android.widget.LinearLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**5** |[0,0][1024,736] | |com.zhiliaoapp.musically | |android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**6** |[0,0][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/fr|android.widget.FrameLayout | |512 |368 |753664 |1024 |736 |0 |0 |1024 |736 |0 |1.3913044 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**7** |[0,24][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/d4|android.view.ViewGroup | |512 |380 |729088 |1024 |712 |0 |24 |1024 |736 |0 |1.4382023 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**8** |[0,24][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/nv|android.widget.RelativeLayout | |512 |380 |729088 |1024 |712 |0 |24 |1024 |736 |0 |1.4382023 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**9** |[4,26][52,74] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/r7|android.widget.ImageView |Report a problem |28 |50 |2304 |48 |48 |4 |26 |52 |74 |1 |1.0 |0 |0 |1 |1 |1 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**10** |[980,38][1008,56] |Skip |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p6|android.widget.Button | |994 |47 |504 |28 |18 |980 |38 |1008 |56 |0 |1.5555556 |0 |0 |1 |1 |1 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**11** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p3|android.widget.LinearLayout | |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |0 |0 |4 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**12** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/tt|androidx.viewpager.widget.View| |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |1 |0 |0 |0 |0 |1 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**13** |[0,77][1024,736] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/p3|android.view.ViewGroup | |512 |406 |674816 |1024 |659 |0 |77 |1024 |736 |0 |1.5538695 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**14** |[30,77][994,628] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.view.ViewGroup | |512 |352 |531164 |964 |551 |30 |77 |994 |628 |0 |1.7495463 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**15** |[267,77][758,396] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|androidx.recyclerview.widget.R| |512 |236 |156629 |491 |319 |267 |77 |758 |396 |0 |1.5391849 |0 |0 |0 |1 |1 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**16** |[267,82][758,228] | |com.zhiliaoapp.musically | |android.widget.LinearLayout | |512 |155 |71686 |491 |146 |267 |82 |758 |228 |0 |3.3630137 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**17** |[267,122][758,150] |Sign up for TikTok |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/ti|android.widget.TextView | |512 |136 |13748 |491 |28 |267 |122 |758 |150 |0 |17.535715 |0 |0 |0 |1 |0 |0 |0 |1 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**18** |[267,162][758,200] |Create a profile, follow other|com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/oe|android.widget.TextView | |512 |181 |18658 |491 |38 |267 |162 |758 |200 |0 |12.921053 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**19** |[267,228][758,272] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Use phone or email |512 |250 |21604 |491 |44 |267 |228 |758 |272 |0 |11.159091 |0 |0 |1 |1 |1 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**20** |[279,238][303,262] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |250 |576 |24 |24 |279 |238 |303 |262 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**21** |[454,241][593,260] |Use phone or email |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |523 |250 |2641 |139 |19 |454 |241 |593 |260 |0 |7.3157897 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**22** |[267,284][758,328] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Continue with Facebook |512 |306 |21604 |491 |44 |267 |284 |758 |328 |0 |11.159091 |0 |0 |1 |1 |1 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**23** |[279,294][303,318] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |306 |576 |24 |24 |279 |294 |303 |318 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**24** |[437,297][611,316] |Continue with Facebook |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |524 |306 |3306 |174 |19 |437 |297 |611 |316 |0 |9.157895 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**25** |[267,340][758,384] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/cz|android.widget.Button |Continue with Google |512 |362 |21604 |491 |44 |267 |340 |758 |384 |0 |11.159091 |0 |0 |1 |1 |1 |0 |3 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**26** |[279,350][303,374] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/gs|android.widget.ImageView | |291 |362 |576 |24 |24 |279 |350 |303 |374 |1 |1.0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**27** |[445,353][602,371] |Continue with Google |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/c7|android.widget.TextView | |523 |362 |2826 |157 |18 |445 |353 |602 |371 |0 |8.722222 |0 |0 |0 |1 |0 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**28** |[32,628][992,675] |By continuing with an account |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/rw|android.widget.TextView | |512 |651 |45120 |960 |47 |32 |628 |992 |675 |0 |20.425531 |0 |0 |0 |1 |1 |0 |1 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[255 255 255] [255 255 255|\r\n|**29** |[0,675][1024,676] | |com.zhiliaoapp.musically |com.zhiliaoapp.musically:id/dx|android.view.View | |512 |675 |1024 |1024 |1 |0 |675 |1024 |676 |0 |1024.0 |0 |0 |0 |1 |0 |0 |2 |0 |0 |0 |0 |0 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, durat|(offset_x=0, offset_y=0, actio|[[[228 228 229] [228 228 229|\r\n\r\n***\r\n***\r\n\r\n### Window Dump Backend\r\n\r\n| **Advantages \u2705** | **Disadvantages \u274c** |\r\n|---------------------------------------------------------------|----------------------------------------------------------------|\r\n| Very fast parser | Results don\u2019t include the element\u2019s text |\r\n| Very low CPU usage | Doesn\u2019t work everywhere (e.g., the start page of the launcher) |\r\n| Can be used alongside any other parser | \u2014 |\r\n| Provides lots of additional information that other parsers don\u2019t have | \u2014 |\r\n| Can find elements that UIAutomator-based parsers can\u2019t detect | \u2014 |\r\n| Undetectable | \u2014 |\r\n\r\n***\r\n\r\n#### Video - in action\r\n\r\n\r\n[](https://www.youtube.com/watch?v=gcjsfM1AJps)\r\n\r\n***\r\n\r\n#### Python Code\r\n\r\n```py\r\n# We need to open a shell and start the app using the am command because\r\n# the parser doesn\u2019t work on the launcher\u2019s start page\r\nmyshell = te.open_shell()\r\nmyshell.sh_force_open_app(\"com.zhiliaoapp.musically\", 3)\r\n\r\ntimesleep(10)\r\ndf = pd.DataFrame()\r\nwhile df.empty:\r\n df = te.get_df_window_dump(with_screenshot=True)\r\n # Provides lots of additional information no other parser has\r\n # (pivot points, font size, font weight, etc.)\r\n df = df.loc[\r\n (df[\"aa_text_scaledTextSize\"] == 12) & (df.aa_end_x <= te.screen_width)\r\n ]\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(2)\r\nwhile df.empty:\r\n df = te.get_df_window_dump(with_screenshot=True)\r\n df = df.loc[\r\n (df[\"aa_text_scaledTextSize\"] == 14) & (df.aa_end_x <= te.screen_width)\r\n ].sort_values(by=[\"aa_start_y\"])\r\n\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(2)\r\nwhile df.empty:\r\n df = te.get_df_window_dump(with_screenshot=True)\r\n df = df.loc[\r\n (df[\"aa_accessibility_labelFor\"] == -1)\r\n & (df[\"aa_topMargin\"] == 0)\r\n & (df[\"aa_layout_gravity\"] == -1)\r\n & (df[\"aa_layout_left\"] > 0)\r\n & (df[\"aa_layout_left\"] < 20)\r\n ].sort_values(by=[\"aa_start_x\"], ascending=[False])\r\ndf.aa_input_tap.iloc[0]()\r\ndf = pd.DataFrame()\r\ntimesleep(2)\r\nte.get_cmd_send_text_natural(\"myemailtest@gmail.com\")()\r\n```\r\n\r\n***\r\n\r\n#### Example of a Pandas DataFrame (column width cropped to 50 chars)\r\n\r\n|**index** |**aa_window_left** |**aa_window_top** |**aa_meta___name__** |**aa_meta___hash__** |**aa_id** |**aa_misc_transformation.alpha** |**aa_misc_transitionName** |**aa_layout_left** |**aa_layout_right** |**aa_layout_top** |**aa_layout_bottom** |**aa_layout_width** |**aa_layout_height** |**aa_layout_layoutDirection** |**aa_layout_layoutRtl** |**aa_layout_hasTransientState** |**aa_layout_baseline** |**aa_layoutParams** |**aa_y** |**aa_horizontalWeight** |**aa_verticalWeight** |**aa_type** |**aa_flags** |**aa_scrolling_scrollX** |**aa_scrolling_scrollY** |**aa_padding_paddingLeft** |**aa_padding_paddingRight** |**aa_padding_paddingTop** |**aa_padding_paddingBottom** |**aa_padding_userPaddingRight** |**aa_padding_userPaddingLeft** |**aa_padding_userPaddingBottom** |**aa_padding_userPaddingStart** |**aa_padding_userPaddingEnd** |**aa_measurement_minHeight** |**aa_measurement_minWidth** |**aa_measurement_measuredWidth** |**aa_measurement_measuredHeight** |**aa_drawing_elevation** |**aa_drawing_translationX** |**aa_drawing_translationY** |**aa_drawing_translationZ** |**aa_drawing_rotation** |**aa_drawing_rotationX** |**aa_drawing_rotationY** |**aa_drawing_scaleX** |**aa_drawing_scaleY** |**aa_drawing_pivotX** |**aa_drawing_pivotY** |**aa_drawing_clipBounds** |**aa_drawing_opaque** |**aa_drawing_alpha** |**aa_drawing_transitionAlpha** |**aa_drawing_shadow** |**aa_drawing_solidColor** |**aa_drawing_layerType** |**aa_drawing_willNotDraw** |**aa_drawing_hardwareAccelerated** |**aa_drawing_willNotCacheDrawing** |**aa_drawing_drawingCacheEnabled** |**aa_drawing_overlappingRendering** |**aa_drawing_outlineAmbientShadowColor** |**aa_drawing_outlineSpotShadowColor** |**aa_focus_hasFocus** |**aa_focus_isFocused** |**aa_focus_focusable** |**aa_focus_isFocusable** |**aa_focus_isFocusableInTouchMode** |**aa_misc_clickable** |**aa_misc_pressed** |**aa_misc_selected** |**aa_misc_touchMode** |**aa_misc_hovered** |**aa_misc_activated** |**aa_misc_visibility** |**aa_misc_fitsSystemWindows** |**aa_misc_filterTouchesWhenObscured** |**aa_misc_enabled** |**aa_misc_soundEffectsEnabled** |**aa_misc_hapticFeedbackEnabled** |**aa_theme** |**aa_meta___attrCount__** |**aa_misc_scrollBarStyle** |**aa_text_textDirection** |**aa_text_textAlignment** |**aa_accessibility_labelFor** |**aa_accessibility_importantForAccessibility** |**aa_focus_descendantFocusability** |**aa_drawing_clipChildren** |**aa_drawing_clipToPadding** |**aa_drawing_childrenDrawingOrderEnabled** |**aa_drawing_persistentDrawingCache** |**aa_meta___childCount__** |**aa_CHILD_META** |**aa_aa_hashcode_int** |**aa_bottomMargin** |**aa_endMargin** |**aa_height** |**aa_layout_alignWithParent** |**aa_layout_baselineAligned** |**aa_layout_baselineAlignedChildIndex** |**aa_layout_gravity** |**aa_layout_totalLength** |**aa_layout_useLargestChild** |**aa_layout_weight** |**aa_leftMargin** |**aa_measurement_baselineChildTop** |**aa_measurement_gravity** |**aa_measurement_measureAllChildren** |**aa_measurement_orientation** |**aa_measurement_totalLength** |**aa_meta___child__0** |**aa_meta___child__1** |**aa_meta___child__2** |**aa_meta___child__3** |**aa_meta___child__4** |**aa_meta___child__5** |**aa_meta___child__6** |**aa_meta___child__7** |**aa_meta___child__8** |**aa_padding_foregroundPaddingBottom** |**aa_padding_foregroundPaddingLeft** |**aa_padding_foregroundPaddingRight** |**aa_padding_foregroundPaddingTop** |**aa_rightMargin** |**aa_startMargin** |**aa_text_curTextColor** |**aa_text_ellipsize** |**aa_text_gravity** |**aa_text_scaledTextSize** |**aa_text_selectionEnd** |**aa_text_selectionStart** |**aa_text_textSize** |**aa_text_typefaceStyle** |**aa_topMargin** |**aa_start_x** |**aa_start_y** |**aa_end_x** |**aa_end_y** |**aa_center_x** |**aa_center_y** |**aa_window_name** |**aa_hashcode_hex** |**aa_input_tap** |**aa_sendevent_mouse_click** |**aa_sendevent_tap** |**aa_mouse_action** |**aa_screenshot** |\r\n|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|--------------------------------------------------|\r\n|**0** |0 |0.0 |com.android.internal.policy.DecorView |192145870.0 |NO_ID |0.0 | |0 |1024 |0 |768 |1024 |768 |0 |False |False |-1 |(3, 'android.view.WindowManager$LayoutParams', 4, |0.0 |0.0 |0.0 |1.0 |-2122252030.0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |-2147483648 |-2147483648 |0 |0 |1024 |768 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |512.0 |384.0 | |False |1.0 |1.0 |False |0 |0 |True |True |False |False |True |-16777216 |-16777216 |False |False |16 |False |False |False |False |False |True |False |False |0 |False |False |True |True |True |(3, 'android.content.res.Resources$Theme', 4, 5365|0 |0 |1 |1 |-1 |1 |262144 |True |True |False |2 |3 |None |nan |nan |nan |None |None |None |nan |nan |nan |None |nan |nan |nan |nan |None |nan |nan |None |None |None |None |None |None |None |None |None |nan |nan |nan |nan |nan |nan |nan |None |nan |nan |nan |nan |nan |nan |nan |-1 |-1 |-1 |-1 |-1 |-1 |a57b656 com.zhiliaoapp.musically/com.ss.android.ug|-1 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, action=0, event_multiply=|[] |\r\n|**1** |None |nan |None |nan |None |nan | |0 |1024 |0 |736 |1024 |736 |0 |False |False |-1 |(3, 'android.widget.FrameLayout$LayoutParams', 4, |nan |nan |nan |nan |nan |0 |0 |0 |0 |0 |0 |0 |0 |0 |-2147483648 |-2147483648 |0 |0 |1024 |736 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |512.0 |368.0 | |False |1.0 |1.0 |False |0 |0 |True |True |False |False |True |-16777216 |-16777216 |False |False |16 |False |False |False |False |False |True |False |False |0 |True |False |True |True |True |(3, 'android.content.res.Resources$Theme', 4, 1907|0 |0 |1 |1 |-1 |0 |131072 |True |True |False |2 |2 |('meta:__child__0', 3, 'android.widget.LinearLayou|45420503.0 |32.0 |-2147483648.0 |None |None |None |nan |nan |nan |None |nan |nan |nan |nan |None |nan |nan |None |None |None |None |None |None |None |None |None |nan |nan |nan |nan |0.0 |-2147483648.0 |nan |None |nan |nan |nan |nan |nan |nan |0.0 |0 |0 |1024 |736 |512 |368 |a57b656 com.zhiliaoapp.musically/com.ss.android.ug|2b50fd7 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, action=0, event_multiply=|[[[255 255 255] [255 255 255] [255 255 255] |\r\n|**2** |None |nan |None |nan |None |nan | |0 |1024 |0 |736 |1024 |736 |0 |False |False |-1 |(3, 'android.widget.LinearLayout$LayoutParams', 4,|nan |nan |nan |nan |nan |0 |0 |0 |0 |0 |0 |0 |0 |0 |-2147483648 |-2147483648 |0 |0 |1024 |736 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |512.0 |368.0 | |False |1.0 |1.0 |False |0 |0 |True |True |False |False |True |-16777216 |-16777216 |False |False |16 |False |False |False |False |False |True |False |False |0 |False |False |True |True |True |(3, 'android.content.res.Resources$Theme', 4, 1907|0 |0 |1 |1 |-1 |0 |131072 |True |True |False |2 |1 |('meta:__child__0', 3, 'android.view.ViewStub', 4,|99812585.0 |0.0 |-2147483648.0 |None |None |None |nan |-1.0 |nan |None |0.0 |nan |nan |nan |None |nan |nan |None |(3, 'android.widget.FrameLayout', 4, 131089238, 5,|None |None |None |None |None |None |None |nan |nan |nan |nan |0.0 |-2147483648.0 |nan |None |nan |nan |nan |nan |nan |nan |0.0 |0 |0 |0 |0 |0 |0 |a57b656 com.zhiliaoapp.musically/com.ss.android.ug|5f304e9 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, action=0, event_multiply=|[] |\r\n|**3** |None |nan |None |nan |None |nan | |0 |1024 |0 |736 |1024 |736 |0 |False |False |-1 |(3, 'android.widget.FrameLayout$LayoutParams', 4, |nan |nan |nan |nan |nan |0 |0 |0 |0 |0 |0 |0 |0 |0 |-2147483648 |-2147483648 |0 |0 |1024 |736 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |0.0 |1.0 |1.0 |512.0 |368.0 | |False |1.0 |1.0 |False |0 |0 |True |True |False |False |True |-16777216 |-16777216 |False |False |16 |False |False |False |False |False |True |False |False |0 |False |False |True |True |True |(3, 'android.content.res.Resources$Theme', 4, 1907|0 |0 |1 |1 |-1 |0 |131072 |True |True |False |2 |2 |('meta:__child__0', 3, 'X.jTV', 4, 211298673, 5, '|211298673.0 |0.0 |-2147483648.0 |None |None |None |nan |nan |nan |None |nan |nan |nan |nan |None |nan |nan |None |None |None |None |None |None |None |None |None |nan |nan |nan |nan |0.0 |-2147483648.0 |nan |None |nan |nan |nan |nan |nan |nan |0.0 |0 |0 |1024 |736 |512 |368 |a57b656 com.zhiliaoapp.musically/com.ss.android.ug|c982971 |(offset_x=0, offset_y=0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, duration=0.0) |(offset_x=0, offset_y=0, action=0, event_multiply=|[[[255 255 255] [255 255 255] [255 255 255] |\r\n\r\n***\r\n***\r\n\r\n## Color Search\r\n\r\n### If you decide to add a screenshot to your DataFrame, you can perform a very fast color search (uses C++ vectors and structs for the results internally).\r\n\r\n```py\r\n\r\n# Pass RGB colors and the name of the column\r\ndf.bb_search_for_colors([[255, 255, 255], [0, 0, 0]], result_column=\"white_and_black\")\r\n\r\n# An new column will be added\r\ndf.white_and_black\r\n\r\n----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\r\niloc | index | white_and_black |\r\n----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\r\n0 | 0 | [{'x': 140, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 141, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 142, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 143, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 144, 'y': 65, 'count': 20 |\r\n1 | 1 | [{'x': 140, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 141, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 142, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 143, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 144, 'y': 65, 'count': 20 |\r\n2 | 2 | [{'x': 140, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 141, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 142, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 143, 'y': 65, 'count': 20148, 'r': 255, 'g': 255, 'b': 255}, {'x': 144, 'y': 65, 'count': 20 |\r\n3 | 3 | [{'x': 128, 'y': 100, 'count': 4811, 'r': 255, 'g': 255, 'b': 255}, {'x': 129, 'y': 100, 'count': 4811, 'r': 255, 'g': 255, 'b': 255}, {'x': 130, 'y': 100, 'count': 4811, 'r': 255, 'g': 255, 'b': 255}, {'x': 131, 'y': 100, 'count': 4811, 'r': 255, 'g': 255, 'b': 255}, {'x': 132, 'y': 100, 'count': 4 |\r\n4 | 4 | [{'x': 128, 'y': 100, 'count': 665, 'r': 255, 'g': 255, 'b': 255}, {'x': 129, 'y': 100, 'count': 665, 'r': 255, 'g': 255, 'b': 255}, {'x': 130, 'y': 100, 'count': 665, 'r': 255, 'g': 255, 'b': 255}, {'x': 131, 'y': 100, 'count': 665, 'r': 255, 'g': 255, 'b': 255}, {'x': 132, 'y': 100, 'count': 665, |\r\n5 | 5 | [{'x': 248, 'y': 100, 'count': 1717, 'r': 255, 'g': 255, 'b': 255}, {'x': 249, 'y': 100, 'count': 1717, 'r': 255, 'g': 255, 'b': 255}, {'x': 250, 'y': 100, 'count': 1717, 'r': 255, 'g': 255, 'b': 255}, {'x': 251, 'y': 100, 'count': 1717, 'r': 255, 'g': 255, 'b': 255}, {'x': 252, 'y': 100, 'count': 1 |\r\n6 | 6 | [{'x': 470, 'y': 100, 'count': 830, 'r': 255, 'g': 255, 'b': 255}, {'x': 471, 'y': 100, 'count': 830, 'r': 255, 'g': 255, 'b': 255}, {'x': 472, 'y': 100, 'count': 830, 'r': 255, 'g': 255, 'b': 255}, {'x': 473, 'y': 100, 'count': 830, 'r': 255, 'g': 255, 'b': 255}, {'x': 474, 'y': 100, 'count': 830, |\r\n7 | 7 | [{'x': 117, 'y': 412, 'count': 311, 'r': 255, 'g': 255, 'b': 255}, {'x': 118, 'y': 412, 'count': 311, 'r': 255, 'g': 255, 'b': 255}, {'x': 119, 'y': 412, 'count': 311, 'r': 255, 'g': 255, 'b': 255}, {'x': 118, 'y': 413, 'count': 311, 'r': 255, 'g': 255, 'b': 255}, {'x': 119, 'y': 413, 'count': 311, |\r\n8 | 8 | [{'x': 339, 'y': 412, 'count': 402, 'r': 255, 'g': 255, 'b': 255}, {'x': 340, 'y': 412, 'count': 402, 'r': 255, 'g': 255, 'b': 255}, {'x': 341, 'y': 412, 'count': 402, 'r': 255, 'g': 255, 'b': 255}, {'x': 340, 'y': 413, 'count': 402, 'r': 255, 'g': 255, 'b': 255}, {'x': 341, 'y': 413, 'count': 402, |\r\n9 | 9 | [{'x': 568, 'y': 497, 'count': 62, 'r': 255, 'g': 255, 'b': 255}, {'x': 569, 'y': 497, 'count': 62, 'r': 255, 'g': 255, 'b': 255}, {'x': 580, 'y': 497, 'count': 62, 'r': 255, 'g': 255, 'b': 255}, {'x': 589, 'y': 497, 'count': 62, 'r': 255, 'g': 255, 'b': 255}, {'x': 597, 'y': 497, 'count': 62, 'r': |\r\n10 | 10 | [{'x': 151, 'y': 729, 'count': 197, 'r': 255, 'g': 255, 'b': 255}, {'x': 152, 'y': 729, 'count': 197, 'r': 255, 'g': 255, 'b': 255}, {'x': 85, 'y': 730, 'count': 197, 'r': 255, 'g': 255, 'b': 255}, {'x': 86, 'y': 730, 'count': 197, 'r': 255, 'g': 255, 'b': 255}, {'x': 149, 'y': 730, 'count': 197, 'r |\r\n11 | 11 | [{'x': 362, 'y': 638, 'count': 627, 'r': 255, 'g': 255, 'b': 255}, {'x': 363, 'y': 638, 'count': 627, 'r': 255, 'g': 255, 'b': 255}, {'x': 364, 'y': 638, 'count': 627, 'r': 255, 'g': 255, 'b': 255}, {'x': 365, 'y': 638, 'count': 627, 'r': 255, 'g': 255, 'b': 255}, {'x': 366, 'y': 638, 'count': 627, |\r\n12 | 12 | [{'x': 140, 'y': 65, 'count': 17610, 'r': 255, 'g': 255, 'b': 255}, {'x': 141, 'y': 65, 'count': 17610, 'r': 255, 'g': 255, 'b': 255}, {'x': 142, 'y': 65, 'count': 17610, 'r': 255, 'g': 255, 'b': 255}, {'x': 143, 'y': 65, 'count': 17610, 'r': 255, 'g': 255, 'b': 255}, {'x': 144, 'y': 65, 'count': 17 |\r\n13 | 13 | [{'x': 136, 'y': 77, 'count': 100, 'r': 255, 'g': 255, 'b': 255}, {'x': 141, 'y': 77, 'count': 100, 'r': 255, 'g': 255, 'b': 255}, {'x': 142, 'y': 77, 'count': 100, 'r': 255, 'g': 255, 'b': 255}, {'x': 143, 'y': 77, 'count': 100, 'r': 255, 'g': 255, 'b': 255}, {'x': 144, 'y': 77, 'count': 100, 'r': |\r\n14 | 14 | [{'x': 150, 'y': 65, 'count': 15852, 'r': 255, 'g': 255, 'b': 255}, {'x': 151, 'y': 65, 'count': 15852, 'r': 255, 'g': 255, 'b': 255}, {'x': 152, 'y': 65, 'count': 15852, 'r': 255, 'g': 255, 'b': 255}, {'x': 153, 'y': 65, 'count': 15852, 'r': 255, 'g': 255, 'b': 255}, {'x': 154, 'y': 65, 'count': 15 |\r\n15 | 15 | [{'x': 568, 'y': 77, 'count': 177, 'r': 255, 'g': 255, 'b': 255}, {'x': 569, 'y': 77, 'count': 177, 'r': 255, 'g': 255, 'b': 255}, {'x': 570, 'y': 77, 'count': 177, 'r': 255, 'g': 255, 'b': 255}, {'x': 571, 'y': 77, 'count': 177, 'r': 255, 'g': 255, 'b': 255}, {'x': 572, 'y': 77, 'count': 177, 'r': |\r\n16 | 16 | [] |\r\n17 | 17 | [] |\r\n18 | 18 | [] |\r\n19 | 19 | [{'x': 344, 'y': 1129, 'count': 250, 'r': 0, 'g': 0, 'b': 0}, {'x': 333, 'y': 1130, 'count': 250, 'r': 0, 'g': 0, 'b': 0}, {'x': 334, 'y': 1130, 'count': 250, 'r': 0, 'g': 0, 'b': 0}, {'x': 331, 'y': 1131, 'count': 250, 'r': 0, 'g': 0, 'b': 0}, {'x': 334, 'y': 1131, 'count': 250, 'r': 0, 'g': 0, 'b' |\r\n20 | 20 | [] |\r\n21 | 21 | [{'x': 599, 'y': 1147, 'count': 1, 'r': 255, 'g': 255, 'b': 255}] |\r\n22 | 22 | []\r\n\r\n```\r\n\r\n## HDBSCAN\r\n\r\nHDBSCAN of the color search results is also possible. It should not be done with a large number of colors.\r\nEven though it is a fast [C++ implementation](https://github.com/rohanmohapatra/hdbscan-cpp), it can take quite some time on an emulator.\r\n\r\n```py\r\n\r\n# Use your favorite method to get the elements\r\ndf = te.get_df_uiautomator2(with_screenshot=True)\r\n\r\n# Search for colors\r\ndf.bb_search_for_colors([[0, 0, 0]], result_column=\"black_color\")\r\n\r\n# Clustering the color search results from the first element found\r\nclustered = df[\"black_color\"][:1].s_cluster_values(min_points=50, min_cluster_size=50)\r\n\r\n# Displaying the first 20 results\r\nclustered[:20]\r\n\r\n-----------------------------------------------------------------------------------------------------------------------\r\niloc | index | original_data | label | membership_probability | outlier_score | outlier_id | dfiloc |\r\n-----------------------------------------------------------------------------------------------------------------------\r\n0 | 0 | [106.0, 388.0] | 2 | 0.05719095841793657 | 0.0 | 424 | 0 |\r\n1 | 1 | [107.0, 388.0] | 2 | 0.10247253214424938 | 0.0 | 425 | 0 |\r\n2 | 2 | [108.0, 388.0] | 2 | 0.10247253214424938 | 0.0 | 426 | 0 |\r\n3 | 3 | [109.0, 388.0] | 2 | 0.10247253214424938 | 0.0 | 427 | 0 |\r\n4 | 4 | [110.0, 388.0] | 2 | 0.10247253214424938 | 0.0 | 428 | 0 |\r\n5 | 5 | [111.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 429 | 0 |\r\n6 | 6 | [112.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 430 | 0 |\r\n7 | 7 | [113.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 431 | 0 |\r\n8 | 8 | [114.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 432 | 0 |\r\n9 | 9 | [115.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 433 | 0 |\r\n10 | 10 | [116.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 434 | 0 |\r\n11 | 11 | [117.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 435 | 0 |\r\n12 | 12 | [118.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 436 | 0 |\r\n13 | 13 | [119.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 437 | 0 |\r\n14 | 14 | [120.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 438 | 0 |\r\n15 | 15 | [121.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 439 | 0 |\r\n16 | 16 | [122.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 440 | 0 |\r\n17 | 17 | [123.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 441 | 0 |\r\n18 | 18 | [124.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 442 | 0 |\r\n19 | 19 | [125.0, 388.0] | 2 | 0.1501634144012026 | 0.0 | 443 | 0 |\r\n```\r\n\r\n## \ud83c\udfaf **Input Events Without Element Parsing**\r\n\r\nTo interact with elements\u2014such as clicking, tapping, scrolling, writing text, or pressing keys\u2014you can create instances of a collection of input classes. The advantage is that these instances are **callable** and can be **reused**, which saves overhead.\r\n\r\nMost of these classes are implemented in **Cython** using low-overhead `cdef` classes for maximum performance.\r\n\r\n***\r\n\r\n### \u26a1 **[Modified C++ Version of `sendevent` (Specifically for Keyboard Events)](https://github.com/hansalemaos/sendevent_multicommands_type_text)**\r\n\r\n#### \u2705 **Very Reliable, Natural `sendevent` Input**\r\n\r\n```python\r\ncmd_sendkeys = te.get_cmd_sendkeys(\r\n text=\"Hi there my friend\",\r\n min_press=1,\r\n max_press=4\r\n)\r\n# Just call the instance to execute the command\r\ncmd_sendkeys()\r\n\r\n```\r\n\r\n***\r\n\r\n### \ud83d\uddb1\ufe0f Using the System's `sendevent` Command\r\n\r\n```py\r\ncmd_sendevent_tap = te.get_cmd_sendevent_tap(100, 100)\r\ncmd_sendevent_tap()\r\n\r\ncmd_sendevent_click = te.get_cmd_sendevent_click(100, 100)\r\ncmd_sendevent_click()\r\n```\r\n***\r\n\r\n\r\n### \ud83d\udcf1 Using the System's `input` Command\r\n\r\n```py\r\ncmd_input_tap = te.get_cmd_input_tap(100, 100)\r\ncmd_input_tap()\r\n```\r\n\r\n***\r\n\r\n### [Another Modified C++ Version of sendevent (Specifically for Mouse/Touch Events)](https://github.com/hansalemaos/mouse_sendevent_android)\r\n\r\n```py\r\ncmd_mouse_action = te.get_cmd_mouse_action(500, 500)\r\n\r\n# The __call__ method accepts the following arguments:\r\ncmd_mouse_action(\r\nint offset_x=0,\r\nint offset_y=0,\r\nint action=0,\r\nint event_multiply=1,\r\nint natural_movement=1,\r\nint use_every_n_element=10,\r\nint min_x_variation=0,\r\nint max_x_variation=0,\r\nint min_y_variation=0,\r\nint max_y_variation=0,\r\nint sleep_time=0,\r\nint debug=0,\r\nint print_device_info=0,\r\n)\r\n\r\n# Check out the documentation for details on each parameter:\r\n# https://github.com/hansalemaos/mouse_sendevent_android\r\n\r\n\r\n```\r\n***\r\n\r\n### \u270d\ufe0f Using the System's `input` Command (Latin Letters with Accents Normalized)\r\n\r\n```py\r\n# Sends the whole text\r\ncmd_send_text = te.get_cmd_send_text(\"Hi there m'y fr\u00f6nd\")\r\ncmd_send_text()\r\n\r\n# sends each text\r\ncmd_send_text_natural = te.get_cmd_send_text_natural(\"Hi there my fr\u00f6nd\")\r\ncmd_send_text_natural()\r\n```\r\n***\r\n\r\n### \u2328\ufe0f Keycodes (Using the System's input Command)\r\n\r\n```py\r\nte.KeyCodes.long_press_KEYCODE_BACKSLASH()\r\nte.KeyCodes.short_press_KEYCODE_BACKSLASH()\r\n```\r\n***\r\n\r\n### [\ud83c\udf10 ADBKeyboard - For Unicode Text (Not Supported on Every Device)](https://github.com/senzhk/ADBKeyBoard)\r\n```py\r\nte.adb_keyboard.download_adbkeyboard_apk()\r\nte.adb_keyboard.install_adbkeyboard_apk()\r\nte.adb_keyboard.activate_adb_keyboard()\r\nte.adb_keyboard.send_unicode_text_with_delay(\r\n text=\"Hello my\u00e7 friend\",\r\n delay_range=(0.05, 0.3),\r\n)\r\nte.adb_keyboard.send_unicode_text(\"Hello my\u00e7 friend\")\r\nte.disable_adb_keyboard()\r\n```\r\n\r\n\r\n## \ud83d\udda5\ufe0f **The Interactive Shell**\r\n\r\nSometimes, you need to do more than just parse and interact with elements on the screen\u2014you need to execute commands directly on the device.\r\n**CyAndroEmu** provides an interactive shell that doesn\u2019t rely on either the Python `subprocess` module or Python threads.\r\n\r\nThis shell is implemented **100% in C++**, runs in **nogil mode**, and offers **excellent reaction times**, making it perfect for high-performance automation tasks.\r\n\r\n***\r\n\r\n### \ud83d\ude80 Key Benefits of the Interactive Shell:\r\n\r\n1. **Real-Time Interaction:** Fast command execution with immediate feedback.\r\n2. **Root Access Control:** Easily switch between normal and superuser modes.\r\n3. **DataFrame Integration:** Collect system data in a structured format for automation workflows.\r\n4. **Optimized for Performance:** Runs in C++ with nogil mode for high responsiveness.\r\n\r\n***\r\n\r\n### \ud83d\ude80 **Starting an Interactive Shell**\r\n\r\n#### To start a shell, simply use:\r\n\r\n```python\r\nmyshell = te.open_shell(\r\n buffer_size=40960, # The max size of the C++ vector\u2014works like collections.deque (ring buffer)\r\n exit_command=b\"exit\", # The command to exit the shell, required by the C++ destructor.\r\n # Executed automatically when 'myshell' goes out of scope.\r\n print_stdout=False, # Prints stdout to the screen\u2014useful for debugging purposes\r\n print_stderr=False # Prints stderr to the screen\u2014useful for debugging purposes\r\n)\r\n\r\n```\r\n\r\n***\r\n***\r\n\r\n## \u26a1 **Interacting Directly with the Shell**\r\n\r\nOnce the interactive shell is running, you can execute commands directly and capture their output effortlessly.\r\n\r\n***\r\n\r\n### \ud83d\udccb **Executing Commands**\r\n\r\n```python\r\n>>> stdout, stderr = myshell.write_and_wait(\"ls -lZ\")\r\n# stdout and stderr contain the command\u2019s output in bytes.\r\n# Use .decode() to convert the output to a human-readable string.\r\n>>> print(stdout.decode())\r\ntotal 48\r\n-rw-r--r-- 1 root root u:object_r:app_data_file:s0 12264 2025-02-06 20:29 None\r\ndrwxr-x--- 16 root root u:object_r:app_data_file:s0 4096 2025-02-04 22:57 cyandroemu\r\n-rw-r--r-- 1 root root u:object_r:app_data_file:s0 0 2025-02-02 01:40 pckldf.pkl\r\n-rw-r----- 1 root root u:object_r:app_data_file:s0 17446 2025-02-04 22:51 pyshell.py\r\ndrwx------ 5 u0_a286 u0_a286 u:object_r:app_data_file:s0:c30,c257,c512,c768 4096 2025-02-01 23:45 tessdata\r\ndrwxr-xr-x 5 root root u:object_r:app_data_file:s0 4096 2025-02-02 00:13 tessdata_best\r\ndrwxr-xr-x 5 root root u:object_r:app_data_file:s0 4096 2025-02-02 00:11 tessdata_fast\r\n```\r\n\r\n***\r\n\r\n#### Entering SU (Superuser) Mode\r\n\r\n```py\r\n# To gain root access within the shell:\r\n>>> myshell.su()\r\n# This elevates the shell session, allowing privileged commands to be executed seamlessly.\r\n```\r\n\r\n***\r\n***\r\n\r\n## Predefined Shell Commands\r\n\r\n### The shell comes with a variety of predefined commands to simplify common tasks.\r\n\r\n#### These commands follow two naming conventions:\r\n\r\n1. get_df_* \u2192 Returns data as a pandas DataFrame for easy analysis.\r\n2. sh_* \u2192 Executes shell commands and usually returns a tuple[bytes, bytes] containing stdout and stderr,\r\nbut not always\u2014some commands may return different structures.\r\n\r\n### \u2705 Example: Checking the Current User\r\n\r\n```py\r\n# This command checks the current user, and the result is returned in byte format (b'root').\r\n>>> myshell.sh_whoami()\r\nb'root'\r\n```\r\n***\r\n\r\n### \u2705 Example: Getting the build props as a pandas DataFrame\r\n\r\n```py\r\n>>> buildprops=myshell.get_df_build_props()\r\n>>> print(buildprops)\r\n\r\n--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\r\niloc | index | aa_file | aa_line | aa_line_content |\r\n--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\r\n0 | 0 | '/data/adb/modules/make_writeable/system.prop' | 0 | b'# This file will be read by resetprop' |\r\n1 | 1 | '/data/adb/modules/make_writeable/system.prop' | 1 | b'# Example: Change dpi' |\r\n2 | 2 | '/data/adb/modules/make_writeable/system.prop' | 2 | b'# ro.sf.lcd_density=320' |\r\n3 | 3 | '/data/adb/modules/make_writeable/module.prop' | 0 | b'id=make_writeable' |\r\n4 | 4 | '/data/adb/modules/make_writeable/module.prop' | 1 | b'name=Make Writeable' |\r\n5 | 5 | '/data/adb/modules/make_writeable/module.prop' | 2 | b'version=1.0' |\r\n6 | 6 | '/data/adb/modules/make_writeable/module.prop' | 3 | b'versionCode=01' |\r\n7 | 7 | '/data/adb/modules/make_writeable/module.prop' | 4 | b'author=hansalemao'\r\n\r\n...\r\n\r\n```\r\n\r\n## \u26a1 **List of Implemented Shell Methods**\r\n\r\nCyAndroEmu provides a wide range of shell methods to control Android devices efficiently. These methods are optimized for speed and reliability.\r\n\r\n## \ud83d\udce6 **Some of the Implemented Shell Methods**\r\n\r\n\r\n### \ud83d\udd0d **Check Out the Source Code for More Details**\r\n\r\n\r\n```py\r\nsh_save_sed_replace(self, file_path, string2replace, replacement, timeout=1000)\r\nsh_svc_enable_wifi(self, timeout=10)\r\nsh_svc_disable_wifi(self, timeout=10)\r\nsh_trim_cache(self, timeout=10)\r\nsh_force_open_app(self, package_name, sleep_time, timeout=3)\r\nsh_get_main_activity(self, package_name, timeout=3)\r\nsh_svc_power_shutdown(self, timeout=3)\r\nsh_svc_power_reboot(self, timeout=3)\r\nsh_dumpsys_dropbox(self, timeout=3)\r\nsh_set_new_launcher(self, package_name, timeout=3)\r\nsh_tar_folder(self, src, dst, timeout=1000000)\r\nsh_extract_tar_zip(self, src_file, dst_folder, timeout=1000000)\r\nsh_get_user_rotation(self, timeout=10)\r\nsh_copy_dir_recursive(self, src, dst, timeout=1000)\r\nsh_backup_file(self, src, timeout=1000)\r\nsh_remove_folder(self, folder, timeout=1000)\r\nsh_get_pid_of_shell(self, int64_t timeout=3)\r\nsh_whoami(self, int64_t timeout=10)\r\nsh_dumpsys_package(self, package, timeout=1000, bint convert_to_dict=True)\r\nsh_get_all_wanted_permissions_from_package(self, package, timeout=1000)\r\nsh_grant_permission(self, package, permission, timeout=10)\r\nsh_grant_permission(self, package, permission, timeout=10)\r\nsh_grant_all_wanted_permissions(self, package, timeout=1000)\r\nsh_revoke_all_wanted_permissions(self, package, timeout=1000)\r\nsh_parse_whole_dumpsys_to_dict(self, timeout=100,convert_to_dict=False)\r\nsh_parse_dumpsys_to_dict(self, subcmd, timeout=100,convert_to_dict=False)\r\nsh_get_available_keyboards(self, timeout=10)\r\nsh_get_active_keyboard(self, timeout=10)\r\nsh_get_all_information_about_all_keyboards(self, timeout=10,convert_to_dict=False)\r\nsh_enable_keyboard(self, keyboard, timeout=10)\r\nsh_disable_keyboard(self, keyboard, timeout=10)\r\nsh_is_keyboard_shown(self, timeout=10)\r\nsh_set_keyboard(self, keyboard, timeout=10)\r\nsh_show_touches(self, timeout=10)\r\nsh_dont_show_touches(self, timeout=10)\r\nsh_show_pointer_location(self, timeout=10)\r\nsh_dont_show_pointer_location(self, timeout=10)\r\nsh_input_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_tap(self, x, y, timeout=10)\r\nsh_clear_file_content(self, file_path, timeout=10)\r\nsh_makedirs(self, folder, timeout=10)\r\nsh_touch(self, file_path, timeout=10)\r\nsh_mv(self, src, dst, timeout=10)\r\nsh_open_accessibility_settings(self, timeout=10)\r\nsh_open_advanced_memory_protection_settings(self, timeout=10)\r\nsh_open_airplane_mode_settings(self, timeout=10)\r\nsh_open_all_apps_notification_settings(self, timeout=10)\r\nsh_open_apn_settings(self, timeout=10)\r\nsh_open_application_details_settings(self, timeout=10)\r\nsh_open_application_development_settings(self, timeout=10)\r\nsh_open_application_settings(self, timeout=10)\r\nsh_open_app_locale_settings(self, timeout=10)\r\nsh_open_app_notification_bubble_settings(self, timeout=10)\r\nsh_open_app_notification_settings(self, timeout=10)\r\nsh_open_app_open_by_default_settings(self, timeout=10)\r\nsh_open_app_search_settings(self, timeout=10)\r\nsh_open_app_usage_settings(self, timeout=10)\r\nsh_open_automatic_zen_rule_settings(self, timeout=10)\r\nsh_open_auto_rotate_settings(self, timeout=10)\r\nsh_open_battery_saver_settings(self, timeout=10)\r\nsh_open_bluetooth_settings(self, timeout=10)\r\nsh_open_captioning_settings(self, timeout=10)\r\nsh_open_cast_settings(self, timeout=10)\r\nsh_open_channel_notification_settings(self, timeout=10)\r\nsh_open_condition_provider_settings(self, timeout=10)\r\nsh_open_data_roaming_settings(self, timeout=10)\r\nsh_open_data_usage_settings(self, timeout=10)\r\nsh_open_date_settings(self, timeout=10)\r\nsh_open_device_info_settings(self, timeout=10)\r\nsh_open_display_settings(self, timeout=10)\r\nsh_open_dream_settings(self, timeout=10)\r\nsh_open_hard_keyboard_settings(self, timeout=10)\r\nsh_open_home_settings(self, timeout=10)\r\nsh_open_ignore_background_data_restrictions_settings(self, timeout=10)\r\nsh_open_ignore_battery_optimization_settings(self, timeout=10)\r\nsh_open_input_method_settings(self, timeout=10)\r\nsh_open_input_method_subtype_settings(self, timeout=10)\r\nsh_open_internal_storage_settings(self, timeout=10)\r\nsh_open_locale_settings(self, timeout=10)\r\nsh_open_location_source_settings(self, timeout=10)\r\nsh_open_manage_all_applications_settings(self, timeout=10)\r\nsh_open_manage_all_sim_profiles_settings(self, timeout=10)\r\nsh_open_manage_applications_settings(self, timeout=10)\r\nsh_open_manage_default_apps_settings(self, timeout=10)\r\nsh_open_manage_supervisor_restricted_setting(self, timeout=10)\r\nsh_open_manage_write_settings(self, timeout=10)\r\nsh_open_memory_card_settings(self, timeout=10)\r\nsh_open_network_operator_settings(self, timeout=10)\r\nsh_open_nfcsharing_settings(self, timeout=10)\r\nsh_open_nfc_payment_settings(self, timeout=10)\r\nsh_open_nfc_settings(self, timeout=10)\r\nsh_open_night_display_settings(self, timeout=10)\r\nsh_open_notification_assistant_settings(self, timeout=10)\r\nsh_open_notification_listener_detail_settings(self, timeout=10)\r\nsh_open_notification_listener_settings(self, timeout=10)\r\nsh_open_notification_policy_access_settings(self, timeout=10)\r\nsh_open_print_settings(self, timeout=10)\r\nsh_open_privacy_settings(self, timeout=10)\r\nsh_open_quick_access_wallet_settings(self, timeout=10)\r\nsh_open_quick_launch_settings(self, timeout=10)\r\nsh_open_regional_preferences_settings(self, timeout=10)\r\nsh_open_satellite_setting(self, timeout=10)\r\nsh_open_search_settings(self, timeout=10)\r\nsh_open_security_settings(self, timeout=10)\r\nsh_open_settings(self, timeout=10)\r\nsh_open_settings(self, timeout=10)\r\nsh_open_sound_settings(self, timeout=10)\r\nsh_open_storage_volume_access_settings(self, timeout=10)\r\nsh_open_sync_settings(self, timeout=10)\r\nsh_open_usage_access_settings(self, timeout=10)\r\nsh_open_user_dictionary_settings(self, timeout=10)\r\nsh_open_voice_input_settings(self, timeout=10)\r\nsh_open_vpn_settings(self, timeout=10)\r\nsh_open_vr_listener_settings(self, timeout=10)\r\nsh_open_webview_settings(self, timeout=10)\r\nsh_open_wifi_ip_settings(self, timeout=10)\r\nsh_open_wifi_settings(self, timeout=10)\r\nsh_open_wireless_settings(self, timeout=10)\r\nsh_open_zen_mode_priority_settings(self, timeout=10)\r\nsh_open_developer_settings(self, timeout=10)\r\nsh_rescan_media_folder(self, folder, timeout=10)\r\nsh_rescan_media_file(self, file_path, timeout=10)\r\nsh_dump_process_memory_to_sdcard(self, pid, timeout=100000)\r\nsh_pm_clear(self, package, timeout=10)\r\nsh_wm_change_size(self, width, height, timeout=10)\r\nsh_wm_reset_size(self, timeout=10)\r\nsh_wm_get_density(self, timeout=10)\r\nsh_wm_change_density(self, density, timeout=10)\r\nsh_wm_reset_density(self, timeout=10)\r\nsh_am_screen_compat_on(self, package, timeout=10)\r\nsh_am_screen_compat_off(self, package, timeout=10)\r\nsh_enable_notifications(self, timeout=10)\r\nsh_disable_notifications(self, timeout=10)\r\nsh_still_image_camera(self, timeout=10)\r\nsh_disable_network_interface(self, nic, timeout=10)\r\nsh_enable_network_interface(self, nic, timeout=10)\r\nsh_get_linux_version(self, timeout=10)\r\nsh_expand_notifications(self, timeout=10)\r\nsh_expand_settings(self, timeout=10)\r\nsh_list_permission_groups(self, timeout=10)\r\nsh_input_dpad_tap(self, x, y, timeout=10)\r\nsh_input_keyboard_tap(self, x, y, timeout=10)\r\nsh_input_mouse_tap(self, x, y, timeout=10)\r\nsh_input_touchpad_tap(self, x, y, timeout=10)\r\nsh_input_gamepad_tap(self, x, y, timeout=10)\r\nsh_input_touchnavigation_tap(self, x, y, timeout=10)\r\nsh_input_joystick_tap(self, x, y, timeout=10)\r\nsh_input_touchscreen_tap(self, x, y, timeout=10)\r\nsh_input_stylus_tap(self, x, y, timeout=10)\r\nsh_input_trackball_tap(self, x, y, timeout=10)\r\nsh_input_dpad_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_dpad_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_dpad_roll(self, x, y, timeout=10)\r\nsh_input_keyboard_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_keyboard_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_keyboard_roll(self, x, y, timeout=10)\r\nsh_input_mouse_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_mouse_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_mouse_roll(self, x, y, timeout=10)\r\nsh_input_touchpad_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_touchpad_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_touchpad_roll(self, x, y, timeout=10)\r\nsh_input_gamepad_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_gamepad_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_gamepad_roll(self, x, y, timeout=10)\r\nsh_input_touchnavigation_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_touchnavigation_roll(self, x, y, timeout=10)\r\nsh_input_joystick_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_joystick_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_joystick_roll(self, x, y, timeout=10)\r\nsh_input_touchscreen_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_touchscreen_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_touchscreen_roll(self, x, y, timeout=10)\r\nsh_input_stylus_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_stylus_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_stylus_roll(self, x, y, timeout=10)\r\nsh_input_trackball_swipe(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_trackball_draganddrop(self, x1, y1, x2, y2, duration, timeout=10)\r\nsh_input_trackball_roll(self, x, y, timeout=10)\r\nsh_open_url(self, url, timeout=10)\r\nsh_get_bios_information(self, timeout=10)\r\nsh_printenv(self, timeout=10)\r\nsh_freeze_proc(self, pid, timeout=10)\r\nsh_unfreeze_proc(self, pid, timeout=10)\r\nsh_show_fragments_on_screen_enable(self, timeout=10)\r\nsh_show_fragments_on_screen_disable(self, timeout=10)\r\nsh_read_write_remount(self, methods, timeout=100)\r\n```\r\n\r\n## \ud83d\udcca Methods That Return Pandas DataFrames\r\n\r\nSome shell methods are designed to return data as pandas DataFrames for easy analysis and manipulation.\r\n\r\n\r\n```py\r\n\r\nget_df_files_with_context_printf(self, object folders, int64_t max_depth=1, int64_t timeout=10)\r\nget_df_build_props(self, int64_t timeout=10)\r\nget_df_files_with_ending(self, object folders, object endings, int64_t max_depth=10000, int64_t timeout=10)\r\nget_df_top_procs(self, timeout=1000)\r\nget_df_users(self, start=0, end=2000, timeout=10000)\r\nget_df_groups_of_user(self, start=0, end=2000, timeout=10000)\r\nget_df_netstat_tlnp(self, timeout=100)\r\nget_df_mounts(self, timeout=100)\r\nget_df_ps_el(self, timeout=1000)\r\nget_df_packages(self, timeout=10)\r\nget_df_netstat_connections_of_apps(self, resolve_names=True, timeout=10)\r\nget_df_lsmod(self, timeout=1000)\r\nget_df_lsof(self, timeout=1000000)\r\n\r\n```\r\n\r\n\r\n\r\n\r\n\r\n<!-- ROADMAP -->\r\n## Roadmap\r\n\r\n- [ ] Add template matching using https://www.fftw.org/ without other dependencies, something like [needlefinder]\r\n (https://github.com/hansalemaos/needlefinder) but without scipy\r\n- [ ] Add more useful commands to the interactive shell\r\n- [ ] Support for Accelerated [Hierarchical Density Clustering in C++](https://github.com/rohanmohapatra/hdbscan-cpp/issues/11)\r\n\r\n\r\nSee the [open issues](https://github.com/hansalemaos/cyandroemu) for a full list of proposed features (and known issues).\r\n\r\n\r\n## Contributing\r\n\r\nContributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.\r\n\r\nIf you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag \"enhancement\".\r\nDon't forget to give the project a star! Thanks again!\r\n\r\n1. Fork the Project\r\n2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)\r\n3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)\r\n4. Push to the Branch (`git push origin feature/AmazingFeature`)\r\n5. Open a Pull Request\r\n\r\n\r\n## License\r\n\r\nDistributed under the MIT License. See `LICENSE` for more information.\r\n\r\n\r\n\r\n## Contact\r\n\r\nIf you\u2019re interested in private classes with me to learn strategies for automating anything, or if you have an automation project (within legal boundaries!) that you\u2019d like to bring to life, feel free to contact me. I speak German, English, and Portuguese fluently, and Spanish proficiently.\r\n\r\n[WhatsApp](https://api.whatsapp.com/send?phone=%205511989782756&text=Question+about+CyAndroEmu)\r\n\r\n[Discord](https://discord.com/invite/ckhnJ3PxEP)\r\n\r\n[Portuguese YouTube Channel](https://www.youtube.com/channel/UC3DeX0cPlJaLSD254T7fpdA)\r\n\r\n[English YouTube Channel](https://youtube.com/channel/UCgIfJ0iFUXGfq-G4zkPXGyw)\r\n\r\n[GitHub](https://github.com/hansalemaos)\r\n\r\n[PIP](https://pypi.org/user/hansalemao)\r\n\r\n\r\n<!-- MARKDOWN LINKS & IMAGES -->\r\n\r\n[product-screenshot]: images/screenshot.png\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Very fast Android automation framework with 7 backends (uiautomator 1+2, fragment parser, window dump ...)",
"version": "1.0.0",
"project_urls": {
"Homepage": "https://github.com/hansalemaos/cyandroemu"
},
"split_keywords": [
"android",
" bot",
" uiautomator",
" magisk",
" kernelsu"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "98c5876293ffcc7e570e4991d9390e7a34b5b244ad33bec195c13f969e346112",
"md5": "b42e592d16f9ab1a6884600091c185de",
"sha256": "1179e125527184e29d5f10a2110d619923682290038ecf83f75bb9edcfa7e198"
},
"downloads": -1,
"filename": "cyandroemu-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b42e592d16f9ab1a6884600091c185de",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 210804,
"upload_time": "2025-02-13T15:24:38",
"upload_time_iso_8601": "2025-02-13T15:24:38.074854Z",
"url": "https://files.pythonhosted.org/packages/98/c5/876293ffcc7e570e4991d9390e7a34b5b244ad33bec195c13f969e346112/cyandroemu-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "dc7d2ce8b3099f9133e72a76c2241432b5f8b387012348dd07683e926dce26fd",
"md5": "48bfe8fa5835555464b1b1a3f24289c6",
"sha256": "47cecc66e2b893f40c735e38b5641185e9e3a8652f4720666ce5bb9ec1504374"
},
"downloads": -1,
"filename": "cyandroemu-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "48bfe8fa5835555464b1b1a3f24289c6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 279322,
"upload_time": "2025-02-13T15:24:41",
"upload_time_iso_8601": "2025-02-13T15:24:41.275881Z",
"url": "https://files.pythonhosted.org/packages/dc/7d/2ce8b3099f9133e72a76c2241432b5f8b387012348dd07683e926dce26fd/cyandroemu-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-13 15:24:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hansalemaos",
"github_project": "cyandroemu",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "cyandroemu"
}