2 место Автоматизация Android без посредников. Часть 1.

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93

55998


Привет, дорогие зенщики! :az:

Небольшое предисловие.
Обычно я стараюсь писать ботов на запросах, так как это не ресурсозатратно и в целом не сложно, если приложение слабозащищено.
Но бывают приложения, которые достаточно трудоёмко воспроизвести так, чтобы бот не умирал каждую неделю. Поэтому я решил, что некоторые вещи, например, регистраторы и фолловеры стоит делать используя автоматизацию эмуляторов.
В этой статье я поделюсь с вами своими наработками по автоматизации Android эмуляторов. И покажу как всё работает на примере эмулятора Nox и приложения Youtube. :al:

Приступим.
Ранее я автоматизировал приложения через Appium, но меня не устраивали батники, запущенные окна cmd и невысокая гибкость всей системы в целом.
Поэтому я решил сделать автоматизацию напрямую, используя только ADB и UIAutomator. Для этого я использовал библиотеку SharpAdbClient.

Разделим статью на несколько частей для удобства:
  1. Установка и настройка необходимого софта
  2. Принцип работы. Разбор методов. XPath.
  3. Определение адреса (ip:port) эмулятора, организация многопоточного режима и обработка зависаний.

1. Установка и настройка необходимого софта.

Установка UIAutomator для поиска элементов:
  • Скачиваем архив под статьёй и распаковываем.
  • Устанавливаем AndroidSDK. Eсли просит установить Java, то устанавливаем сначала её (jre-8u241-windows-x64.exe).
  • Запускаем SDKManager и устанавливаем необходимые пакеты.
    56231


    56232
  • Прописываем пути до SDK (если их нет) в переменные среды:
    • Заходим в "Систему", через поиск Windows, либо комбинация клавиш Win + Pause/Break.
    • Дополнительные параметры системы
    • Переменные среды
Создаём переменную ANDROID_HOME и прописываем путь до папки с SDK.
56235


В системной переменной Path прописываем пути до папки tools и platform-tools
56236
  • Создаём ярлык для uiautomatorviewer.bat на рабочем столе, сам файл можно найти по пути "android-sdk/tools/uiautomatorviewer.bat", там куда вы установили AndroidSDK.
  • Запускаем uiautomatorviewer.bat для теста. Если появилось окно под названием UI Automator Viewer, значит всё хорошо.

Установка и настройка эмулятора и ZennoPoster:
  • Перемещаем библиотеки (.dll) из ExternalAssemblies в директорию ZennoPoster
  • Скачиваем и устанавливаем Nox.
  • Запускаем MultiDrive и создаём 3 эмулятора для теста (для удобства в настройках можно выставить телефонную ориентацию)
  • Добавляем шаблон в ZennoPoster. Прописываем необходимые пути в настройках (nox_adb.exe и nox.exe в папке bin).
  • Запускаем последовательно 3 эмулятора, затем устанавливаем 3 потока в ZennoPoster, и запускаем для теста. Должна пойти автоматизация в Youtube.

2. Принцип работы. Разбор методов. XPath.

Как получается связать adb с эмулятором без посредника (например Appium)?

У adb есть множество команд для управления Android. Например, команда
cmd.exe:
adb shell input tap x y
позволяет нам тапнуть по указанным координатам.

Соответственно, чтобы тапнуть по нужному элементу, нам надо узнать координаты этого элемента.
На эмуляторе по умолчанию предустановлен UIAutomator, поэтому вы можете получать данные видимых элементов с помощью команды:
cmd.exe:
adb shell uiautomator dump
Но в таком случае XML сохранится в корневой папкe Android, и придется скачивать его на ПК для просмотра - это долго и неудобно, поэтому добавим к команде /dev/tty.
Теперь команда будет выглядеть так:
cmd.exe:
adb shell uiautomator dump /dev/tty
Таким образом, мы выведем содержимое XML файла в лог, в этом случае библиотека SharpAdbClient подцепит ответ и мы сможем извлечь необходимые координаты.
55999

Приведу небольшой список часто используемых команд, которые поддерживает adb:
cmd.exe:
adb help //вывести весь список комманд
adb start-server //запустить adb сервер
adb kill-server //закрыть adb сервер
adb connect <ip:port> //подключиться к устройству
adb devices //показать список подключенных устройств
adb reboot //перезагрузить устройство
adb install <path to .apk> //установить .apk файл
adb shell // Запускать команды через терминал Shell
adb shell input x y //тапнуть по координатам
adb shell input swipe x1 y1 x2 y2 sss //свайпнуть по координатам, где sss - скорость в миллисекундах
adb shell input text <string> //отправить текст
adb shell input keyevent <event_code> //отправить event (полный список event'ов будет ниже)
adb shell pm list packages //показать установленные пакеты
adb shell pm uninstall <com.your.app> //удалить пакет
adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp' //показать название текущей активности
Все остальные команды можно найти в поисковике, достаточно написать "adb commands list".

Теперь перейдем к шаблону.
В GAC уже добавлены необходимые .dll, а в директиве using и общем коде добавлены необходимые пространства имён.
Директивы using и общий код:
using SharpAdbClient;
using System.Net;
using System.Xml;
using System.Windows.Forms;
using System.Diagnostics;
using System.Management;
Команды adb теперь можно пропустить через подключенную библиотеку SharpAdbClient.
В общем коде я написал методы для удобства, обзор которых будет на видео в конце статьи.

Пройдемся по готовым кубикам.
Начнём с проверки запущен ли adb сервер по пути из переменной settings_adb:
56000
C#:
if (!AdbServer.Instance.GetStatus().IsRunning) {
AdbServer server = new AdbServer();
var result = server.StartServer(project.Variables["settings_adb"].Value, restartServerIfNewer: false);

    throw new Exception("Restart.");
}

Подключаемся к ip:port эмулятора. Обычно он автоматически подключается, но подстрахуемся командой:
C#:
AdbClient.Instance.Connect(new DnsEndPoint("127.0.0.1", int.Parse(Regex.Match(project.Variables["device"].Value, "(?<=:).*").ToString())));

Cоздаём объект ADB и сохраняем его в контексте, чтобы использовать далее в проекте:
C#:
ADB a = new ADB(project);
project.Context["ADB"] = a;

Создаём объект PackageManager, который позволит нам Удалять/Устанавливать приложение в этом же сниппете:
C#:
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

Осуществляем запуск приложения:
C#:
var a = project.Context["ADB"];
a.StartApp("com.google.android.youtube/com.google.android.apps.youtube.app.WatchWhileActivity"); //запуск приложения
// в CMD получить наименование текущего окна, которое нужно вставить в этот запрос
// adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'

Ожидаем появление элемента:
C#:
var a = project.Context["ADB"];
a.Wait("//node[@resource-id='' and @class='android.widget.ImageView']", 0, 10); //XPath, Index, Секунды

Тапаем на элемент:
C#:
var a = project.Context["ADB"];
a.Click("//node[@resource-id='com.google.android.youtube:id/menu_search' and @class='android.widget.TextView']", 0, 10); //XPath, Index, Секунды
Обратите внимание, здесь впервые мы используем XPath для поиска объекта.
Учимся составлять свой XPath (это несложно):
Для начала запустим Nox и убедимся, что он подключен к adb.
cmd.exe:
adb devices
Вы должны увидеть своё устройство в списке.
56001
Если подключенных устройств нет, тогда придется подключить эмулятор самостоятельно с помощью команды:
cmd.exe:
adb connect 127.0.0.1:62001
Вы должны получить сообщение о подключении. Обычно порт первого эмулятора 62001, но в моём случае 62025.
56002

Если не получается поймать порт, то пробуйте перебор от 62001 до 62100.
Теперь установим и запустим youtube.apk из архива, а затем запустим uiautomatorviewer.bat и сделаем dump окна.
56003
Вы можете поводить курсором по элементам и заметите, что в правой части окна выделяются соответствующие узлы (node). Соответственно, чтобы составить XPath мы должны выделить нужный нам элемент и взять атрибуты, которые могут идентифицировать элемент в дереве.
Составим XPath для лупы (поиск), взяв атрибуты resource-id и class:
XPath:
//node[@resource-id='com.google.android.youtube:id/menu_search' and @class='android.widget.TextView']

Если случается, что элемент невозможно идентифицировать (не указаны атрибуты), то в таком случае можно составить длинный XPath, например до элемента Home слева от лупы:
XPath:
//node[@resource-id='com.google.android.youtube:id/toolbar' and @class='android.view.View']/node[@class='android.widget.TextView']
Весь синтаксис XPath можно подсмотреть здесь.


Ввод текста и нажатие event'а (Enter):
C#:
var a = project.Context["ADB"];
a.Text("ZennoLab"); //ввод текста
a.KeyEvent("66"); //Enter
0 --> "KEYCODE_UNKNOWN"
1 --> "KEYCODE_MENU"
2 --> "KEYCODE_SOFT_RIGHT"
3 --> "KEYCODE_HOME"
4 --> "KEYCODE_BACK"
5 --> "KEYCODE_CALL"
6 --> "KEYCODE_ENDCALL"
7 --> "KEYCODE_0"
8 --> "KEYCODE_1"
9 --> "KEYCODE_2"
10 --> "KEYCODE_3"
11 --> "KEYCODE_4"
12 --> "KEYCODE_5"
13 --> "KEYCODE_6"
14 --> "KEYCODE_7"
15 --> "KEYCODE_8"
16 --> "KEYCODE_9"
17 --> "KEYCODE_STAR"
18 --> "KEYCODE_POUND"
19 --> "KEYCODE_DPAD_UP"
20 --> "KEYCODE_DPAD_DOWN"
21 --> "KEYCODE_DPAD_LEFT"
22 --> "KEYCODE_DPAD_RIGHT"
23 --> "KEYCODE_DPAD_CENTER"
24 --> "KEYCODE_VOLUME_UP"
25 --> "KEYCODE_VOLUME_DOWN"
26 --> "KEYCODE_POWER"
27 --> "KEYCODE_CAMERA"
28 --> "KEYCODE_CLEAR"
29 --> "KEYCODE_A"
30 --> "KEYCODE_B"
31 --> "KEYCODE_C"
32 --> "KEYCODE_D"
33 --> "KEYCODE_E"
34 --> "KEYCODE_F"
35 --> "KEYCODE_G"
36 --> "KEYCODE_H"
37 --> "KEYCODE_I"
38 --> "KEYCODE_J"
39 --> "KEYCODE_K"
40 --> "KEYCODE_L"
41 --> "KEYCODE_M"
42 --> "KEYCODE_N"
43 --> "KEYCODE_O"
44 --> "KEYCODE_P"
45 --> "KEYCODE_Q"
46 --> "KEYCODE_R"
47 --> "KEYCODE_S"
48 --> "KEYCODE_T"
49 --> "KEYCODE_U"
50 --> "KEYCODE_V"
51 --> "KEYCODE_W"
52 --> "KEYCODE_X"
53 --> "KEYCODE_Y"
54 --> "KEYCODE_Z"
55 --> "KEYCODE_COMMA"
56 --> "KEYCODE_PERIOD"
57 --> "KEYCODE_ALT_LEFT"
58 --> "KEYCODE_ALT_RIGHT"
59 --> "KEYCODE_SHIFT_LEFT"
60 --> "KEYCODE_SHIFT_RIGHT"
61 --> "KEYCODE_TAB"
62 --> "KEYCODE_SPACE"
63 --> "KEYCODE_SYM"
64 --> "KEYCODE_EXPLORER"
65 --> "KEYCODE_ENVELOPE"
66 --> "KEYCODE_ENTER"
67 --> "KEYCODE_DEL"
68 --> "KEYCODE_GRAVE"
69 --> "KEYCODE_MINUS"
70 --> "KEYCODE_EQUALS"
71 --> "KEYCODE_LEFT_BRACKET"
72 --> "KEYCODE_RIGHT_BRACKET"
73 --> "KEYCODE_BACKSLASH"
74 --> "KEYCODE_SEMICOLON"
75 --> "KEYCODE_APOSTROPHE"
76 --> "KEYCODE_SLASH"
77 --> "KEYCODE_AT"
78 --> "KEYCODE_NUM"
79 --> "KEYCODE_HEADSETHOOK"
80 --> "KEYCODE_FOCUS"
81 --> "KEYCODE_PLUS"
82 --> "KEYCODE_MENU"
83 --> "KEYCODE_NOTIFICATION"
84 --> "KEYCODE_SEARCH"
85 --> "TAG_LAST_KEYCODE"

Так же случаются ситуации, когда вам нужно сделать двойной тап или другие действия, которых нет в списке.
На помощь приходит команда sendevent:
cmd.exe:
adb shell sendevent /dev/input/event<x>

Получаем координаты элемента, с помощью метода получения координат.
Вы можете получать "чистые" координаты, либо уже высчитанную рандомную точку. В нашем случае используем сразу второй вариант:
C#:
var a = project.Context["ADB"];
string coord = a.GetCoord("//node[@resource-id='com.google.android.youtube:id/channel_avatar' and @class='android.widget.ImageView']", 0, 10, true); //XPath, Index, Секунды, рандомная точка между x1,y1 и x2,y2
string[] coords = coord.Split(new char[] {','});
project.Variables["x"].Value = coords[0];
project.Variables["y"].Value = coords[1];

Введем команду в cmd, кликнем на эмуляторе и запишем событие:
cmd.exe:
adb shell getevent
Вы получите значения в HEX, преобразуем их в DEC с помощью любого сервиса.
Получится:
Код:
/dev/input/event<N>: 1 330 1
/dev/input/event<N>: 3 58 1
/dev/input/event<N>: 3 53 <x>
/dev/input/event<N>: 3 54 <y>
/dev/input/event<N>: 0 2 0
/dev/input/event<N>: 0 0 0
/dev/input/event<N>: 0 2 0
/dev/input/event<N>: 0 0 0
/dev/input/event<N>: 1 330 0
/dev/input/event<N>: 3 58 0
/dev/input/event<N>: 3 53 0
/dev/input/event<N>: 3 54 38
/dev/input/event<N>: 0 2 0
/dev/input/event<N>: 0 0 0
Получаем номер event'a с помощью команды:
C#:
var a = project.Context["ADB"];
a.Command("cat /proc/bus/input/devices", true);
project.Variables["event"].Value = Regex.Match(project.Variables["receiver"].Value, "(?<=mouse2 event).*").ToString().Trim(); //получение № ивэнта

Тапаем с помощью sendevent, подставив номер event'а и координаты (в нашем случае двойной тап не нужен, поэтому я закомментил вторую часть в шаблоне):
C#:
var a = project.Context["ADB"];
string evnt = project.Variables["event"].Value;
string x = project.Variables["x"].Value;
string y = project.Variables["y"].Value;
a.Command(String.Format("sendevent /dev/input/event{0} 1 330 1", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 3 58 1", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 3 53 {1}", evnt, x), false);
a.Command(String.Format("sendevent /dev/input/event{0} 3 54 {1}", evnt, y), false);
a.Command(String.Format("sendevent /dev/input/event{0} 0 2 0", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 0 0 0", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 0 2 0", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 0 0 0", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 1 330 0", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 3 58 0", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 3 53 0", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 3 54 38", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 0 2 0", evnt), false);
a.Command(String.Format("sendevent /dev/input/event{0} 0 0 0", evnt), false);

Свайпаем:
C#:
var a = project.Context["ADB"];
    a.Swipe("200", "600", "200", "200", "900"); //координаты x1, y1, x2, y2, sss - скорость в милисекундах

Также можно спарсить что-нибудь. Спарсим длительность видимых роликов (результат появится в списке шаблона):
C#:
var a = project.Context["ADB"];
project.Lists["parse"].AddRange(a.Parse("//node[@resource-id='com.google.android.youtube:id/duration' and @class='android.widget.TextView']", "text", 0, 5)); //XPath, какой аттрибут парсить, Index, Секунды

Button Back:
C#:
var a = project.Context["ADB"];
a.Back();

Button Home и Kill Process:
C#:
var a = project.Context["ADB"];
a.Home(); //Свернуть все окна
a.Kill("com.google.android.youtube"); //Убить процесс

Перезагрузить Android:
C#:
var a = project.Context["ADB"];
a.Reboot();

Загрузка файла. Я написал 2 метода для загрузки файла: обычная загрузка
C#:
var a = project.Context["ADB"];
a.UploadFile("/storage/sdcard0/ZennoLab.txt", project.Directory + @"\ZennoLab.txt");
и из переменной.
C#:
var a = project.Context["ADB"];
a.UploadFromVar("/storage/sdcard0/ZennoLab.txt", "ZennoLab TEST");

Скачивание файла:
C#:
var a = project.Context["ADB"];
a.DownloadFile("/storage/sdcard0/ZennoLab.txt", project.Directory + @"\Download_test.txt");

Удаление Файла:
C#:
var a = project.Context["ADB"];
a.Command("rm -rf /storage/sdcard0/ZennoLab.txt", false);

3. Определение IP+PORT эмулятора, организация многопоточного режима и обработка зависаний.

Для организации многопоточного режима я решил использовать залоченную глобальную переменную, в которой будут записаны id процессов (pid) окон эмуляторов через ";".
Когда шаблон запускается, то в глобальную переменную записывается pid первого по списку свободного эмулятора. Если в переменной не было этого pid, то другой поток не будет работать с этим pid. :bf:
Сам pid можно найти в Диспетчере задач (Ctrl+Shift+Esc).
56004

Далее если ввести в cmd команду:
cmd.exe:
netstat -a -n -o
то высветится множество адресов, а в самой правой колонке мы увидем pid.
56005

Зная, что порты для подключение adb у Nox начинаются с 620, мы можем взять адрес по pid'у с помощью команды:
cmd.exe:
netstat -a -n -o | find "PID" | find "127.0.0.1" | find "620"
вместо PID подставив id процесса (pid).

Теперь сделаем тоже самое в зенке.
Инициализируем/проверяем существование глобальной переменной:
C#:
lock(SyncObject) {
    try {
        var gbVar = project.GlobalVariables["Zappium", "process"];
        return null;
    } catch (KeyNotFoundException ex) {
        string defaultValue = String.Empty;
        project.GlobalVariables.SetVariable("Zappium", "process", defaultValue);
    }
}

Получаем свободный PID с помощью стандартного инструментария .Net:
C#:
lock(SyncObject) {
var gbVar = project.GlobalVariables["Zappium", "process"];
Process[] processes = Process.GetProcessesByName("NoxVMHandle");
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 + ";";
        }
}
}

Получаем адрес устройства, подставив pid в ранее написанную команду:
C#:
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}\" | find \"127.0.0.1\" | find \"620\"",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:)62.*?(?= )");

По завершению работы шаблона удаляем из глобальной переменной pid, чтобы освободить окно для следующих потоков:
C#:
lock(SyncObject) {
    var gbVar = project.GlobalVariables["Zappium", "process"];
    gbVar.Value = gbVar.Value.ToString().Replace(project.Variables["process"].Value + ";", "");
}
(В этом способе есть один минус. Если вы прерываете работу шаблона вручную, то pid не удаляется. Буду рад вашим идеям решения этой проблемы в комментариях.)

Порой случается, что эмулятор зависает, для этого я использую метод CommandLineUtilities, прописанный в общем коде, чтобы записать все процессы связанные с эмулятором, закрыть и открыть их заново.
Закрываем процессы:
C#:
Process[] processes = Process.GetProcessesByName("Nox");
var ids = processes.Select(p => p.Id);
var process = Process.GetProcessById(int.Parse(project.Variables["process"].Value));

string name = Regex.Match(CommandLineUtilities.getCommandLines(process), "(?<=--comment ).*(?= --startvm)").ToString();
project.SendInfoToLog(CommandLineUtilities.getCommandLines(process));

foreach(int processId in ids){
    var nox = Process.GetProcessById(processId);
    if (Regex.Match(CommandLineUtilities.getCommandLines(nox),"(?<=-clone:).*").ToString().Contains(name)){
        project.Variables["start_cmd"].Value = CommandLineUtilities.getCommandLines(nox);
    nox.Kill();
        break;
    }
}
process.Kill();

Открываем эмулятор заново:
C#:
var proc = System.Diagnostics.Process.Start(project.Variables["settings_nox"].Value, Regex.Match(project.Variables["start_cmd"].Value, "-clone:.*").ToString());



Заключение.
Надеюсь моя статья облегчит вам работу с эмуляторами и поможет создать более совершенную схему взаимодействия с ними. Это лишь небольшая часть того, как можно взаимодействовать с эмуляторами.
Каждый ваш голос за статью будет мотивировать меня делиться многими полезными фишками в следующих частях.
Спасибо за внимание, друзья! :bt:
 
Тема статьи
Нестандартные хаки
Номер конкурса статей
Тринадцатый конкурс статей

Вложения

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.

Последнее редактирование:

molotok

Client
Регистрация
17.04.2015
Сообщения
733
Благодарностей
358
Баллы
63
Следующие части в следующих конкурсах?
Спасибо за статью!
 
  • Спасибо
Реакции: WLDN

radv

Client
Регистрация
11.05.2015
Сообщения
3 821
Благодарностей
2 030
Баллы
113
Статья огонь!!! А как реализована работа через прокси для каждого эмулятора?
 
  • Спасибо
Реакции: WLDN

606

Client
Регистрация
07.03.2019
Сообщения
20
Благодарностей
3
Баллы
3
отличный старт)
 
  • Спасибо
Реакции: WLDN

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93
Статья огонь!!! А как реализована работа через прокси для каждого эмулятора?
Спасибо :-) В этой части пока что рассказываю про базовую автоматизацию, в след частях буду делиться своими решениями по прокси и другим полезным вещам.
 

SHILY

Client
Регистрация
05.06.2016
Сообщения
258
Благодарностей
307
Баллы
63
Шикарно! Мой голос, явно, за тебя!:-)
 
  • Спасибо
Реакции: WLDN

TazMan

Client
Регистрация
05.01.2017
Сообщения
236
Благодарностей
37
Баллы
28

radv

Client
Регистрация
11.05.2015
Сообщения
3 821
Благодарностей
2 030
Баллы
113
в след частях буду делиться своими решениями по прокси и другим полезным вещам.
будешь след. конкурс статей ждать? Это же полгода примерно. с учетом того, что конкурсы примерно раз в квартал проходят, и след. конкурс будет про шаблоны. К тому времени информация может немного устареть, используемая библиотека обновиться. А без прокси у каждого эмулятора будет один айпишник, что не есть гуд.
 
  • Спасибо
Реакции: WLDN

che100

Client
Регистрация
18.04.2017
Сообщения
808
Благодарностей
503
Баллы
93
Статья огонь!!! А как реализована работа через прокси для каждого эмулятора?
Можно через Proxy Droid.
Работа через эмулятор это здорово, но 2 момента смущают сходу, приложение может определить что оно запускается на эмуляторе и то что версии андроида такие древние, что в реальной жизни на таких никто не сидит.
 
  • Спасибо
Реакции: vertigo141

radv

Client
Регистрация
11.05.2015
Сообщения
3 821
Благодарностей
2 030
Баллы
113

nectah

Client
Регистрация
17.09.2010
Сообщения
95
Благодарностей
18
Баллы
8
Статья огонь :az: думаю лучше в этом конкурсе уже ничего не будет...заранее
 
  • Спасибо
Реакции: WLDN

Saavdav

Client
Регистрация
23.09.2019
Сообщения
50
Благодарностей
5
Баллы
8
Интересно, но для пользователя с хорошим опытом в програмировании. К сожалению тяжело усвоилось... Будем изучать) Спасибо за хорошую статью! Успехов
 
  • Спасибо
Реакции: WLDN

radv

Client
Регистрация
11.05.2015
Сообщения
3 821
Благодарностей
2 030
Баллы
113

nectah

Client
Регистрация
17.09.2010
Сообщения
95
Благодарностей
18
Баллы
8
предлагаешь расходится и не ждать остальных авторов? :ap:
я по андроиду только и ждал :ap: но лучшая статья там где дают пищу для размышлений, а не просто схему)
 
  • Спасибо
Реакции: WLDN

Nike59

Client
Регистрация
05.08.2011
Сообщения
120
Благодарностей
121
Баллы
43
Очень хорошее начало конкурса. Статья порадовала. Спасибо за подгон библиотеки для работы c# с adb. Почему-то думал, что достойной альтернативы appium нет. Все-таки appium - костыль. А тут напрямую идет работа с adb.
 
  • Спасибо
Реакции: WLDN

Dexio

Client
Регистрация
09.05.2014
Сообщения
1 251
Благодарностей
219
Баллы
63
Спасибо за шикарные сниппеты!
 
  • Спасибо
Реакции: WLDN

sergio197675

Client
Регистрация
21.09.2019
Сообщения
360
Благодарностей
318
Баллы
63
Благодарю автора! давно искал методы избавиться от cmd и аппиума)- в программировании я 0, все на кубиках))
Интересна была бы реализация и стабильность работы с физическими устройствами... у меня " ферма "-10 андроидов, но непериодические отвалы по юсб и зависания демонов adb) , те сырой шаблон "плугэндплей", прокси, смена ип..ссори пишу за рулём с телефона)
просьба добавить примеров с реальными устройствами!
Мой голос за вас , удачи!
 
Последнее редактирование:

seregakot

Client
Регистрация
19.03.2016
Сообщения
126
Благодарностей
63
Баллы
28
Спасибо большое за очень интересный и познавательный материал.
Тоже думал как избавиться от аппиума и ошибок.
 
  • Спасибо
Реакции: WLDN

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93
будешь след. конкурс статей ждать? Это же полгода примерно. с учетом того, что конкурсы примерно раз в квартал проходят, и след. конкурс будет про шаблоны. К тому времени информация может немного устареть, используемая библиотека обновиться. А без прокси у каждого эмулятора будет один айпишник, что не есть гуд.
Согласен с тобой, что информация имеет свойство устаревать. К сожалению, времени, возможностей и желания хватило пока раскрыть эту сторону вопроса. :( Моё решение по прокси нужно хорошо обдумать, скомпоновать и потом уже выкладывать. Если к тому времени появится чьё-то решение, то я либо опущу этот вопрос, либо дополню его своим решением.

Вообще вижу, что ты тоже занимаешься автоматизацией Android, был бы рад, если бы ты смог поделиться в комментариях своим решением.
 
  • Спасибо
Реакции: FAQBILL и radv

radv

Client
Регистрация
11.05.2015
Сообщения
3 821
Благодарностей
2 030
Баллы
113
Вообще вижу, что ты тоже занимаешься автоматизацией Android, был бы рад, если бы ты смог поделиться в комментариях своим решением.
Насчет прокси пока тестирую разные варианты.
 
  • Спасибо
Реакции: WLDN

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93
вчера только мучался / https://t.me/zennolabchat/222939 и ждал что бы хоть кто то ответил / как найти элементы под таким слоем? https://prnt.sc/sidh4y
Привет, если uiautomator его не отображает, то нужно редактировать .jar. У меня были подобные небольшие проблемы, и я решил, что лучшим решением будет подредачить uiautomator.jar, либо заменить его на что-то более совершенное.
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 821
Благодарностей
2 030
Баллы
113
Все-таки appium - костыль. А тут напрямую идет работа с adb.
В аппиуме идет работа с самими элементами. Я бы не сказал что это костыль, там можно и проверку наличия элементов делать и много всего. Конечно это может влиять на скорость работы, но зато повышает стабильность. В моем конструкторе есть работа и через адб и через аппиум без всяких дополнительных окон консоли и батников. Сейчас можно проверить и работу через описанную библиотеку и сравнить со своими методами работы с эмулятором.
 
  • Спасибо
Реакции: Nike59

limarkximus

Client
Регистрация
01.08.2019
Сообщения
115
Благодарностей
73
Баллы
28
ну во! таких бы статей поболее.. а не то как спамить дейт)
 
  • Спасибо
Реакции: 606 и WLDN

TazMan

Client
Регистрация
05.01.2017
Сообщения
236
Благодарностей
37
Баллы
28
Привет, если uiautomator его не отображает, то нужно редактировать .jar. У меня были подобные небольшие проблемы, и я решил, что лучшим решением будет подредачить uiautomator.jar, либо заменить его на что-то более совершенное.
не проще ли тогда будет отловить запросы на fiddler и сделать post-get? пересобирать apk как то не с руки :-) хотя как вариант наверное прокатит
 

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93
не проще ли тогда будет отловить запросы на fiddler и сделать post-get? пересобирать apk как то не с руки :-) хотя как вариант наверное прокатит
Если защита слабенькая, то конечно проще будет использовать этот вариант.
 

Nats1

Client
Регистрация
15.04.2015
Сообщения
198
Благодарностей
194
Баллы
43
Ждем рекапчи, фанкапчи и другие "закрутки" в мобильных прилах :D . Но статья хорошая.
 
  • Спасибо
Реакции: 606 и WLDN

mrboogie

Client
Регистрация
28.05.2019
Сообщения
40
Благодарностей
18
Баллы
8
Спасибо :-) В этой части пока что рассказываю про базовую автоматизацию, в след частях буду делиться своими решениями по прокси и другим полезным вещам.
Почему используешь UI Automator а не Appium?
 

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93
  • Спасибо
Реакции: mrboogie

radv

Client
Регистрация
11.05.2015
Сообщения
3 821
Благодарностей
2 030
Баллы
113
Кстати, стоит разделять Appium как софт и как dll. Так вот Appium(Софт) т.е. обертка-интерфейс над dll может помогать исследовать элементы вместо использования UI Automator, а вот если использовать саму dll с аппиумом, то можно все действия делать через C# код.
 
Регистрация
23.03.2015
Сообщения
1 222
Благодарностей
764
Баллы
113
Спасибо за статью, Очень полезная информация! Но зачем ты сходу с козырей херачит? Таким скромным автором как я, даже неловко публиковаться(
Шучу
 
  • Спасибо
Реакции: WLDN и 606

Кто просматривает тему: (Всего: 4, Пользователи: 0, Гости: 4)