Автоматизация Андроид Приложений
Шаблон со статьи: https://zennolab.com/discussion/threads/avtomatizacija-android-bez-posrednikov-chast-1.79012/
https://disk.yandex.ru/d/w1pxVQ2kC25MJw
Содержимое файла консультации:
adb
https://zennolab.com/discussion/threads/avtomatizacija-android-bez-posrednikov-chast-1.79012/
adbkeyboard https://github.com/senzhk/ADBKeyBoard (установить её по умолчанию)
Любой функционаи дополняется умением работать с adb.
2.Эмуляторы
Если работать на сервере, то необходима видеокарта + виртуализация.
Memu
https://www.memuplay.com/blog/how-to-manipulate-memu-thru-command-line.html
После установки эмулятори (или обновления) необходимо зайти в папку с эмулятором и заменить adb файлы эмулятора на adb с built tools.
Обращение к нужному экземпляру эмулятори
adb -s 127.0.0.1:21513 КОМАНДА
a.Wait("//node[@resource-id='com.cyanogenmod.filemanager:id/navigation_view_item_name' and @text='storage']", 0, 10); //XPath, Index, Секунды
3.Анонимность
Для телефонов
Xposed + модули. Device faker, Device Emulator pro
https://4pda.ru/forum/index.php?showtopic=425052
Для эмуляторов лучше создать новый эмулятор.
4.Прокси как установить.
В самом android приложении:
-Proxydroid (не проксирует DNS)
-Drony
-В разделе "полезное" (ниже) через сниппет
5. Курсы
https://cloud.mail.ru/public/4jXc/51RHwKWra/
1. Cтавим прокси через Drony (через вкладку "вай-фай", а не через "остальные сети")
а) Через АРК устанавливаем .арk файл клавиатуры
Или устанавливаем .apk с помощью сниппета:
var a = project.Context["ADB"]; var device = a.Device();
SharpAdbClient.DeviceCommands.PackageManager manager = new SharpAdbClient.DeviceCommands.PackageManager(device); try { manager.UninstallPackage("com.google.android.youtube"); //удаление пакета } catch (Exception e) {} manager.InstallPackage(project.Directory + @"\youtube.apk", reinstall: false); //установка apk
После установки, нажать на рабочем столе на иконку чтобы установилось
Далее через консоль cmd установить ADBkeyboard клавиатуру по умолчанию
adb shell ime set com.android.adbkeyboard/.AdbIME
После проверить клавиатуру на работоспособность через консоль командой
adb shell am broadcast -a ADB_INPUT_TEXT --es msg 'Привет?'
И уже в самом PM проверить чтобы в using была команда
И сам сниппет для ввода текста через РМ:
var sn = project.Variables["threads_tel_sn"].Value; //тут серийник устройства для многопотока вида 127.0.0.1:21503 ProcessStartInfo startInfo1 = new ProcessStartInfo(); startInfo1.FileName = "adb.exe"; startInfo1.Arguments = "-s "+sn+" shell am broadcast -a ADB_INPUT_TEXT --es msg 'Привет'"; startInfo1.WindowStyle = ProcessWindowStyle.Hidden; Process.Start(startInfo1).WaitForExit();
- Меняю язык системы на английский чтобы проще было находить элементы. (за элементы на русском путь по xpath не работает).
- Устанавливаю галерею.
Чтобы узнать путь, куда загружать фотки чтобы они были в галерее:
И затем по этому пути заливаем папку с изображениями.
Полезное:
lock(SyncObject) { var gbVar = project.GlobalVariables["Zappium", "process"]; Process[] processes = Process.GetProcessesByName("MEmuHeadless"); var ids = processes.Select(p => p.Id); string process = ""; foreach(int processId in ids){ //project.SendInfoToLog(processId.ToString()); process = processId.ToString(); if (project.Variables["process"].Value == String.Empty && !project.GlobalVariables["Zappium", "process"].Value.ToString().Contains(process)){ project.Variables["process"].Value = process; gbVar.Value = gbVar.Value + process + ";"; return process; } } throw new Exception("Нет свободных эмуляторов"); }
Process cmd = new Process(); cmd.StartInfo.FileName = "cmd.exe"; cmd.StartInfo.RedirectStandardInput = true; cmd.StartInfo.RedirectStandardOutput = true; cmd.StartInfo.CreateNoWindow = true; cmd.StartInfo.UseShellExecute = false; cmd.Start(); cmd.StandardInput.WriteLine(String.Format("netstat -a -n -o | find \"{0}\" | findstr \"21.*3\"",project.Variables["process"].Value)); cmd.StandardInput.Flush(); cmd.StandardInput.Close(); cmd.WaitForExit(); return "127.0.0.1:" + Regex.Match(cmd.StandardOutput.ReadToEnd(), "(?<=127.0.0.1:)21.*3(?= )");
Сниппеты:
ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = @"adb"; startInfo.Arguments = @"shell am start -a android.intent.action.VIEW -d http://zennolab.com"; startInfo.WindowStyle = ProcessWindowStyle.Hidden; Process.Start(startInfo).WaitForExit();
var sn = project.Variables["threads_tel_sn"].Value;//тут серийник устройства для многопотока вида 127.0.0.1:21503 ProcessStartInfo startInfo1 = new ProcessStartInfo(); startInfo1.FileName = "adb.exe"; startInfo1.Arguments = "-s "+sn+" shell am broadcast -a ADB_INPUT_TEXT --es msg 'Привет'"; startInfo1.WindowStyle = ProcessWindowStyle.Hidden; Process.Start(startInfo1).WaitForExit();
Поставить прокси конкретному потоку:
a.Command("settings put global http_proxy 354.574.57.90:8080", false);
Process p = new Process(); p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = "adb.exe"; p.StartInfo.Arguments = @"-s "+sn+" shell dumpsys battery | grep 'level'"; p.StartInfo.CreateNoWindow = true; p.Start(); string output = p.StandardOutput.ReadToEnd(); p.WaitForExit(); project.Variables["battery_level"].Value = output.Trim();
Сниппет для ввода команд Memu с получением ответа от команд
System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo.CreateNoWindow = true; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(866); p.StartInfo.FileName = @"D:\Program Files\Microvirt\MEmu\memuc.exe"; // путь к батнику или exe p.StartInfo.Arguments = @" listvms running"; // его параметры p.Start(); string output = p.StandardOutput.ReadToEnd(); p.WaitForExit(); // ожидание завершения процесса return output;
System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo.CreateNoWindow = true; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(866); p.StartInfo.FileName = @"D:\Program Files\Microvirt\MEmu\memuc.exe"; // путь к батнику или exe p.StartInfo.Arguments = @" reboot -i 0"; // его параметры p.Start(); string output = p.StandardOutput.ReadToEnd(); p.WaitForExit(); // ожидание завершения процесса return output;
//ПЕРЕМЕЩАЕМ КАРТИНКУ В ГАЛЕРЕЮ string pat_ishodniy = @"C:\Users\User\Desktop\AAA\iHappy_img"; var List = project.Lists["Файлы"]; string supportedExtensions = "*.jpg,*.gif,*.png,*.bmp,*.jpe,*.jpeg,*.wmf,*.emf,*.xbm,*.ico,*.eps,*.tif,*.tiff,*.g01,*.g02,*.g03,*.g04,*.g05,*.g06,*.g07,*.g08"; foreach (string imageFile in Directory.GetFiles(pat_ishodniy, "*.*", SearchOption.AllDirectories).Where(s => supportedExtensions.Contains(Path.GetExtension(s).ToLower()))) { List.Add(imageFile); } string pathFile = List[0].Trim(); string newNameFile = Regex.Match(pathFile, "(?<=iHappy_img\\\\).*(?=\\.jpg)").Value; string pathNewDirectory = @"C:\Users\User\Pictures\MEmu Photo\photos55\"; // новая директория для файла. //string newNameFile = "Мой перемещенный файл"; var fileInfo = new FileInfo(pathFile); var directoryInfo = new DirectoryInfo(pathNewDirectory); string newPathFile = Path.Combine(directoryInfo.FullName, newNameFile + fileInfo.Extension); try { if (!fileInfo.Exists) throw new Exception(quot;Файла не существует: {fileInfo.FullName}"); // проверяем файл на существование. if (!directoryInfo.Exists) Directory.CreateDirectory(directoryInfo.FullName); // проверяем директорию на существование, если её нет - создаем. File.Move(fileInfo.FullName, newPathFile); // перемещаем файл. project.SendInfoToLog(quot;Новый путь файла: {newPathFile}"); } catch(Exception ex) { project.SendWarningToLog(ex.Message); // вывод ошибки в лог. }