As part of our effort to automate taking screenshots, we also need the ability to spin up Android emulators via the command line. This all needs to run headless, so it's necessary to be able to spin up Android emulators from the command line. A quick look at my ps
output showed this to be even simpler a task than I'd anticipated.
To launch a new instance of the Android Player from the command line, all you need to do is run:
"/Applications/Xamarin Android Player.app/Contents/Helpers/Xamarin Android Player.app/Contents/MacOS/Xamarin Android Player" --name "Nexus 5 (KitKat)"
You can substitute the name there for whichever image you want to spin up. Once it finishes launching it'll be in a locked state. From the command line you can unlock it by using the adb
command:
adb shell input keyevent 82
Here's a little F# script I put together to run through this sequence. If it finds any Android Player processes running, it assumes one is already running and skips that step. If you have the main Xamarin Android app running, even without having started any emulators from within it, this check will treat that as if an emulator is running. If none are found, it launches one and waits for 30 seconds before trying to unlock. Crude, but it does the job for now.
let startAndroidEmulator = fun (emulatorName:string) ->
let xamarinPlayerPath = "/Applications/Xamarin Android Player.app/Contents/Helpers/Xamarin Android Player.app/Contents/MacOS/Xamarin Android Player"
let exec = fun file args ->
let info = new ProcessStartInfo()
info.FileName <- file
info.Arguments <- args
let proc = new Process()
proc.StartInfo <- info
proc.Start() |> ignore
if Process.GetProcessesByName("Xamarin Android").Length = 0 then
exec xamarinPlayerPath (String.Format("--name \"{0}\"", emulatorName))
Async.Sleep(30 * 1000) |> Async.RunSynchronously
exec "adb" "shell input keyevent 82"