What this page is: A structured runbook for AI assistants (ChatGPT, Claude, Cursor, etc.) with command-line access. When a user asks for help managing local Genymotion Desktop Android virtual devices, you can execute these gmtool and genyshell commands directly in their terminal.
For cloud devices: Use the gmsaas CLI runbook instead.
Install Genymotion Desktop: genymotion.com/download | Official docs: docs.genymotion.com/desktop
gmtool and genyshell are NOT on PATH. You must use the full path to the binary. See platform paths below.
| Tool | macOS | Windows | Linux |
|---|---|---|---|
gmtool |
/Applications/Genymotion.app/Contents/MacOS/gmtool |
C:\Program Files\Genymobile\Genymotion\gmtool.exe |
$HOME/genymotion/gmtool or /opt/genymotion/gmtool |
genyshell |
/Applications/Genymotion Shell.app/Contents/MacOS/genyshell |
C:\Program Files\Genymobile\Genymotion\genyshell.exe |
$HOME/genymotion/genymotion-shell |
adb (bundled) |
/Applications/Genymotion.app/Contents/MacOS/tools/adb |
C:\Program Files\Genymobile\Genymotion\tools\adb.exe |
$HOME/genymotion/tools/adb |
# Auto-discover gmtool on macOS/Linux:
$ GM=$(find /Applications /opt $HOME/genymotion -name gmtool -type f 2>/dev/null | head -1)
$ [ -z "$GM" ] && echo "gmtool not found — install from https://www.genymotion.com/download/" && exit 1
$ $GM version
Version : 3.9.0
gmtool supports --format json as a global option BEFORE the subcommand: gmtool --format json admin list
However, JSON only works on admin list. All other commands return plain text regardless of the flag.
| Output behavior | Commands |
|---|---|
| JSON supported | admin list |
| No output on success (check exit code 0) | admin start, admin stop, admin clone, device adbconnect |
| Plain text only | admin details, admin create, admin delete, admin hwprofiles, admin osimages, license info, version, config list |
| Errors always plain text | All commands, even with --format json |
For device commands, the --name flag goes AFTER the action, not before:
gmtool device adbconnect --name "my-device"gmtool device --name "my-device" adbconnectgmtool device -n "my-device" adbconnect| Tier | Available Commands |
|---|---|
| Free (Personal Use) | admin list, admin start, admin stop, version |
| Paid (Indie/Business) | All free commands plus: admin create, admin edit, admin details, admin clone, admin delete, admin stopall, admin factoryreset, admin hwprofiles, admin osimages, device install/push/pull/flash/adbconnect/adbdisconnect/logcatdump/logcatclear |
If the user gets "A license is required to use this feature", they need a paid license or must use the Genymotion Desktop GUI for that operation.
admin list)The only command with reliable JSON output. Use it to get device names, UUIDs, states, and ADB serials:
$ gmtool --format json admin list
{
"exit_code": 0,
"exit_code_desc": "SUCCESS",
"instances": [
{
"adb_serial": "127.0.0.1:6555", // ADB address when running
"adb_serial_port": 6555,
"name": "Google Nexus 4", // Use this or uuid to target device
"recipe": {
"osimage": {
"android_version": "15.0.0",
"api_version": "35",
"architecture": "arm64",
"image_version": "3.4.0",
"is_beta": false,
"name": "Android 15.0"
}
},
"state": "on", // "off" or "on"
"uuid": "b54fe1d2-0e30-42e6-b62b-94b3596088b9"
}
]
}
Note: adb_serial_port is 6554 when off but changes to 6555 when running. Always read adb_serial from admin list after starting the device.
Always run these checks before executing any gmtool workflow.
# 1. Find gmtool
$ GM=/Applications/Genymotion.app/Contents/MacOS/gmtool # macOS
$ $GM version
Version : 3.9.0
# 2. Check license tier
$ $GM license info
License Type : Trial
Activated Workstations : 1
Expires on : April 16, 2026 16:59:58
# 3. Check hypervisor configuration
$ $GM config list
hypervisor=qemu
virtual_devices.directory=/Users/me/.Genymobile/Genymotion/deployed/
# 4. List existing devices
$ $GM --format json admin list | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'{len(d[\"instances\"])} devices found')"
1 devices found
When the user says: "Create an Android emulator" / "Set up a local Genymotion device" / "I need a Pixel 9 on Android 14"
$ gmtool admin hwprofiles
UUID NAME DISPLAY SOURCE
------------------------------------ ----------------------- ------------------- ------
b56ca2cf-2c9d-42a7-9040-53b9c0546928 Google Pixel 9 1080 x 2424 dpi 422 VENDOR
90f8c57b-113e-46b7-aaba-322d3329b016 Samsung Galaxy S24 1080 x 2340 dpi 418 VENDOR
e104f058-b291-4764-8e0d-d9ff78a41192 Custom Phone 768 x 1280 dpi 320 VENDOR
$ gmtool admin osimages
UUID NAME ANDROID VERSION API VERSION BETA ARCHITECTURE SOURCE
------------------------------------ ------------ --------------- ----------- ---- ------------ ----------
160ea4fa-d62c-4207-b540-7100541f6dc6 Android 14.0 14.0.0 34 No arm64 Genymotion
a27c4113-a385-4013-856f-c5bde3dcb69c Android 15.0 15.0.0 35 No arm64 Genymotion
e04c1797-dda4-40b1-b850-dc62a2c008c7 Android 16.0 16.0.0 36 Yes arm64 Genymotion
These are plain text tables (no JSON). Use the NAME column (not UUID) when creating devices.
If you get "A license is required", the user must create devices via the Genymotion Desktop GUI instead.
$ gmtool admin create "Google Pixel 9" "Android 14.0" "my-device"
Creating my-device from hwprofile Google Pixel 9 and osimage Android 14.0
Downloading OsImage...
(32MB / 800MB) (257MB / 800MB) (519MB / 800MB) (800MB / 800MB) Download finished
OsImage ready
Virtual device created successfully
Arguments: <hwprofile NAME> <osimage NAME> <device name>. Output is plain text with download progress.
Options: --density 480, --width 1080, --height 2400, --nbcpu 4, --ram 4096, --navbar on, --root-access on, --quickboot on (QEMU only)
$ gmtool admin start "my-device"
# No output on success (exit code 0). Blocks until device is booted.
# Use -t 300 to set a 5-minute timeout.
# Use --coldboot to force a full boot cycle.
If exit code 3 ("The virtual device stopped unexpectedly"): Run with -v for details: gmtool -v admin start "my-device". Look for Player exited early with error code. Common cause: port 6379 conflict (see Troubleshooting).
Option A — Use gmtool (paid):
$ gmtool device adbconnect --name "my-device"
# No output on success (exit code 0).
# CRITICAL: --name goes AFTER "adbconnect", not before.
Option B — Read ADB serial from admin list and connect directly (free):
$ ADB_SERIAL=$(gmtool --format json admin list | python3 -c \
"import sys,json; instances=json.load(sys.stdin)['instances']; \
print(next(i['adb_serial'] for i in instances if i['name']=='my-device'))")
$ adb connect $ADB_SERIAL
already connected to 127.0.0.1:6555
$ adb devices
List of devices attached
127.0.0.1:6555 device
# With gmtool (paid) — --name goes AFTER the action:
$ gmtool device install --name "my-device" app.apk
$ gmtool device push --name "my-device" local.txt /sdcard/Download/
Pushing local.txt to my-device...
File pushed to my-device
$ gmtool device pull --name "my-device" /sdcard/file.txt .
$ gmtool device logcatdump --name "my-device" logcat.txt
Writing logcat for my-device into logcat.txt...
# Or with ADB directly (free, once connected):
$ adb -s 127.0.0.1:6555 install app.apk
$ adb -s 127.0.0.1:6555 shell
$ adb -s 127.0.0.1:6555 exec-out screencap -p > screenshot.png
$ adb -s 127.0.0.1:6555 shell getprop ro.build.version.release
15
$ gmtool admin stop "my-device"
Virtual device stopped successfully
When the user says: "Simulate GPS location" / "Set battery to low" / "Test network conditions" / "Change device rotation"
genyshell controls sensors on running virtual devices. The device must be started first with gmtool admin start.
If only one device is running, genyshell auto-selects it. With multiple devices, use -r <IP> to target one.
$ genyshell -c "gps setlatitude 48.8566" # Single command
$ genyshell -f test_script.sh # Run script file
$ genyshell -r 127.0.0.1 # Target specific device IP
$ genyshell -q -c "battery getlevel" # Quiet mode (less banner noise)
Every -c call prints a welcome banner. When parsing output, look for the result AFTER the "Genymotion virtual device selected:" line:
Connection mode: local host
Welcome to Genymotion Shell
Genymotion virtual device selected: Google Nexus 4
GPS Latitude set to: 48.8566 <-- actual result is here
$ genyshell -c "gps setstatus enabled"
$ genyshell -c "gps setlatitude 48.8566"
$ genyshell -c "gps setlongitude 2.3522"
$ genyshell -c "gps setaltitude 35.0"
$ genyshell -c "gps setaccuracy 1.0"
$ genyshell -c "gps setbearing 180.0"
# Read back:
$ genyshell -c "gps getlatitude"
GPS Latitude: 48.8566
$ genyshell -c "battery setmode manual"
$ genyshell -c "battery setlevel 15"
$ genyshell -c "battery setstatus discharging"
# Status values: charging, discharging, full, not-charging
# Read back:
$ genyshell -c "battery getlevel"
Battery level: 15%
# Rotation
$ genyshell -c "rotation setangle 90" # 0, 90, 180, 270
# Network (Android 8+)
$ genyshell -c "network setstatus enabled"
$ genyshell -c "network setsignalstrength 3" # 0-4
$ genyshell -c "network setmobileprofile edge" # full|gsm|hscsd|gprs|edge|umts|hsdpa|lte|5gnr
# Simulate incoming call/SMS
$ genyshell -c "phone call 5551234567"
$ genyshell -c 'phone sms 5551234567 "Test message"'
# Device management
$ genyshell -c "devices list"
$ genyshell -c "devices select 127.0.0.1"
#!/bin/bash
# delivery_route_test.sh — Run with: genyshell -f delivery_route_test.sh
gps setstatus enabled
gps setlatitude 48.8566
gps setlongitude 2.3522
# Pause in your test framework, then update coordinates:
gps setlatitude 48.8606
gps setlongitude 2.3376
battery setmode manual
battery setlevel 10
battery setstatus discharging
admin details — Key : Value Format$ gmtool admin details "my-device"
Name : Google Nexus 4
UUID : b54fe1d2-0e30-42e6-b62b-94b3596088b9
Android Version : 15.0.0
API Level : 35
Screen Width : 768
Screen Height : 1280
Screen DPI : 320
Nb CPU : 4
RAM : 2048
State : On
IP : 127.0.0.1
ADB Serial : 127.0.0.1:6555
Root Access : false
Quickboot : true
# Parse a specific field:
$ gmtool admin details "my-device" | grep "^Android Version" | awk -F': ' '{print $2}'
15.0.0
hwprofiles and osimages — Fixed-Width TableParse by splitting on 2+ consecutive spaces, or use column positions. The NAME column is what you pass to admin create.
Global options: -t, --timeout <0-3600> (seconds), -v, --verbose, --format <json|compactjson> (before subcommand)
| Command | Description | License | Output |
|---|---|---|---|
| Device Administration | |||
gmtool --format json admin list [--running|--off] | List devices | Free | JSON |
gmtool admin start <name|uuid> [--coldboot] | Start device | Free | None (exit code) |
gmtool admin stop <name|uuid> | Stop device | Free | Plain text |
gmtool admin stopall | Stop all devices | Paid | None |
gmtool admin create <hw> <os> <name> [opts] | Create device | Paid | Download progress |
gmtool admin edit <name|uuid> [opts] | Edit device config | Paid | None |
gmtool admin details <name|uuid> | Device properties | Paid | Key : Value |
gmtool admin clone <name|uuid> <new_name> | Duplicate device | Paid | None (exit code) |
gmtool admin delete <name|uuid> | Delete device | Paid | Plain text |
gmtool admin factoryreset <name|uuid> | Factory reset | Paid | None |
gmtool admin hwprofiles | List hardware profiles | Paid | Table |
gmtool admin osimages | List OS images | Paid | Table |
gmtool admin logzip <path> | Generate log archive | Paid | None |
Device Interaction (--name goes AFTER the action) | |||
gmtool device adbconnect --name <device> | Connect to ADB | Paid | None (exit code) |
gmtool device adbdisconnect --name <device> | Disconnect ADB | Paid | None |
gmtool device install --name <device> <apk> | Install APK | Paid | Plain text |
gmtool device push --name <device> <src> <dst> | Push file to device | Paid | Plain text |
gmtool device pull --name <device> <src> <dst> | Pull file from device | Paid | Plain text |
gmtool device flash --name <device> <zip> | Flash archive | Paid | Plain text |
gmtool device logcatdump --name <device> <file> | Dump logcat | Paid | Plain text |
gmtool device logcatclear --name <device> | Clear logcat | Paid | None |
| Configuration | |||
gmtool config list | Show all config (KEY=VALUE) | Free | Plain text |
gmtool config get <key> | Get single config value | Free | Plain text |
gmtool config set hypervisor <qemu|virtualbox> | Switch hypervisor | Free | None |
gmtool config set use_custom_sdk on | Enable custom Android SDK | Free | None |
gmtool config set sdk_path <path> | Set Android SDK path | Free | None |
gmtool config reset | Restore defaults | Free | None |
gmtool config signout | Sign out, remove license | Free | None |
| License | |||
gmtool license info | License type & expiry | Free | Plain text |
gmtool license register <key> | Activate license | Free | Plain text |
gmtool license count | Activated workstations | Free | Plain text |
gmtool license validity | Days remaining | Free | Plain text |
admin create / admin edit)| Option | Description | Notes |
|---|---|---|
--density <120-640> | Screen density (dpi) | |
--width <value> / --height <value> | Screen dimensions | |
--virtualkeyboard <on|off> | Virtual keyboard | |
--navbar <on|off> | Android navigation bar | |
--nbcpu <value> | Number of processors | |
--ram <value> | Memory in MB | |
--network-mode <nat|bridge> | Network mode | VirtualBox only |
--root-access <on|off> | Root access | Android 12+ default: off |
--quickboot <on|off> | Resume state | QEMU only, not Windows |
--sysprop <prop>:<val> | Build properties | MODEL, BRAND, MANUFACTURER, etc. |
| Exit Code | Meaning | Fix |
|---|---|---|
| 0 | Success | — |
| 3 | Command failed / device won't start | Try --coldboot. Run with -v for details. Check port 6379 conflict. |
| 4 | Virtualization engine unresponsive | Hypervisor misconfigured or not installed |
| 5 | Virtual device not found | Wrong name/UUID — check admin list |
| 13 | Unable to start device | Check FAQ |
| 14 | Requires paid license | User must upgrade or use the GUI |
QEMU forwards port 6379 from the virtual device to localhost. If Redis (or anything else) is already on port 6379, the device will fail to start with exit code 3.
# Check for port conflict:
$ lsof -i -P -n | grep 6379
redis-ser 4526 user 6u IPv4 ... TCP 127.0.0.1:6379 (LISTEN)
# Fix: stop Redis before starting the device
$ brew services stop redis # macOS
$ sudo systemctl stop redis # Linux
# Then start the device
$ gmtool admin start "my-device"
Hyper-V must be completely disabled when using VirtualBox:
> bcdedit /set hypervisorlaunchtype off
# Reboot required
# Flash ARM translation for x86 devices running ARM-only apps:
$ adb push Genymotion-ARM-Translation.zip /sdcard/Download/
$ adb shell "/system/bin/flash-archive.sh /sdcard/Download/Genymotion-ARM-Translation.zip"
Note: Apple Silicon Macs run arm64 images natively — no translation needed, but only arm64-v8a apps are supported.
Google Play is not pre-installed. Flash Open GApps:
$ gmtool device flash --name "my-device" open_gapps.zip
Android 12+ images are non-rooted by default:
# Enable at creation:
$ gmtool admin create "Pixel 9" "Android 14.0" "rooted-device" --root-access on
# Or toggle on a running device via ADB:
$ adb root # Enable root shell
$ adb unroot # Disable root shell
| Platform | Supported Versions | Default Hypervisor | Architecture |
|---|---|---|---|
| macOS | Sequoia 15, Sonoma 14 | QEMU (recommended) | Intel + Apple Silicon (Rosetta required) |
| Windows | 10/11 64-bit (x86_64 only) | VirtualBox (included) | x86_64 only. Hyper-V must be disabled for VBox. |
| Linux | Ubuntu 24.04, Debian 13, Fedora 43 | QEMU/KVM (embedded) | x86_64 only |
| Platform | Apps Supported |
|---|---|
| Intel Mac/PC | x86_64 (Android 11+), x86 (Android 5-10), ARM via translation |
| Apple Silicon Mac | arm64-v8a only |
| Linux x86_64 | x86_64, x86, ARM via translation |