public override Task <DiagnosticResult> Examine(SharedState history) { AndroidSdk.AvdManager avdManager = null; var javaHome = history.GetEnvironmentVariable("JAVA_HOME"); string java = null; if (!string.IsNullOrEmpty(javaHome) && Directory.Exists(javaHome)) { java = Path.Combine(javaHome, "bin", "java" + (Util.IsWindows ? ".exe" : "")); } var avds = new List <AndroidSdk.AvdManager.Avd>(); // Try invoking the java avdmanager library first if (File.Exists(java)) { avdManager = new AndroidSdk.AvdManager(java, history.GetEnvironmentVariable("ANDROID_SDK_ROOT") ?? history.GetEnvironmentVariable("ANDROID_HOME")); avds.AddRange(avdManager.ListAvds()); } // Fallback to manually reading the avd files if (!avds.Any()) { avds.AddRange(AndroidSdk.AvdManager.ListAvdsFromFiles()); } if (avds.Any()) { var emu = avds.FirstOrDefault(); ReportStatus($"Emulator: {emu.Name ?? emu.SdkId} found.", Status.Ok); return(Task.FromResult(DiagnosticResult.Ok(this))); } // If we got here, there are no emulators at all var missingEmulators = RequiredEmulators; if (!missingEmulators.Any()) { return(Task.FromResult(DiagnosticResult.Ok(this))); } AndroidSdk.AvdManager.AvdDevice preferredDevice = null; try { if (avdManager != null) { var devices = avdManager.ListDevices(); preferredDevice = devices.FirstOrDefault(d => d.Name.Contains("pixel", StringComparison.OrdinalIgnoreCase)); } } catch (Exception ex) { var msg = "Unable to find any Android Emulators. You can use Visual Studio to create one if necessary: [underline]https://docs.microsoft.com/xamarin/android/get-started/installation/android-emulator/device-manager[/]"; ReportStatus(msg, Status.Warning); Util.Exception(ex); return(Task.FromResult( new DiagnosticResult(Status.Warning, this, msg))); } return(Task.FromResult(new DiagnosticResult( Status.Error, this, new Suggestion("Create an Android Emulator", missingEmulators.Select(me => new ActionSolution((sln, cancel) => { try { var installer = new AndroidSDKInstaller(new Helper(), AndroidManifestType.GoogleV2); installer.Discover(); var sdkInstance = installer.FindInstance(null); var installedPackages = sdkInstance.Components.AllInstalled(true); var sdkPackage = installedPackages.FirstOrDefault(p => p.Path.Equals(me.SdkId, StringComparison.OrdinalIgnoreCase)); if (sdkPackage == null && (me.AlternateSdkIds?.Any() ?? false)) { sdkPackage = installedPackages.FirstOrDefault(p => me.AlternateSdkIds.Any(a => a.Equals(p.Path, StringComparison.OrdinalIgnoreCase))); } var sdkId = sdkPackage?.Path ?? me.SdkId; avdManager.Create($"Android_Emulator_{me.ApiLevel}", sdkId, device: preferredDevice?.Id, tag: "google_apis", force: true, interactive: true); return Task.CompletedTask; } catch (Exception ex) { ReportStatus("Unable to create Emulator. Use Visual Studio to create one instead: https://docs.microsoft.com/xamarin/android/get-started/installation/android-emulator/device-manager", Status.Warning); Util.Exception(ex); } return Task.CompletedTask; })).ToArray())))); }
static IEnumerable <DeviceData> AndroidDevices() { const int HighPriority = 0; const int MedPriority = 1; const int LowPriority = 2; var results = new List <(DeviceData Device, int Priority)>(); // Get ADB Devices (includes emulators) var adb = new AndroidSdk.Adb(); var adbDevices = adb.GetDevices() ?? Enumerable.Empty <AndroidSdk.Adb.AdbDevice>(); // Split out emulators and physical devices var emulators = adbDevices?.Where(d => d.IsEmulator)?.Select(e => new { EmulatorName = adb.GetEmulatorName(e.Serial), Emulator = e }); var devices = adbDevices?.Where(d => !d.IsEmulator); // Physical devices are easy foreach (var d in devices) { results.Add((new DeviceData { IsEmulator = false, IsRunning = true, Name = d.Device, Platforms = new[] { "android" }, Serial = d.Serial, Version = d.Model }, HighPriority)); } // Get all Avds var avdManager = new AndroidSdk.AvdManager(); var avds = avdManager.ListAvds() ?? Enumerable.Empty <AndroidSdk.AvdManager.Avd>(); // Look through all avd's to list, but let's be smart and see if any of them // are already running (so were listed in the adb devices output) foreach (var a in avds) { var avdConfig = ParseAvdConfigIni(Path.Combine(a.Path, "config.ini")); var abi = avdConfig?["abi.type"] ?? string.Empty; var architecture = avdConfig?["hw.cpu.arch"] ?? string.Empty; var manufacturer = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(avdConfig?["hw.device.manufacturer"] ?? string.Empty); var model = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(avdConfig?["hw.device.name"] ?? string.Empty); var tag = avdConfig?["tag.display"] ?? string.Empty; // See if ADB returned a running instance var emulator = emulators.FirstOrDefault(e => e.EmulatorName == a.Name); results.Add((new DeviceData { IsEmulator = true, IsRunning = emulator != null, Name = a.Name, Details = emulator != null ? emulator.Emulator.Product + " " + emulator.Emulator.Model : manufacturer + " " + model + " (" + architecture + ")", Platforms = new[] { "android" }, Serial = emulator?.Emulator?.Serial ?? a.Name, Version = a.BasedOn, RuntimeIdentifier = architecture switch { "armeabi-v7a" => "android-arm", "armeabi" => "android-arm", "arm" => "android-arm", "arm64" => "android-arm64", "arm64-v8a" => "android-arm64", "x86" => "android-x86", "x86_64" => "android-x64", _ => "android-arm" } }, emulator == null ? LowPriority : MedPriority));