A bilingual (English / العربية) PyQt5 desktop application for managing and diagnosing Android devices over ADB (Android Debug Bridge). Dark-themed, modular, and built around a background worker thread so long-running adb commands never freeze the UI.
Diagnostics & info
- Deep device diagnostics — identity, CPU, RAM, storage, battery, display, sensors
- Quick info panel and live logcat viewer
Media
- Screenshot capture
- Screen recording (configurable duration)
- Screen mirroring & control via scrcpy — keep-screen-off, always-on-top, and max-FPS options, launched detached so the app never blocks
Files & apps
- Visual File Manager — browse the device's filesystem (
QListWidget), navigate into folders, go up a directory, then push/pull files and folders - Install APK
- App package listing and uninstall
Connectivity
- Wireless ADB — a 3-step USB → Wi-Fi flow: enable TCP/IP mode (
adb tcpip 5555), auto-detect the device's Wi-Fi IP (ip route/ip addr show wlan0), then connect over the network — with clear diagnostics for the two most common failure causes (network/AP isolation timeouts, and Windows Firewall/antivirus blocking outbound socket access)
Device control
- Power/reboot controls (reboot, recovery, bootloader, power button)
- Full backup (
adb backup) - Factory reset (with a typed confirmation guard)
UI
- Full bilingual support (English / Arabic), including RTL layout mirroring
- Dark theme applied consistently across every widget, including checkboxes and inputs
The app follows an MVC-style separation: ui/ only builds widgets and wires
signals/slots, core/ and tasks/ own all adb/subprocess/filesystem logic,
and config/ owns everything presentational that isn't code (translations,
stylesheet).
main.py # Entry point — creates QApplication and MainWindow
config/
texts.py # TEXTS: all bilingual (en/ar) UI strings
style.py # STYLE_SHEET: the app's dark Qt stylesheet
core/ # Low-level primitives — no PyQt5 imports here
adb.py # run_cmd(), check_device(), getprop()
worker.py # Worker(QThread): runs a task_* function off the UI thread
scrcpy.py # scrcpy detection + detached, non-blocking launch
tasks/ # One function per background operation.
adb_tasks.py # Each task_*(log, ...) runs inside a Worker and
wireless_tasks.py # returns a result dict; `log` reports progress
file_manager_tasks.py # back to the UI via a Qt signal.
ui/
main_window.py # MainWindow: sidebar nav + one page per feature
Adding a new feature means: add background logic as a task_* function in
tasks/, add any bilingual strings to config/texts.py, then add a
_build_x_page() + handler methods in ui/main_window.py. The UI never
calls adb/subprocess directly — it only calls core/tasks functions
through a Worker.
- Python 3.8+ (developed against 3.12)
adbavailable on your system PATH- scrcpy on PATH (optional — only needed for the Screen Mirroring tab; the app detects if it's missing and shows a clear error instead of crashing)
- USB debugging enabled on the Android device (Developer Options)
python -m venv venv
.\venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install PyQt5 pyinstaller pillow.\venv\Scripts\Activate.ps1
python main.pyRun
main.pyfrom the project root — it's the entry point. Launching a file insideui/,core/, ortasks/directly (e.g.python ui\main_window.py) will fail withModuleNotFoundError: No module named 'config', because Python only puts a directly-run script's own folder onsys.path, not the project root where the sibling packages live.
.\venv\Scripts\pyinstaller.exe --clean --onefile --windowed --name "ADB_PRO" --icon "icons8-android-24.ico" main.pyPyInstaller follows the import graph from main.py, so config/, core/,
tasks/, and ui/ are bundled automatically — no extra --add-data or
--paths flags needed as long as you build from the project root.
To debug a startup crash in the packaged EXE, build with a console attached:
.\venv\Scripts\pyinstaller.exe --clean --onefile --console --log-level DEBUG --name "ADB_PRO_debug" --icon "icons8-android-24.ico" main.py
.\dist\ADB_PRO_debug.exeModuleNotFoundError: No module named 'config'— you ran a file inside a subpackage directly instead ofmain.pyfrom the project root. See the note under Run above.- EXE opens a console when clicking buttons — child
adbprocesses are launched withsubprocess.CREATE_NO_WINDOWon Windows (core/adb.py,core/scrcpy.py); rebuild after pulling the latest code. - Wireless ADB: "Wi-Fi connection failed: timeout" — the PC never got a response from the phone's IP. Almost always means the phone and PC aren't actually on the same network/subnet, or the Wi-Fi network blocks device-to-device traffic (common on office/campus/guest Wi-Fi, "AP/client isolation"). Try a personal hotspot or home router instead.
- Wireless ADB: error 10013 ("forbidden by its access permissions") —
a Windows-level socket block, not a network isolation issue. Check Windows
Firewall (an outbound rule for
adb.exe, not just inbound), any third-party antivirus's own firewall, and whether a VPN client is active — VPNs frequently block direct LAN connections unless you enable a "local network access" / split-tunneling option. - Screen Mirroring says scrcpy wasn't found — install
scrcpy and make sure it's on PATH
(test with
scrcpy --versionin a terminal). - Icon error about PNG format during PyInstaller build — install
pillow, or convert the icon to.icofirst.
- The packaged EXE bundles Qt platform plugins; if it fails to start, make sure antivirus/Windows Defender isn't blocking its temporary extraction.
ADB_PRO.pyis the original single-file version of this app, kept in the repository for reference; it is no longer maintained — all development happens in the modularmain.py+config//core//tasks//ui/layout described above.
Updated: 2026-07-21