"Enter"a basıp içeriğe geçin

uiautomator – Android’e hükmet

Merhaba, bugün size “uiautomator” isimli programı inceleyeceğiz. Bu ADB (Android Debug Bridge) üzerinden çalıştırılan bir yazılımdır. Çoğunuz UiAutomatorViewer biliyordur. Java ile çalışan ve kullanılması biraz ilginç, uğraştırıcı olabiliyor. Ben shell içerisinde kullandığımız uiautomator uygulamasından bahsedeceğim. Hadi Başlayalım!

Ne öğreneceksiniz?

dump

dump bizim en temel parametremiz. Bu parametere bizim harika uygulamamıza sebep oluyor, “–compressed” parametresi çıktıyı sıkıştırmamıza sebep olur. Sonrasında ise istediğimiz kısımdan çıktı yapabiliriz.

adb shell uiautomator dump window_dump.xml

Parametreleri anlatalım. “adb shell” cihazın komut verebileceğimiz kısmına geçiş yapmamızı sağlıyor. “uiautomator dump” ise uiautomator’u kullanmamızı sağlıyor. Çıktı olarak XML döndürür. Dosya çoğu zaman standart olarak “window_dump.xml” dir. İstediğiniz ismi verebilirsiniz.

Not: dosya parametresi vermezseniz kendi sabit dosya adını ve kısmını yerleştirecektir.

Çıktımız bu şekilde;

adb shell uiautomator dump /sdcard/window_dump.xml

    UI hierchary dumped to: /sdcard/window_dump.xml

Bu, başarılı olduğu anlamına gelir. artık verilen uzantıyı bilgisayara aktaralım.

adb pull /sdcard/window_dump.xml

“adb pull” işlemi sayesinde cihazımıza yazdırılan dosyayı aktarıyoruz. Dosya şu şekilde olabilir;

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
    <hierarchy rotation="0">
    <node index="0" text="" resource-id="" class="android.widget.FrameLayout"
    package="com.google.android.apps.nexuslauncher" content-desc="" checkable="false" checked="false"
    clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false"
    password="false" selected="false" bounds="[0,0][1080,2088]">
    <node index="0" text="" resource-id="" class="android.widget.LinearLayout"
    package="com.google.android.apps.nexuslauncher" content-desc="" checkable="false" checked="false"
    clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
    long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2088]">
    <node index="0" text="" resource-id="android:id/content" class="android.widget.FrameLayout"
    package="com.google.android.apps.nexuslauncher" content-desc="" checkable="false" checked="false"
    clickable="false" enabled="true" focusable="false" focused="false" scrollable="false"
    long-clickable="false" password="false" selected="false" bounds="[0,0][1080,2088]">
    <node index="0" text="" resource-id="com.google.android.apps.nexuslauncher:id/launcher"
    class="android.widget.FrameLayout" package="com.google.android.apps.nexuslauncher" content-desc=""
    checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
    focused="false" scrollable="false" long-clickable="false" password="false" selected="false"
    bounds="[0,0][1080,2088]">
    <node index="0" text="" resource-id="com.google.android.apps.nexuslauncher:id/drag_layer"
    class="android.widget.FrameLayout" package="com.google.android.apps.nexuslauncher"
    content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
    focusable="false" focused="false" scrollable="false" long-clickable="false" password="false"
    selected="false" bounds="[0,0][1080,2088]">
    <node index="0" text="" resource-id="com.google.android.apps.nexuslauncher:id/scrim_view"
    class="android.view.View" package="com.google.android.apps.nexuslauncher" content-desc=""
    checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
    focused="false" scrollable="false" long-clickable="false" password="false"
    selected="false" bounds="[0,0][1080,2088]"/>
    <node index="1" text="" resource-id="com.google.android.apps.nexuslauncher:id/workspace"
    class="android.widget.ScrollView" package="com.google.android.apps.nexuslauncher"
    content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
    focusable="false" focused="false" scrollable="true" long-clickable="false"
    password="false" selected="false" bounds="[0,0][1080,2088]">
    <node index="0" text="" resource-id="" class="android.view.ViewGroup"
    package="com.google.android.apps.nexuslauncher" content-desc="" checkable="false"
    checked="false" clickable="false" enabled="true" focusable="false" focused="false"
    scrollable="false" long-clickable="false" password="false" selected="false"
    bounds="[22,88][1058,1606]">
    <node index="0" text="" resource-id="" class="android.view.ViewGroup"
    package="com.google.android.apps.nexuslauncher" content-desc="" checkable="false"
    checked="false" clickable="false" enabled="true" focusable="false" focused="false"
    scrollable="false" long-clickable="false" password="false" selected="false"
    bounds="[38,88][1042,1606]">
    <node index="0" text=""
    resource-id="com.google.android.apps.nexuslauncher:id/search_container_workspace"
    class="android.widget.FrameLayout"
    package="com.google.android.apps.nexuslauncher" content-desc=""
    checkable="false" checked="false" clickable="false" enabled="true"
    focusable="false" focused="false" scrollable="false" long-clickable="false"
    password="false" selected="false" bounds="[38,88][1042,391]">
    <node index="0" text=""
    resource-id="com.google.android.apps.nexuslauncher:id/bc_smartspace_view"
    class="android.widget.FrameLayout"
    package="com.google.android.apps.nexuslauncher" content-desc=""
    checkable="false" checked="false" clickable="false" enabled="true"
    focusable="false" focused="false" scrollable="false"
    long-clickable="false" password="false" selected="false"
    bounds="[82,96][1042,382]">
    <node index="0" text=""
    resource-id="com.google.android.apps.nexuslauncher:id/smartspace_card_pager"
    class="androidx.viewpager.widget.ViewPager"
    package="com.google.android.apps.nexuslauncher" content-desc=""
    checkable="false" checked="false" clickable="false" enabled="true"
    focusable="true" focused="false" scrollable="false"
    long-clickable="true" password="false" selected="false"
    bounds="[82,96][1042,382]">
    <node index="0" text="" resource-id=""
    class="android.widget.LinearLayout"
    package="com.google.android.apps.nexuslauncher" content-desc=""
    checkable="false" checked="false" clickable="true" enabled="true"
    focusable="true" focused="false" scrollable="false"
    long-clickable="false" password="false" selected="false"
    bounds="[82,96][1042,382]">
    <node index="0" text="" resource-id=""
    class="android.widget.RelativeLayout"
    package="com.google.android.apps.nexuslauncher"
    content-desc="" checkable="false" checked="false"
    clickable="false" enabled="true" focusable="false"
    focused="false" scrollable="false" long-clickable="false"
    password="false" selected="false" bounds="[82,140][1042,278]">
    <node index="0" text="Sat, Jul 30"
    resource-id="com.google.android.apps.nexuslauncher:id/clock"
    class="android.widget.TextView"
    package="com.google.android.apps.nexuslauncher"
    content-desc="Sat, Jul 30" checkable="false"
    checked="false" clickable="false" enabled="true"
    focusable="false" focused="false" scrollable="false"
    long-clickable="false" password="false" selected="false"
    bounds="[82,140][1042,204]"/>
    </node>
    </node>
    </node>
    </node>
    </node>
    </node>
    </node>
    </node>
    <node index="2" text="" resource-id="" class="android.view.View"
    package="com.google.android.apps.nexuslauncher" content-desc="Home" checkable="false"
    checked="false" clickable="false" enabled="true" focusable="false" focused="false"
    scrollable="false" long-clickable="false" password="false" selected="false"
    bounds="[0,66][1080,2088]"/>
    <node index="3" text="" resource-id="com.google.android.apps.nexuslauncher:id/page_indicator"
    class="android.view.View" package="com.google.android.apps.nexuslauncher" content-desc=""
    checkable="false" checked="false" clickable="false" enabled="true" focusable="false"
    focused="false" scrollable="false" long-clickable="false" password="false"
    selected="false" bounds="[0,1573][1080,1639]"/>
    <node index="4" text="" resource-id="com.google.android.apps.nexuslauncher:id/hotseat"
    class="android.view.ViewGroup" package="com.google.android.apps.nexuslauncher"
    content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
    focusable="false" focused="false" scrollable="false" long-clickable="false"
    password="false" selected="false" bounds="[0,1639][1080,2088]">
    <node index="0" text="" resource-id="" class="android.view.ViewGroup"
    package="com.google.android.apps.nexuslauncher" content-desc="" checkable="false"
    checked="false" clickable="false" enabled="true" focusable="false" focused="false"
    scrollable="false" long-clickable="false" password="false" selected="false"
    bounds="[38,1639][1042,1807]">
    <node index="0" text="Messages" resource-id="" class="android.widget.TextView"
    package="com.google.android.apps.nexuslauncher" content-desc="Messages"
    checkable="false" checked="false" clickable="true" enabled="true" focusable="true"
    focused="false" scrollable="false" long-clickable="true" password="false"
    selected="false" bounds="[239,1639][440,1807]"/>
    <node index="1" text="Chrome" resource-id="" class="android.widget.TextView"
    package="com.google.android.apps.nexuslauncher" content-desc="Chrome"
    checkable="false" checked="false" clickable="true" enabled="true" focusable="true"
    focused="false" scrollable="false" long-clickable="true" password="false"
    selected="false" bounds="[641,1639][842,1807]"/>
    </node>
    <node index="1" text="" resource-id="" class="android.widget.FrameLayout"
    package="com.google.android.apps.nexuslauncher" content-desc="Search"
    checkable="false" checked="false" clickable="true" enabled="true" focusable="true"
    focused="false" scrollable="false" long-clickable="true" password="false"
    selected="false" bounds="[69,1880][1011,2053]">
    <node index="0" text="" resource-id="com.google.android.apps.nexuslauncher:id/g_icon"
    class="android.widget.ImageView" package="com.google.android.apps.nexuslauncher"
    content-desc="" checkable="false" checked="false" clickable="false" enabled="true"
    focusable="false" focused="false" scrollable="false" long-clickable="false"
    password="false" selected="false" bounds="[113,1933][179,1999]"/>
    <node index="1" text="" resource-id="" class="android.widget.LinearLayout"
    package="com.google.android.apps.nexuslauncher" content-desc="" checkable="false"
    checked="false" clickable="false" enabled="true" focusable="false" focused="false"
    scrollable="false" long-clickable="false" password="false" selected="false"
    bounds="[862,1880][1011,2053]">
    <node index="0" text=""
    resource-id="com.google.android.apps.nexuslauncher:id/mic_icon"
    class="android.widget.ImageView"
    package="com.google.android.apps.nexuslauncher" content-desc="Voice search"
    checkable="false" checked="false" clickable="true" enabled="true"
    focusable="false" focused="false" scrollable="false" long-clickable="false"
    password="false" selected="false" bounds="[862,1880][1011,2053]"/>
    </node>
    </node>
    </node>
    </node>
    </node>
    </node>
    </node>
    </node>
    </hierarchy>

Çıktı, XML şeklinde. Burada “node” adı verilen kısımlar sizin cihazınızdaki o anda bulunan elemanlar olmakta. Örneğin “class” parametresinde “android.widget.FrameLayout” yazması bunun FrameLayout olduğu anlamına gelir. İşleri basitleştiren Python kütüphanesi mevcut.

Olası Hatalar

Bad State

Bad State hatası uiautomator programının ekranı belirtilen sürede çıktısını alamaması ve “timeout” yaşamasından sebep olur. Bad State hatasına 2 şey sebep oluyor olabilir. Birincisi bulunan ekranın statik olmadığı anlamına gelir. Ekranda düzenli olarak elemanlar değişiyor ise bu, muhtemel sebep olabilir. Çözüm ise.. Yoktur. İkinci sebep ise cihaza ulaşılamamasıdır.

Sorun olduğunda, yorum atmaktan çekinmeyin.

Tek Yorum

  1. Ömer Ömer

    ADB ve otomasyon ile uğraşanlar için çok faydalı bir makale olmuş elinize sağlık 👏

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir