Перейти к содержимому

Как включить api accessibility service

  • автор:

В Android 13 Google ограничит доступ к спец. возможностям

В Google решили ограничить доступ к службам специальных возможностей (API AccessibilityService) приложениям, которые загружены из неизвестных источников. Такое изменение появится на устройствах под управлением Android 13. Выясняем: что это может означать для пользователей с нарушением зрения.

✅ Ограничение обусловлено соображениями безопасности пользователей.

Дело в том, что приложения, обращающиеся к специальным возможностям, получают гораздо больше прав на устройстве, чем обычные приложения. В частности, специальные возможности дают приложению доступ к информации, отображаемой на экране устройства. Эта возможность предназначена для программ экранного доступа для пользователей с нарушением зрения, например: TalkBack и Jieshuo (Commentary) Screenreader. Но и приложения, модифицированные злоумышленниками, могут, пользуясь правами специальных возможностей, отслеживать информацию, появляющуюся на экране, включая личные и платёжные данные. только в отличии от программы экранного доступа, вовсе не с целью озвучить данные для пользователя. Причём владелец устройства может и не подозревать о такой активности приложения.

✅ Ограничение коснётся только приложений, загруженных из неизвестных источников.

На устройство с системой Android пользователь может устанавливать приложения двумя способами:

  1. Загружать из официальных магазинов приложений (Google Play, F-droid, Samsung Galaxy Store и др.). Считается, что перед публикацией в магазине проводится проверка приложений на безопасность.
  2. Скачивать файл с расширением APK с других интернет-ресурсов. Такие приложения Google называет загруженными из неизвестных или ненадёжных источников. Есть опасность, что приложение могло быть изменено злоумышленниками.

Популярную среди незрячих пользователей Android-устройств программу экранного доступа Jieshuo (Commentary) Screenreader приходится устанавливать как раз вторым способом.

✅ Кстати, рассматриваемое ограничение — не единственное. Как сообщает сайт о технологиях 4PDA, Google с 11 мая ограничивает доступ к API AccessibilityService сторонним приложениям для записи телефонных разговоров. В прочем, опция записи звонков остаётся легальной для приложений, предустановленных производителями устройств.

Отметим, что пока нет подробностей, сложно с уверенностью говорить о том, как эти изменения отразятся на незрячих пользователях будущей версии системы Android (Android 13). Тем не менее, мы обратились за комментарием к Сергею Екатеринушкину — преподавателю, обучающему начинающих пользователей с нарушением зрения (г. Тамбов).

Комментарий Сергея Екатеринушкина

«Что касается записи звонков: смартфоны фирм Huawei и Xiaomi могут записывать телефонные разговоры через стандартное приложение «Диктофон» либо непосредственно в звонилки, то есть в приложение «Телефон». Китайские производители модифицировали эти приложения таким образом, чтобы они могли записывать звонки, и встроили их в систему. Так что подобные ограничения, вводимые компанией Google, могут быть обойдены производителями устройств на уровне модификации системы.

Что касается основного вопроса о специальных возможностях, то китайский Commentary screenreader работает, например, и на смартфонах Samsung. В устройствах Samsung свой набор сервисов отвечающих за спец. возможности. Приэтом сторонние приложения использующие API AccessibilityService, не могут их задействовать. Так, в тех местах где активируется элемент обычным двойным касанием, например, при срабатывании стандартного будильника, с Commentary screenreader приходится провести двумя пальцами снизу вверх либо в всторону.

Ввод текста на фирменной клавиатуре Samsung тоже не даёт для Commentary весь свой функционал. Так при наборе текста с Commentary и клавиатурой Samsung нужно включить отображение клавиши смены раскладки (Глобус) в настройках самой клавиатуры. Другая проблема — это отсутствие функции «Ввод одним касанием», когда мы отпускаем символ, чтобы его ввести. Приходится вводить букву двойным касанием, как активируем обычный элемент управления на экране. Эти мелкие неудобства обходятся установкой клавиатуры Google.

Также, на некоторых моделях Samsung фирменный браузер Samsung internet не даёт Commentary читать web-странички. Но ведь Android — открытая ОС. Есть альтернативы в виде браузеров Chrome и FireFox.

Таким образом, можно сделать вывод, что возможны небольшие неудобства, с которыми столкнутся незрячие пользователи при обновлении до Android 13. Уверен, что часть проблем решиться заменой некоторых стандартных приложений, таких как клавиатура, либо использованием новых жестов, либо разработчики Commentary screenreader со временем исправят возникшие проблемы, а активное сообщество пользователей в этом поможет.

А если вы — начинающий пользователь, то переждите этот период адаптации и не обновляйте своё устройство до тех пор, пока не решатся критичные для вас проблемы. Но паниковать точно не стоит», — заключает Сергей Екатеринушкин.

Хотите оперативно узнавать о новых публикациях? Присоединяйтесь к нашей группе в WhatsApp.

Благодарим Вас за внимание! Пожалуйста, поделитесь с друзьями в соцсетях.

Контроль над Android. Перехватываем данные и сбрасываем настройки смартфона через самые опасные API

Кро­ме тра­дици­онных раз­решений, в Android есть три мета‑раз­решения, которые откры­вают дос­туп к весь­ма опас­ным API, поз­воля­ющим в пря­мом смыс­ле зах­ватить кон­троль над устрой­ством. В этой статье мы научим­ся их исполь­зовать, что­бы прог­рам­мно нажимать кноп­ки смар­тфо­на, перех­ватывать уве­дом­ления, извле­кать текст из полей вво­да дру­гих при­ложе­ний и сбра­сывать нас­трой­ки смар­тфо­на.

О каких API пой­дет речь?

  1. Ад­минис­три­рова­ние устрой­ства — API, пред­назна­чен­ный для кор­поратив­ных при­ложе­ний. Поз­воля­ет сбра­сывать и уста­нав­ливать пароль экра­на бло­киров­ки, сбра­сывать смар­тфон до завод­ских нас­тро­ек и уста­нав­ливать пра­вила минималь­ной слож­ности пароля. Одна из осо­бен­ностей API — зап­рещено уда­лять при­ложе­ния, получив­шие пра­ва адми­нис­тра­тора, чем с радостью поль­зуют­ся авто­ры злов­редных при­ложе­ний.
  2. Accessibility — API для реали­зации при­ложе­ний, ори­енти­рован­ных на людей с огра­ничен­ными воз­можнос­тями. Фак­тичес­ки API поз­воля­ет соз­давать аль­тер­натив­ные спо­собы управле­ния устрой­ством и поэто­му откры­вает поис­тине огромный прос­тор для зло­упот­ребле­ния. С его помощью мож­но получить дос­туп к содер­жимому экра­на прак­тичес­ки любого при­ложе­ния, нажимать кноп­ки интерфей­са и прог­рам­мно нажимать кла­виши самого смар­тфо­на. Но есть и спо­соб защиты: раз­работ­чик при­ложе­ния может пря­мо ука­зать, что опре­делен­ные эле­мен­ты интерфей­са при­ложе­ния будут недос­тупны для сер­висов Accessibility.
  3. Уве­дом­ления — API, поз­воля­ющий получить дос­туп ко всем уве­дом­лени­ям, которые отоб­ража­ются в панели уве­дом­лений. С помощью это­го API при­ложе­ние может про­читать всю информа­цию об уве­дом­лении, вклю­чая заголо­вок, текст и содер­жимое кно­пок управле­ния, нажать на эти кноп­ки и даже смах­нуть уве­дом­ление. API поль­зует­ся осо­бой популяр­ностью сре­ди раз­работ­чиков все­воз­можных бан­ков­ских тро­янов, с помощью которо­го они могут читать коды под­твержде­ния и сма­хивать пре­дуп­режда­ющие сооб­щения от бан­ков.

По­лучив дос­туп ко всем этим API, злов­редное при­ложе­ние смо­жет сде­лать со смар­тфо­ном прак­тичес­ки все что угод­но. Имен­но поэто­му для их защиты исполь­зуют­ся не тра­дици­онные зап­росы пол­номочий, на которые поль­зователь может машиналь­но отве­тить «Да», а скры­тый глу­боко в нас­трой­ках интерфейс, который при акти­вации покажет угро­жающее сооб­щение. Все, что может сде­лать при­ложе­ние, что­бы получить нуж­ное пол­номочие, — это переб­росить поль­зовате­ля в окно нас­тро­ек, пос­ле чего тот дол­жен будет най­ти нуж­ное при­ложе­ние, вклю­чить нап­ротив него перек­лючатель и сог­ласить­ся с пре­дуп­режда­ющим сооб­щени­ем.

Зас­тавить поль­зовате­ля дать раз­решение на исполь­зование этих API мож­но обма­ном. Зачас­тую злов­реды при­киды­вают­ся легитим­ными при­ложе­ниями, которым раз­решение нуж­но для работы клю­чевой фун­кци­ональ­нос­ти. К при­меру, это может быть при­ложе­ние для ведения жур­нала уве­дом­лений или при­ложе­ние для аль­тер­натив­ной жес­товой навига­ции (такому при­ложе­нию нужен сер­вис Accessibility для нажатия кно­пок навига­ции). Так­же мож­но исполь­зовать ата­ку Cloak & Dagger, что­бы перек­рыть окно нас­тро­ек дру­гим безобид­ным окном.

Нажимаем кнопки смартфона

Прос­тей­ший сер­вис Accessibility может выг­лядеть так (код на Kotlin):

Что­бы сис­тема узна­ла о нашем сер­висе, его необ­ходимо объ­явить в AndroidManifest.xml :

Это опи­сание ссы­лает­ся на кон­фигура­цион­ный файл accessibility_service_config.xml , который дол­жен быть опре­делен в катало­ге xml про­екта. Для нашего слу­чая дос­таточ­но будет такого кон­фига:

Пос­ле того как поль­зователь вклю­чит наш сер­вис Accessibility в окне «Нас­трой­ки → Спец. воз­можнос­ти», сис­тема авто­мати­чес­ки запус­тит сер­вис и мы смо­жем выпол­нить фун­кцию pressHome() , что­бы нажать кноп­ку «Домой»:

// Если service не null — значит, система успешно запустила сервисif (AccessService.service != null)

Од­ной лишь толь­ко этой фун­кци­ональ­нос­ти дос­таточ­но, что­бы реали­зовать Ransomware, который будет вызывать фун­кцию pressHome() в цик­ле и бес­конеч­но воз­вра­щать поль­зовате­ля на домаш­ний экран, не давая нор­маль­но исполь­зовать устрой­ство.

Контроль над Android. Перехватываем данные и сбрасываем настройки смартфона через самые опасные API
Ок­но вклю­чения сер­виса Accessibility в Android 11

Од­нако нас­тоящая мощь Accessibility кро­ется не в нажатии кно­пок навига­ции, а в воз­можнос­ти кон­тро­лиро­вать дру­гие при­ложе­ния.

Перехватываем содержимое полей ввода

API Accessibility был соз­дан для людей с огра­ничен­ными воз­можнос­тями. С его помощью мож­но, нап­ример, соз­дать при­ложе­ние, которое будет зачиты­вать все над­писи интерфей­са и поз­волит нажимать эле­мен­ты интерфей­са голосом. Все это дос­тижимо бла­года­ря тому, что Accessibility дает пол­ный дос­туп к интерфей­су при­ложе­ний в виде дерева эле­мен­тов: мож­но прой­ти по нему и выпол­нить над эле­мен­тами опре­делен­ные опе­рации.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Что стоит учесть при разработке приложения для специальных возможностей в Android?

Я наткнулся на проблему описанную в вопросе на этом же форуме — см. Служба специальных возможностей неисправна. Покапавшись в сети я нашел этот сайт — см. Сервис работает некорректно Xiaomi спец возможности. В нем написано следующие:

  1. Включите администрирование устройства. Сделав это, пришло время заглянуть в меню «Администрирование устройства». Приложения с правами администратора устройства остаются в памяти и редко отключаются в настройках специальных возможностей.

Что, конечно, не является техническим ликбезом, но это всё что я нашел, что хоть косвенно, но связано с этой проблемой.

Моему приложению выдано разрешение IGNORE_BATTERY_OPTIMIZATIONS, Wake Lock также используется.

Тогда у меня возник вопрос, а как другие разработчики с этим справляются?

Вопросы

    Правильно ли я делаю, включая Wake Lock только в ресивере:

public class ScreenReceiver extends BroadcastReceiver < public static boolean wasScreenOn = true; @Override public void onReceive(final Context context, final Intent intent) < if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) < // do whatever you need to do here wasScreenOn = false; System.out.println("Экран: выключен"); // Включить блокировку спящего режима для своего приложения: MyService.wakeLock.acquire(); System.out.println("Включить блокировку спящего режима для своего приложения"); >else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) < // and do whatever you need to do here wasScreenOn = true; System.out.println("Экран: включен"); // Выключить блокировку спящего режима для своего приложения: MyService.wakeLock.release(); System.out.println("Выключить блокировку спящего режима для своего приложения"); >> > 

Ну, т.е в MyService и в AccessibilityService нет включений кода:

MyService.wakeLock.release() и MyService.wakeLock.acquire() 

Отслеживать
17.9k 11 11 золотых знаков 25 25 серебряных знаков 57 57 бронзовых знаков
задан 11 июл 2023 в 15:01
27 2 2 бронзовых знака

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Тогда у меня возник вопрос, а как другие разработчики с этим справляются?

С проблемой спец возможности работают некорректно, можно справится поставив wake lock, но не там где я поставил.

  1. Wake lock обычно прописывают в классах, у которых есть свой жизненный цикл. Таких как Activity, Service, IntentService. В AccessibilityService прописывать wake lock не нужно, т.к он является автономным и его жизненный цикл управляется непосредственно Android OS. У ресиверов жизненный цикл отсутствует вовсе. Их код просто переодически вызывается системой и только тогда код ресивера активный.
  2. Также я заметил, что в службах прописывать код Wake Lock также не требуется, если служба работает не постоянно, а запускается той которая работает постоянно. Т.е если MainService запускает службу GPSTraker и после какого-то времени служба отключается, в ней реализовывать wake lock не обязательно(у меня это и так работает).

в службе или активности нужно прописывать код создания Wake Lock:

PowerManager.WakeLock wakeLock = null; @Override public void onTaskRemoved(Intent rootIntent) < if (wakeLock != null) < if (wakeLock.isHeld() == true) < wakeLock.release(); >> > @Override public void onDestroy() < super.onDestroy(); if (wakeLock != null) < if (wakeLock.isHeld() == true) < wakeLock.release(); >> > @Override public void onCreate() < super.onCreate(); PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE); if (wakeLock == null) < wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PeriSecure:MyWakeLock"); >if (wakeLock != null) < if (wakeLock.isHeld() == false) < wakeLock.acquire(); >> > 

В каждом классе нужно создать новый WakeLock, а не использовать старый.

Надеюсь я понятно объяснил. Хотя, в Android документации объясняют не лучше..

В моём случае, я не там включал WakeLock и Android перезапускал службу спец возможностей, это видимо и приводило к не корректной работе. Как описывается в Accessibility Service is malfunctioning.

Это не из вашего приложения. После завершения работы вашего приложения системой. При следующей попытке включить службу специальных возможностей всегда не удается запустить службу специальных возможностей. Это ошибка Android. Android не удается запустить службу специальных возможностей после завершения работы службы. Вы ничего не можете с этим поделать. Кто-то уже отправил отчет об ошибке в Google в 2016 году, но это не было исправлено. Проверьте это: issuetracker.google.com/issues/37123359

Что ещё мне стоит знать, чтобы служба спец возможностей работала стабильно и без перебоев?

По сути больше учитывать нечего для работы службы в штатном режиме. Я надеюсь только у меня возник вопрос, а что делать если MainService не задумывался как работающий при выключенном экране, ведь тогда приложение остановится и служба спец возможностей вместе с ним, а обратно уже не запустится..

Моё предложение: по ходу, разберемся )

Автоматизируем работу с программами на Android при помощи Accessibility Service

И программистам, и хакерам, и безопасникам иногда нужны способы автоматизировать пользовательские действия — то есть писать скрипты, которые будут тыкать в кнопки чужих софтин так, чтобы те принимали это чистую монету. Кто сказал «негласно автоматизировать работу с мобильным банком»? �� Стыдитесь, товарищ! Мы за мирную автоматизацию. В прошлой статье по Accessibility Service мы сфокусировались на получении данных экрана, а сегодня мы научим Accessibility Service делать работу на устройстве за нас!

WWW

Понажимай эти кнопки за меня

Еще в XIX веке Гегель сказал: «Машиноподобный труд нужно отдать машинам». И тут с одним из творцов немецкой классической философии трудно поспорить: вряд ли Георг Вильгельм Фридрих отказался бы от автоматизации таких действий, как отключение звука и нажатие кнопки «Пропустить рекламу» при просмотре ролика в YouTube или получение ежедневных бонусов за посещение приложения. Тем более что для всего этого у нас уже есть готовый инструментарий!

Как мы говорили в предыдущей статье, Accessibility Service может получать события, происходящие на экране, но он же может и вызывать их. Например, находить нужные элементы в приложении и кликать по ним.

Ставить чужое приложение с подобной функциональностью опасно — все мы знаем репутацию Google Play и примерно представляем себе, что такое приложение может сделать с твоим банковским клиентом на телефоне. Поэтому выхода два: либо декомпилировать чужое ПО и смотреть, куда именно оно нажимает, либо пилить свое, строго под поставленные задачи.

Для исследовательских целей я создал приложение, которое будет само в себя кликать из собственного сервиса :).

Подготовка к работе сервиса

Чтобы наш сервис начал работу, ему нужно предоставить права в специальном разделе настроек. Как перенаправить туда пользователя, ты уже знаешь из первой статьи. Дополнительно мы сами можем перепроверить, есть ли эти права у приложения.

 protected boolean checkAccess() < String string = getString(R.string.accessibilityservice_id); for (AccessibilityServiceInfo id : ((AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE)).getEnabledAccessibilityServiceList(AccessibilityEvent.TYPES_ALL_MASK)) < if (string.equals(id.getId())) < return true; >> return false; >

Здесь accessibilityservice_id — это строка вида «имя пакета/.сервис», у нас это ru.androidtools.selfclicker/.ClickService.

Вот описание сервиса из манифеста:

Параметр label отвечает за название приложения в настройках сервиса спецвозможностей. В разделе meta-data задается указание на описание нужных функций для работы сервиса. Вот файл serviceconfig:

В нем мы описываем полномочия сервиса, типы событий, которые он может обрабатывать, и активити, которое запустится для настройки работы сервиса.

Полное описание этих параметров, как всегда, есть в документации.

checkAccess() вернул false!

Рекомендуем почитать:

Xakep #295. Приемы рыбалки

  • Содержание выпуска
  • Подписка на «Хакер» -60%

Жизненным циклом сервиса управляет система. Сами остановить сервис мы не можем. ОС самостоятельно выгрузит ненужные сервисы — к примеру, зачем крутить сервис для приложения, которое не запущено?

Мы можем привязать сервис к строго нужному приложению. Как только мы дали разрешение на работу, у сервиса вызовется метод onServiceConnected. У него мы должны вызвать метод setServiceInfo() с параметром AccessibilityServiceInfo. За фильтрацию приложений, с которыми работает сервис, отвечает строковый массив packageNames.

@Override protected void onServiceConnected() < super.onServiceConnected(); Log.v(TAG, "onServiceConnected"); AccessibilityServiceInfo info = new AccessibilityServiceInfo(); info.flags = AccessibilityServiceInfo.DEFAULT | AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS; info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; info.packageNames = new String[]; setServiceInfo(info); >

Да, он точно будет

Работаем с событиями AccessibilityEvent

После раздачи всех разрешений нам надо запустить нужное приложение. Если мы знаем его имя пакета, сделать это несложно:

 private void startApp() < Intent launchIntent = getPackageManager().getLaunchIntentForPackage("ru.androidtools.selfclicker"); // Запуск из нужного места без предыстории приложения launchIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(launchIntent); >

Для запуска приложения с чистого листа используем флаг Intent.FLAG_ACTIVITY_CLEAR_TOP. В противном случае приложение может вернуться на экран со старым состоянием, очень далеким от стартового экрана.

Теперь нужно обрабатывать события в методе onAccessibilityEvent. У события есть тип, он поможет определить, что произошло (например, сменилось окно, кликнули по элементу, элемент получил фокус). Чтобы получить источник события AccessibilityNodeInfo, надо у объекта события вызвать метод getSource().

Источник имеет много полезных свойств, помогающих в работе: текст, ID, имя класса. У него могут быть родительский и дочерние элементы.

Он может быть кликабельным isClickable(), и, чтобы щелкнуть по нему, как нормальный пользователь, нужно вызвать метод performAction(AccessibilityNodeInfo.ACTION_CLICK).

Если мы хотим более глобальных действий, например нажать клавишу «Назад» на устройстве, то следует вызвать метод performGlobalAction() с нужным параметром.

Чтобы найти на экране требующуюся AccessibilityNodeInfo, мы можем вызвать один из методов: поиск по ID (findAccessibilityNodeInfosByViewId) и поиск по тексту (findAccessibilityNodeInfosByText). Будь готов к тому, что он вернет нам массив элементов или вообще ни одного.

Потренируемся на кошках, точнее — на окошках

Вот разметка нашего подопытного экрана:

У некоторых элементов есть ID и текст, у других только текст, некоторые некликабельны.

Иногда обработчики кликов устанавливают на области, превышающие своими размерами элемент с текстом или картинкой.

Поизучаем эту задачу с помощью метода debugClick.

 private void debugClick(AccessibilityEvent event) < if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) < AccessibilityNodeInfo nodeInfo = event.getSource(); if (nodeInfo == null) < return; >nodeInfo.refresh(); Log.d(TAG, "ClassName:" + nodeInfo.getClassName() + " Text:" + nodeInfo.getText() + " ViewIdResourceName:" + nodeInfo.getViewIdResourceName() + " isClickable:" + nodeInfo.isClickable()); > >

Вот что вышло в лог:

03-03 16:23:15.220 24461-24461/ru.androidtools.selfclicker D/ClickService: ClassName:android.widget.Button Text:ID/BUTTONTEST ViewIdResourceName:ru.androidtools.selfclicker:id/buttonTest isClickable:true 03-03 16:23:26.356 24461-24461/ru.androidtools.selfclicker D/ClickService: ClassName:android.widget.Button Text:БЕЗ ID ViewIdResourceName:null isClickable:true 03-03 16:23:36.697 24461-24461/ru.androidtools.selfclicker D/ClickService: ClassName:android.widget.LinearLayout Text:null ViewIdResourceName:null isClickable:true 03-03 16:23:44.320 24461-24461/ru.androidtools.selfclicker D/ClickService: ClassName:android.widget.Button Text:НЕРАБОЧАЯ КНОПКА ViewIdResourceName:ru.androidtools.selfclicker:id/button3 isClickable:true

Чтобы воспроизвести последовательность кликов, нужно сначала изучить элементы, которые будут нажиматься. Но иногда также важна и последовательность их нажатий.

Для нажатий на первые две кнопки можно использовать findAccessibilityNodeInfosByText и findAccessibilityNodeInfosByViewId. Если текст у элементов повторяется, дополнительно можно проверять на ClassName или родителя.

Чтобы кликнуть в наш LinearLayout, нужно получить его AccessibilityNodeInfo, ID у него нет, но есть дочерние элементы TextView и Button, у которых есть текст.

Для начала нам нужно получить один из них, а потом кликнуть в его родителя.

private boolean linearClick(AccessibilityNodeInfo nodeInfo) < Listlist = nodeInfo.findAccessibilityNodeInfosByText("Нерабочая кнопка"); if (list.size() > 0) < for (AccessibilityNodeInfo node : list) < AccessibilityNodeInfo parent = node.getParent(); parent.performAction(AccessibilityNodeInfo.ACTION_CLICK); >return true; > else return false; >

Бывают и обратные ситуации, когда есть родитель, а кликаем мы в дочерние. Для этого используй nodeInfo.getChildCount() и обращайся к элементу в цикле по ID nodeInfo.getChild(id) (если не ошибаюсь, нумерация ID идет с нуля).

Начинать работу сервиса лучше с события смены окна:

event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED

Если весь алгоритм действий уже готов, то можно запускать сервис автоматически через AlarmManager, например раз в сутки.

private void setRepeatTask() < Intent alarmIntent = new Intent(this, ClickService.class); PendingIntent pendingIntent = PendingIntent.getService( this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); // Запускаем в 10:00 Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 10); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, // Повторять каждые 24 часа pendingIntent); >

Отменить запуск можно вот так:

public void cancelRepeat()

Заключение

Класс AccessibilityService позволит избавиться от рутинных операций на твоем Android-устройстве. Его возможностей достаточно, чтобы реализовать почти любую задачу, главное — дать разрешения и найти кликабельный элемент на экране.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *