with one click
uiautomator-device-control
// UiDevice API for Android device-level control — button simulation, screen rotation, power state, coordinate gestures, and system UI interaction.
// UiDevice API for Android device-level control — button simulation, screen rotation, power state, coordinate gestures, and system UI interaction.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | uiautomator-device-control |
| description | UiDevice API for Android device-level control — button simulation, screen rotation, power state, coordinate gestures, and system UI interaction. |
| tech_stack | ["android"] |
| language | ["kotlin","java"] |
| capability | ["integration-testing"] |
| version | androidx.test.uiautomator:uiautomator 2.4.0-alpha05 |
| collected_at | "2026-04-22T00:00:00.000Z" |
Source: https://developer.android.com/reference/androidx/test/uiautomator/UiDevice, https://developer.android.com/training/testing/other-components/ui-automator-legacy, https://developer.android.com/training/testing/other-components/ui-automator
UiDevice is the primary entry point for UI Automator tests. It provides access to device state (display, orientation, current package) and simulates user actions at the system level — button presses, rotation changes, gestures, and power control. Unlike Espresso, UiDevice operates outside the target app process, enabling cross-app and system-level testing.
UiDevice.getInstance(Instrumentation) is the mandatory first stepUiDevice device = UiDevice.getInstance(
InstrumentationRegistry.getInstrumentation());
// ALWAYS use the Instrumentation-accepting form;
// the no-arg getInstance() is deprecated and prone to misuse.
// Start every test from Home screen
device.pressHome();
String launcherPkg = device.getLauncherPackageName();
device.wait(Until.hasObject(By.pkg(launcherPkg).depth(0)), 5000);
uiAutomator {
startApp("com.example.app")
waitForAppToBeVisible("com.example.app")
activeWindow().waitForStable()
onElement { textAsString() == "Submit" }.click()
}
| Method | What it does |
|---|---|
pressHome() | Press Home button |
pressBack() | Press Back button |
pressRecentApps() | Press Recent Apps button |
pressMenu() | Press Menu button |
pressKeyCode(int keyCode, int metaState?) | Press any key code, optional meta state |
pressKeyCodes(int[] keyCodes) | Press key sequence |
pressEnter() / pressDelete() | Enter / Delete keys |
pressDPadCenter/Up/Down/Left/Right() | D-pad directional buttons |
All setters freeze rotation after applying — call unfreezeRotation() to allow physical rotation again.
| Method | Effect |
|---|---|
setOrientationLandscape() | Force landscape (width ≥ height) |
setOrientationPortrait() | Force portrait (height ≥ width) |
setOrientationNatural() | Return to device's natural orientation |
setOrientationLeft() / setOrientationRight() | Rotate left/right |
freezeRotation() / unfreezeRotation() | Freeze/unfreeze current rotation |
getDisplayRotation() | Query current rotation value |
isNaturalOrientation() | Check if display is in natural orientation |
API 30+ multi-display variants accept int displayId: e.g. setOrientationLandscape(int).
wakeUp() — presses power if screen is OFF, no-op otherwisesleep() — presses power if screen is ON, no-op otherwiseisScreenOn() — queries power manager stategetDisplayWidth() / getDisplayHeight() — pixels, adjusted for current orientationgetDisplaySizeDp() — device-independent pixels, actual screen size (ignores status bar)getDisplayWidth(int displayId), getDisplayHeight(int displayId)Each step is throttled to ~5ms. A 100-step swipe ≈ 0.5 seconds.
device.click(500, 1000); // tap at coordinates
device.swipe(x1, y1, x2, y2, steps); // linear swipe
device.swipe(Point[] segments, int segmentSteps); // multi-segment swipe
device.drag(startX, startY, endX, endY, steps); // drag (like swipe)
openNotification() — open notification shadeopenQuickSettings() — open Quick Settings shadeexecuteShellCommand("am start -a android.settings.SETTINGS") — launch system Settings (discouraged for complex commands; prefer UiAutomation.executeShellCommandRwe)Bitmap bmp = device.takeScreenshot();
device.takeScreenshot(new File("/sdcard/screen.png")); // default 1.0 scale, 90% quality
device.takeScreenshot(new File("/sdcard/screen.png"), 0.5f, 80); // custom scale/quality
Screenshots are automatically adjusted for screen rotation.
device.wait(Condition, timeoutMs) — generic condition waitdevice.wait(SearchCondition, timeoutMs) — search-based waitwaitForIdle() / waitForIdle(timeoutMs) — wait for event queue idle (no hard UI-stability guarantee)waitForWindowUpdate(packageName, timeoutMs) — wait for window content updateperformActionAndWait(action, EventCondition, timeoutMs) — execute action, then waitwaitForAppToBeVisible(packageName, timeoutMs) — wait for app to appearactiveWindow().waitForStable() — wait until accessibility tree stops changingwaitForRootInActiveWindow(timeoutMs, sleepIntervalMs, clearCache) — wait for root nodegetCurrentPackageName() — last package reporting accessibility events (reliable)getLauncherPackageName() — default launcher package (varies by OEM)getProductName() — device product namegetCurrentActivityName() — deprecated, unreliablefindObject(BySelector) → UiObject2 or nullfindObjects(BySelector) → List<UiObject2>findWindow(ByWindowSelector) → UiWindow or null (2.4.0-beta02+)findWindows(ByWindowSelector) → sorted List (descending Z-order)hasObject(BySelector) / hasWindow(ByWindowSelector) → boolean@SdkSuppress(minSdkVersion = 18). Multi-display methods need API 30+.getInstance(Instrumentation): The no-arg form is deprecated and hides the Instrumentation dependency.unfreezeRotation() to re-enable physical rotation after setOrientationLandscape() etc.getDisplayWidth()/getDisplayHeight() before computing coordinates — dimensions change with rotation.waitForStable() (modern) for UI stability.UiAutomation.executeShellCommandRwe for complex commands.setCompressedLayoutHeirarchy is misspelled; the correct method is setCompressedLayoutHierarchy.UiDevice.findObject() with BySelector or the modern onElement {} predicate DSL to find UI elements before interacting.pressHome() + By.pkg(launcherPackage) to start cross-app flows; use openNotification() / openQuickSettings() for SystemUI interaction.UiWatcher instances via registerWatcher() to handle permission dialogs or ANR popups that may appear during device-level actions.@After to avoid contaminating other tests.getDisplayWidth()/getDisplayHeight() rather than hardcoding.