Skip to main content

Locates more items/views/elements on an Android device than similar Android automation packages by combining ADB's dumpsys activity/uiautomator

$pip install androdf

from androdf import AndroDF

andf = AndroDF(

        adb_path="C:\\Users\\Gamer\\AppData\\Local\\Android\\Sdk\\platform-tools\\adb.exe",

        deviceserial="localhost:5895",

        screenshotfolder="f:\\compare_android",  # screenshots will be saved here 

        max_variation_percent_x=10, # used for one of the click functions, to not click exactly in the center - more information below

        max_variation_percent_y=10, # used for one of the click functions, to not click exactly in the center

        loung_touch_delay=(1000, 1500), # with this settings longtouch will take somewhere between 1 and 1,5 seconds

        swipe_variation_startx=10, # swipe coordinate variations in percent 

        swipe_variation_endx=10,

        swipe_variation_starty=10,

        swipe_variation_endy=10,

        sdcard="/storage/emulated/0/",  # sdcard will be used if you use the sendevent methods, don’t pass a symlink - more information below

        tmp_folder_on_sd_card="AUTOMAT", # this folder will be created in the sdcard folder for using sendevent actions

        bluestacks_divider=32767,  # coordinates must be recalculated for BlueStacks https://stackoverflow.com/a/73733261/15096247 when using sendevent

    )

andf.get_df_from_activity(with_screenshot=False) # executes dumpsys activity top -c and converts the relative coordinates to absolute coordinates

andf.get_df_from_view(with_screenshot=False) # dataframe from uiautomator xml dump, extracts all results

df_activities,df_uiautomator,df_merged = andf.get_all_results() #  Returns copies of the 3 DataFrames containing the results # df_merged will be empty 

andf.get_screenshot() 

andf.get_dfs_from_view_and_activity(with_screenshot=True) # DataFrame will contain screenshots 

andf.get_dfs_from_view_and_activity(with_screenshot=True) # df_merged will contain all data from both DataFrames

df_activities1,df_uiautomator1,df_merged1 = andf.get_all_results() 

Let’s compare the results with the ones from https://github.com/dtmilano/AndroidViewClient (Uiautomator backend)

Don't get me wrong, AndroidViewClient is a wonderful tool and I have been using it for a long time, but it works on BlueStacks (most important for me) only with the Uiautomator backend (at least on my PC), and unfortunately, it doesn't always identify all items https://github.com/dtmilano/AndroidViewClient/issues/305. As far as I know, the more recent project https://github.com/dtmilano/CulebraTester2-public identifies more views.

Bluestacks start screen

vcd = vc.dump(-1)

times_ = timest()

for ini, _ in enumerate(vcd):

    outputfile = os.path.join(f"f:\\compare_android\\2\\{times_}", str(ini) + '.png')

    touch(outputfile)

    _.writeImageToFile(outputfile)

Results AndroidViewClient

df_activities1.dropna(subset='aa_screenshot').ff_aa_save_screenshot.apply(lambda x:x())

Results df_activities1

df_uiautomator1.dropna(subset='bb_screenshot').ff_bb_save_screenshot.apply(lambda x: x())

Results df_uiautomator1

Bluestacks settings

Results AndroidViewClient

Results df_activities1

Results df_uiautomator1

All results in DataFrames

You can use the whole power of pandas.DataFrame.loc https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.loc.html to locate any item and easily call touch/swipe/longtouch methods that are stored in different columns of the DataFrame

The DataFrame columns explained

df_activities1.columns.to_list()

Out[9]: ['aa_area', 'aa_bounds', 'aa_center_x', 'aa_center_x_cropped', 'aa_center_y', 'aa_center_y_cropped', 'aa_class_name', 'aa_clickable', 'aa_complete_dump', 'aa_context_clickable', 'aa_cropped_x_end', 'aa_cropped_x_start', 'aa_cropped_y_end', 'aa_cropped_y_start', 'aa_depth', 'aa_drawn', 'aa_enabled', 'aa_focusable', 'aa_has_screenshot', 'aa_hashcode_hex', 'aa_hashcode_int', 'aa_height', 'aa_height_cropped', 'aa_id_information', 'aa_is_child', 'aa_long_clickable', 'aa_mID_hex', 'aa_mID_int', 'aa_old_index', '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_pure_id', 'aa_screenshot', 'aa_scrollbars_horizontal', 'aa_scrollbars_vertical', 'aa_shapely', 'aa_valid_square', 'aa_visibility', 'aa_width', 'aa_width_cropped', 'aa_x_end', 'aa_x_end_relative', 'aa_x_start', 'aa_x_start_relative', 'aa_y_end', 'aa_y_end_relative', 'aa_y_start', 'aa_y_start_relative', 'ee_aa_longtouch', 'ee_aa_longtouch_bs', 'ee_aa_longtouch_offset', 'ee_aa_longtouch_offset_bs', 'ee_aa_touch', 'ee_aa_touch_bs', 'ee_aa_touch_offset', 'ee_aa_touch_offset_bs', 'ff_aa_downswipe', 'ff_aa_save_screenshot', 'ff_aa_show_screenshot', 'ff_aa_tap_center_offset', 'ff_aa_tap_center_offset_long', 'ff_aa_tap_center_variation', 'ff_aa_tap_center_variation_long', 'ff_aa_tap_exact_center', 'ff_aa_tap_exact_center_long', 'ff_aa_upswipe', 'ff_show_parents', 'parent_000', 'parent_001', 'parent_002', 'parent_003', 'parent_004', 'parent_005', 'parent_006', 'parent_007', 'parent_008', 'parent_009', 'parent_010', 'parent_011']



df_uiautomator1.columns.to_list()

Out[10]: ['bb_area', 'bb_center_x', 'bb_center_y', 'bb_x_end', 'bb_y_end', 'bb_height', 'bb_x_start', 'bb_y_start', 'bb_width', 'bb_bounds', 'bb_checkable', 'bb_checked', 'bb_class', 'bb_clickable', 'bb_content_desc', 'bb_enabled', 'bb_focusable', 'bb_focused', 'bb_index', 'bb_keys_hierarchy', 'bb_long_clickable', 'bb_package', 'bb_password', 'bb_resource_id', 'bb_scrollable', 'bb_selected', 'bb_text', 'bb_pure_id', 'bb_screenshot', 'bb_old_index', 'bb_valid_square', 'bb_shapely', 'bb_cropped_x_start', 'bb_cropped_y_start', 'bb_cropped_x_end', 'bb_cropped_y_end', 'bb_width_cropped', 'bb_height_cropped', 'bb_center_x_cropped', 'bb_center_y_cropped', 'ff_bb_show_screenshot', 'ff_bb_save_screenshot', 'ff_bb_tap_center_offset', 'ff_bb_tap_exact_center', 'ff_bb_tap_center_variation', 'ff_bb_tap_center_offset_long', 'ff_bb_tap_exact_center_long', 'ff_bb_tap_center_variation_long', 'ff_bb_upswipe', 'ff_bb_downswipe', 'ee_bb_longtouch_offset', 'ee_bb_longtouch_offset_bs', 'ee_bb_touch_offset', 'ee_bb_touch_offset_bs', 'ee_bb_longtouch_bs', 'ee_bb_touch_bs', 'ee_bb_touch', 'ee_bb_longtouch']

The columns starting with aa_ or bb_ are self explaining, they contain data (height, width ...) to identify objects

The column prefix ee_ means that you can call functions which use sendevent (root access necessary)

  • aa_ after ee_ stands for activity DataFrame

  • bb_ after ee_ stands for uiautomator DataFrame (name difference (aa_/bb_) important for merging when calling andf.get_dfs_from_view_and_activity()

  • the suffix _bs is only interesting for you if you use BlueStacks (like me)

df_activities1.ee_aa_longtouch.iloc[28]() # longtouch on item 28

df_activities1.ee_aa_longtouch_bs.iloc[28]() # recalculated for bluestacks, won’t work against a “regular” Android Device https://stackoverflow.com/a/73733261/15096247 
df_activities1.ee_aa_longtouch_offset_bs.iloc[28](200,1) # x,y offset 

df_activities1.ee_aa_longtouch_offset_bs.iloc[28](200,1)  # x,y offset / recalculated for bluestacks 
df_activities1.ee_aa_touch_offset.iloc[28](100,1) # x,y offset 

df_activities1.ee_aa_touch_offset_bs.iloc[28](100,1) # x,y offset / recalculated for bluestacks 
df_activities1.ee_aa_touch.iloc[28]()

df_activities1.ee_aa_touch_bs.iloc[28]() # recalculated for bluestacks 

The column prefix ff_ means that the action is executed using adb shell input (root access not necessary)

# swipes down (or up, depending on your interpretation) within the bounds of the item

df_activities1.ff_aa_downswipe.iloc[28]()
# swipes up (or down, depending on your interpretation) within the bounds of the item

df_activities1.ff_aa_upswipe.iloc[28]()
# save all screenshots to the defined folder (when you created the instance), subfolder with timestamp as name will be created for each new DataFrame

df_activities1.dropna(subset='aa_screenshot').ff_aa_save_screenshot.apply(lambda x:x())
#show screenshot with cv2.imshow, window can be closed by pressing 'q'

df_activities1.ff_aa_show_screenshot.iloc[28]()
df_activities1.ff_aa_tap_center_offset.iloc[28](1,20) # offset from the center of the found item - touch

df_activities1.ff_aa_tap_center_offset_long.iloc[28](1,20) # offset from the center of the found item - longtouch

df_activities1.ff_aa_tap_center_variation.iloc[28]()

df_activities1.ff_aa_tap_center_variation_long.iloc[28]()

df_activities1.ff_aa_tap_exact_center.iloc[28]()

df_activities1.ff_aa_tap_exact_center_long.iloc[28]()
df_activities1.ff_show_parents.iloc[28]() # Returns a DataFrame with all parent items 

Metadata

Release files for androdf 0.12

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for androdf 0.12
File Size Uploaded Provenance Actions
androdf-0.12.tar.gz 21.1 kB Without provenance Details for androdf-0.12.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for androdf 0.12
File Interpreter ABI Platform Actions
androdf-0.12-py3-none-any.whl Python 3 none any Details for androdf-0.12-py3-none-any.whl

Total release size: 42.5 kB

Release files / androdf-0.12.tar.gz

Download URL androdf-0.12.tar.gz
Size 21.1 kB
Tags Source
SHA-256 checksum
How to use checksums
cb212db23d0f25fc0b0a576ee5d07305955d64abae3d8de6450a9f2560125cc2
BLAKE2b-256 checksum
How to use checksums
7574660d2dbcf003aa40f58c390770755ecc14987f0f9b03c4f258041c283463
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Release files / androdf-0.12-py3-none-any.whl

Download URL androdf-0.12-py3-none-any.whl
Size 21.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4e4ddead392686e48470fc07ddfbdf0fd43f0d9ada5a9c83375214a27dbd0483
BLAKE2b-256 checksum
How to use checksums
4a524164e4e20deb44da501575fec995e6fca8365768b908410bfe55a9955c70
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.9.13

Security for androdf 0.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page