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

WLDN

Client
Joined
Jul 9, 2015
Messages
358
Reaction score
571
Points
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 с помощью любого сервиса.
Получится:
Code:
/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:
 
Тема статьи
Нестандартные хаки
Номер конкурса статей
Тринадцатый конкурс статей

Attachments

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

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

Last edited:

molotok

Client
Joined
Apr 17, 2015
Messages
748
Reaction score
373
Points
63
Следующие части в следующих конкурсах?
Спасибо за статью!
 
  • Thank you
Reactions: WLDN

radv

Client
Joined
May 11, 2015
Messages
3,875
Reaction score
2,109
Points
113
Статья огонь!!! А как реализована работа через прокси для каждого эмулятора?
 
  • Thank you
Reactions: WLDN

606

Client
Joined
Mar 7, 2019
Messages
20
Reaction score
3
Points
3
отличный старт)
 
  • Thank you
Reactions: WLDN

WLDN

Client
Joined
Jul 9, 2015
Messages
358
Reaction score
571
Points
93
Статья огонь!!! А как реализована работа через прокси для каждого эмулятора?
Спасибо :-) В этой части пока что рассказываю про базовую автоматизацию, в след частях буду делиться своими решениями по прокси и другим полезным вещам.
 

SHILY

Client
Joined
Jun 5, 2016
Messages
258
Reaction score
309
Points
63
Шикарно! Мой голос, явно, за тебя!:-)
 
  • Thank you
Reactions: WLDN

TazMan

Client
Joined
Jan 5, 2017
Messages
237
Reaction score
38
Points
28

radv

Client
Joined
May 11, 2015
Messages
3,875
Reaction score
2,109
Points
113
в след частях буду делиться своими решениями по прокси и другим полезным вещам.
будешь след. конкурс статей ждать? Это же полгода примерно. с учетом того, что конкурсы примерно раз в квартал проходят, и след. конкурс будет про шаблоны. К тому времени информация может немного устареть, используемая библиотека обновиться. А без прокси у каждого эмулятора будет один айпишник, что не есть гуд.
 
  • Thank you
Reactions: WLDN

che100

Client
Joined
Apr 18, 2017
Messages
808
Reaction score
507
Points
93
Статья огонь!!! А как реализована работа через прокси для каждого эмулятора?
Можно через Proxy Droid.
Работа через эмулятор это здорово, но 2 момента смущают сходу, приложение может определить что оно запускается на эмуляторе и то что версии андроида такие древние, что в реальной жизни на таких никто не сидит.
 
  • Thank you
Reactions: vertigo141

radv

Client
Joined
May 11, 2015
Messages
3,875
Reaction score
2,109
Points
113
Можно через Proxy Droid.
Как вариант да, но он не всегда стабильно работает. С одним эмулятором можно и через проксифаер работать.
 

nectah

Client
Joined
Sep 17, 2010
Messages
97
Reaction score
18
Points
8
Статья огонь :az: думаю лучше в этом конкурсе уже ничего не будет...заранее
 
  • Thank you
Reactions: WLDN

Saavdav

Client
Joined
Sep 23, 2019
Messages
50
Reaction score
5
Points
8
Интересно, но для пользователя с хорошим опытом в програмировании. К сожалению тяжело усвоилось... Будем изучать) Спасибо за хорошую статью! Успехов
 
  • Thank you
Reactions: WLDN

radv

Client
Joined
May 11, 2015
Messages
3,875
Reaction score
2,109
Points
113
думаю лучше в этом конкурсе уже ничего не будет
предлагаешь расходится и не ждать остальных авторов? :ap:
 

nectah

Client
Joined
Sep 17, 2010
Messages
97
Reaction score
18
Points
8
предлагаешь расходится и не ждать остальных авторов? :ap:
я по андроиду только и ждал :ap: но лучшая статья там где дают пищу для размышлений, а не просто схему)
 
  • Thank you
Reactions: WLDN

Nike59

Client
Joined
Aug 5, 2011
Messages
120
Reaction score
121
Points
43
Очень хорошее начало конкурса. Статья порадовала. Спасибо за подгон библиотеки для работы c# с adb. Почему-то думал, что достойной альтернативы appium нет. Все-таки appium - костыль. А тут напрямую идет работа с adb.
 
  • Thank you
Reactions: WLDN

Dexio

Client
Joined
May 9, 2014
Messages
1,251
Reaction score
219
Points
63
Спасибо за шикарные сниппеты!
 
  • Thank you
Reactions: WLDN

sergio197675

Client
Joined
Sep 21, 2019
Messages
360
Reaction score
320
Points
63
Благодарю автора! давно искал методы избавиться от cmd и аппиума)- в программировании я 0, все на кубиках))
Интересна была бы реализация и стабильность работы с физическими устройствами... у меня " ферма "-10 андроидов, но непериодические отвалы по юсб и зависания демонов adb) , те сырой шаблон "плугэндплей", прокси, смена ип..ссори пишу за рулём с телефона)
просьба добавить примеров с реальными устройствами!
Мой голос за вас , удачи!
 
Last edited:

seregakot

Client
Joined
Mar 19, 2016
Messages
126
Reaction score
63
Points
28
Спасибо большое за очень интересный и познавательный материал.
Тоже думал как избавиться от аппиума и ошибок.
 
  • Thank you
Reactions: WLDN

WLDN

Client
Joined
Jul 9, 2015
Messages
358
Reaction score
571
Points
93
будешь след. конкурс статей ждать? Это же полгода примерно. с учетом того, что конкурсы примерно раз в квартал проходят, и след. конкурс будет про шаблоны. К тому времени информация может немного устареть, используемая библиотека обновиться. А без прокси у каждого эмулятора будет один айпишник, что не есть гуд.
Согласен с тобой, что информация имеет свойство устаревать. К сожалению, времени, возможностей и желания хватило пока раскрыть эту сторону вопроса. :( Моё решение по прокси нужно хорошо обдумать, скомпоновать и потом уже выкладывать. Если к тому времени появится чьё-то решение, то я либо опущу этот вопрос, либо дополню его своим решением.

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

radv

Client
Joined
May 11, 2015
Messages
3,875
Reaction score
2,109
Points
113
Вообще вижу, что ты тоже занимаешься автоматизацией Android, был бы рад, если бы ты смог поделиться в комментариях своим решением.
Насчет прокси пока тестирую разные варианты.
 
  • Thank you
Reactions: WLDN

WLDN

Client
Joined
Jul 9, 2015
Messages
358
Reaction score
571
Points
93
вчера только мучался / https://t.me/zennolabchat/222939 и ждал что бы хоть кто то ответил / как найти элементы под таким слоем? https://prnt.sc/sidh4y
Привет, если uiautomator его не отображает, то нужно редактировать .jar. У меня были подобные небольшие проблемы, и я решил, что лучшим решением будет подредачить uiautomator.jar, либо заменить его на что-то более совершенное.
 

radv

Client
Joined
May 11, 2015
Messages
3,875
Reaction score
2,109
Points
113
Все-таки appium - костыль. А тут напрямую идет работа с adb.
В аппиуме идет работа с самими элементами. Я бы не сказал что это костыль, там можно и проверку наличия элементов делать и много всего. Конечно это может влиять на скорость работы, но зато повышает стабильность. В моем конструкторе есть работа и через адб и через аппиум без всяких дополнительных окон консоли и батников. Сейчас можно проверить и работу через описанную библиотеку и сравнить со своими методами работы с эмулятором.
 
  • Thank you
Reactions: Nike59

limarkximus

Client
Joined
Aug 1, 2019
Messages
115
Reaction score
74
Points
28
ну во! таких бы статей поболее.. а не то как спамить дейт)
 
  • Thank you
Reactions: 606 and WLDN

TazMan

Client
Joined
Jan 5, 2017
Messages
237
Reaction score
38
Points
28
Привет, если uiautomator его не отображает, то нужно редактировать .jar. У меня были подобные небольшие проблемы, и я решил, что лучшим решением будет подредачить uiautomator.jar, либо заменить его на что-то более совершенное.
не проще ли тогда будет отловить запросы на fiddler и сделать post-get? пересобирать apk как то не с руки :-) хотя как вариант наверное прокатит
 

WLDN

Client
Joined
Jul 9, 2015
Messages
358
Reaction score
571
Points
93
не проще ли тогда будет отловить запросы на fiddler и сделать post-get? пересобирать apk как то не с руки :-) хотя как вариант наверное прокатит
Если защита слабенькая, то конечно проще будет использовать этот вариант.
 

Nats1

Client
Joined
Apr 15, 2015
Messages
198
Reaction score
194
Points
43
Ждем рекапчи, фанкапчи и другие "закрутки" в мобильных прилах :D . Но статья хорошая.
 
  • Thank you
Reactions: 606 and WLDN

mrboogie

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

WLDN

Client
Joined
Jul 9, 2015
Messages
358
Reaction score
571
Points
93
Почему используешь UI Automator а не Appium?
Привет. О решении не использовать Appium написал в начале статьи. :-)
 
  • Thank you
Reactions: mrboogie

radv

Client
Joined
May 11, 2015
Messages
3,875
Reaction score
2,109
Points
113
Кстати, стоит разделять Appium как софт и как dll. Так вот Appium(Софт) т.е. обертка-интерфейс над dll может помогать исследовать элементы вместо использования UI Automator, а вот если использовать саму dll с аппиумом, то можно все действия делать через C# код.
 
Joined
Mar 23, 2015
Messages
1,295
Reaction score
846
Points
113
Спасибо за статью, Очень полезная информация! Но зачем ты сходу с козырей херачит? Таким скромным автором как я, даже неловко публиковаться(
Шучу
 
  • Thank you
Reactions: WLDN and 606

Users Who Are Viewing This Thread (Total: 1, Members: 0, Guests: 1)