Ние автоматизираме работата с Android програми с помощта на услугата за достъпност
Съдържанието на статията
Както обсъдихме в предишната статия, услугата за достъпност може да получава събития, които се случват на екрана, но също така може да ги повдига. Напримернамерете желаните елементи в приложението и щракнете върху тях.
За изследователски цели създадох приложение, което ще щрака върху себе си от собствената си услуга :).
Сервизна подготовка
За да започне да работи нашата услуга, тя трябва дапредостави права в специална секция за настройки. Вече знаете как да пренасочите потребителя там от първата статия. Освен това ние сами можем да проверим отново дали приложението има тези права.
Тук accessibilityservice_id е низ като "име на пакет/.service", имаме го ru.androidtools.selfclicker/.ClickService.
Ето описанието на услугата от манифеста:
Параметърът етикет отговаря за името на приложението в настройките на услугата за достъпност. Разделът с метаданни съдържа индикация за описанието на необходимите функции, за да работи услугата. Ето файлаserviceconfig :
В него ние описваме разрешенията на услугата, типовете събития, които може да обработва, и дейността, която ще бъде стартирана за конфигуриране на услугата.
Пълно описание на тези параметри, както винаги, е в документацията.
checkAccess() върна невярно!Xakep #240. Гидра
Жизненият цикъл на услугата се управлява от системата. Не можем сами да спрем услугата. ОС автоматично ще разтовари ненужните услуги - например, защо да въртите услугата за приложение, което не работи?
Можем да обвържем услугата със строго необходимо приложение. Веднага щом дадем разрешение за работа, услугата ще извика методаonServiceConnected. Трябва да извикаме методаsetServiceInfo() с параметъраAccessibilityServiceInfo от него. Отзадфилтрирането на приложения, с които работи услугата, се отговаря от масива от низовеpackageNames.
Да, определено ще го направиРабота с AccessibilityEvents
След като раздадем всички разрешения, трябва да стартираме желаното приложение. Ако знаем името на неговия пакет, това е лесно да се направи:
За да стартирате приложението от нулата, използвайте флагаIntent.FLAG_ACTIVITY_CLEAR_TOP. В противен случай приложението може да се върне на екрана със старо състояние, което е много далеч от началния екран.
Сега трябва да обработваме събития в методаonAccessibilityEvent. Събитието има тип, то ще помогне да се определи какво се е случило (например прозорецът е променен, елементът е щракнат, елементът е получил фокус). За да получите източника на събитиеAccessibilityNodeInfo, извикайте методаgetSource() на обекта на събитието.
Източникът има много полезни свойства, които помагат в работата: текст, ID, име на клас. Може да има родителски и дъщерни елементи.
Може да се кликваisClickable() и за да щракнете върху него като нормален потребител, трябва да извикате методаperformAction(AccessibilityNodeInfo.ACTION_CLICK).
Ако искаме повече глобални действия, катонатискане на клавиша за връщане назад на устройството, тогава трябва да извикаме методаperformGlobalAction() с желания параметър.
За да намерим необходимияAccessibilityNodeInfo на екрана, можем да извикаме един от методите: търсене по ID (findAccessibilityNodeInfosByViewId) и търсене по текст (findAccessibilityNodeInfosByText). Бъдете готови за факта, че ще ни върне масив от елементи или нито един.
Нека се упражняваме върху котките, по-точно - върху прозорците
Ето маркирането за нашия тестов екран:
Някои елементи имат ID и текст, другисамо текст, някои не могат да се кликнат.
Понякога манипулаторите за щракване се задават на области, които са по-големи от елемент с текст или изображение.
Нека проучим тази задача с помощта на методаdebugClick.
Ето какво излезе в дневника:
За давъзпроизвеждате поредица от щраквания, първо трябва да проверите елементите, върху които ще щраквате. Но понякога е важна и последователността на кликванията им.
За щраквания върху първите два бутона можете да използватеfindAccessibilityNodeInfosByText иfindAccessibilityNodeInfosByViewId. Ако текстът на елементите се повтаря, можете допълнително да проверите заClassName или родителя.
За да щракнем върху нашияLinearLayout, трябва да го получимAccessibilityNodeInfo, той няма ID, но имаTextView иButton деца, които имат текст.
Първо трябва да вземем един от тях и след това да щракнем върху неговия родител.
Има и обратни ситуации, когато има родител, а ние кликваме върху децата. За да направите това, използвайтеnodeInfo.getChildCount() и достъпете елемента в цикъла чрез IDnodeInfo.getChild(id) (ако не греша, номерирането на ID започва от нула).
По-добре е да стартирате услугата със събитието за промяна на прозореца:
Ако целият алгоритъм от действия вече е готов, тогава можете да стартирате услугата автоматично чрезAlarmManager, например веднъж на ден.
Можете да отмените стартирането по следния начин:
Заключение
КласътAccessibilityService ще ви позволи да се отървете от рутинните операции на вашето устройство с Android. Неговите възможности са достатъчни за изпълнение на почти всяка задача, основното е да дадете разрешения и да намерите елемента, върху който можете да щракнете, на екрана.