Metadata-Version: 2.4
Name: jaydroid
Version: 0.1.0
Summary: A beginner-friendly Python wrapper for simulating Android actions via ADB (tap, swipe, power on/off).
Author: Johnston Kweku Abubakar
License: MIT
Project-URL: Homepage, https://github.com/johnston-kweku/jaydroid
Project-URL: Issues, https://github.com/johnston-kweku/jaydroid/issues
Keywords: adb,android,automation,adb-wrapper
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Intended Audience :: Developers
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# jaydroid

`jaydroid` is a small Python wrapper around [Android Debug Bridge (ADB)](https://developer.android.com/tools/adb). It provides helpers for connecting to an Android device, reading display dimensions and device info, sending button input, capturing the screen, and performing swipe and tap gestures.

This is my first Python package, built as a way to learn how to design, structure, and publish one from scratch. I'm documenting the build process — bugs, refactors, and design decisions — as a video series. Expect it to keep growing.

## Requirements

- Python 3.8 or newer
- ADB installed and available on your `PATH`
- An Android device or emulator connected to ADB
- USB debugging enabled when using a physical device

Check the connection with:

```bash
adb devices
```

## Installation

```bash
pip install jaydroid
```

For local development, from the project directory:

```bash
python -m pip install -e .
```

## Quick start

`jaydroid` exposes ready-to-use instances, so there's no setup required beyond connecting your device:

```python
from jaydroid import device, button, swipe, tap

device.connect()

button.wake(delay=1)
swipe.swipe_up()
tap.tap(360, 640)
```

`device.connect()` checks that a device or emulator is actually reachable over ADB and loads its display dimensions. It's the one required step before using anything that depends on screen size (like the directional swipe helpers).

## Delays

Every `Button`, `Screen`, `Swipe`, and `Tap` method accepts an optional `delay` argument, in seconds (default `0`). The delay runs *after* the action completes successfully — "do this, then wait" — so it's useful for giving the device a moment to catch up before your next command fires:

```python
button.wake(delay=1)
swipe.swipe_up(delay=0.5)
```

If a command fails, the delay is skipped — you'll see the error immediately rather than waiting first.

## Gestures

### Swipe

```python
from jaydroid import swipe

swipe.swipe_up()
swipe.swipe_down()
swipe.swipe_left()
swipe.swipe_right()
swipe.unlock()  # alias for swipe_up()
```

Directional swipes are calculated as a percentage of the connected device's display size, so they scale across different screens rather than relying on hardcoded pixels:

- Left and right: 10% to 90% of display width, at 50% of height
- Up and down: 50% of display width, from 80% to 10% of height

For custom coordinates, use `swipe.swipe(x1, y1, x2, y2)`:

```python
swipe.swipe(600, 640, 100, 640, delay=0.5)
```

### Tap

```python
from jaydroid import tap

tap.tap(360, 640)
tap.double_tap(360, 640)
tap.longpress(360, 640, duration=1000)
```

## Buttons

```python
from jaydroid import button

button.power()
button.wake()
button.sleep()
button.home()
button.back()
button.recent_apps()
button.menu()
button.volume_up()
button.volume_down()
```

Each accepts `delay=0`.

## Screen

```python
from jaydroid.screen import Screen

screen = Screen()
screen.capture()
screen.screenshot(filename='screen.png', pull=True)
screen.screenrecord(filename='recording.mp4', pull=True, duration=10)
```

`screenshot()` and `screenrecord()` save to `/sdcard/` on the device by default, and can optionally pull the file to your local directory with `pull=True`.

## Device information

```python
from jaydroid import device

device.connect()
print(device.width, device.height)
print(device.is_connected())
print(device.get_android_version())
print(device.battery_info())
```

- `width` and `height` are only available after `connect()` — accessing them beforehand raises `DeviceNotConnectedError`.
- `is_connected()`, `get_android_version()`, and `battery_info()` check the ADB connection live each time they're called, so they don't require `connect()` to have been run first.
- `battery_info()` returns a dictionary parsed from `adb shell dumpsys battery`. Core fields (`level`, `status`, `health`, `voltage`, `temperature`, `technology`, and the `*_powered` flags) are consistently present across devices, but the full set of keys can vary by manufacturer, since some OEMs include additional proprietary fields.

## Errors

`jaydroid` raises specific exceptions instead of generic ones, so you can catch exactly what went wrong:

- `DeviceNotFoundError` — raised by `connect()` when no device or emulator is reachable over ADB.
- `DeviceNotConnectedError` — raised when accessing `width`/`height` before `connect()` has been called.
- `AdbCommandError` — raised when an ADB command itself fails (e.g. the device disconnects mid-session). Includes ADB's own error output.

```python
from jaydroid import device
from jaydroid.exceptions import DeviceNotFoundError

try:
    device.connect()
except DeviceNotFoundError:
    print("No device connected — plug one in and try again.")
```

## Roadmap

Planned additions include WiFi status, installed app listing, and more device/system information. This package is under active development.

## Author

Built by Johnston Kweku Abubakar ([@johnston-kweku](https://github.com/johnston-kweku)) — this is my first Python package, built while learning to design, structure, and publish one from scratch.

## License

This project is licensed under the MIT License. See [LICENSE](LICENSE).
