|
97 / 4 / 0
Регистрация: 09.05.2015
Сообщений: 70
|
||||||
Артефакт при осуществлении первой попытки обратного вызова для метода onAccessibilityStateChanged20.03.2017, 13:27. Показов 1373. Ответов 12
Я использую в своем приложении функциональность, связанную с дополнительными возможностями, представляемыми через использование служб Accessibility Services для операционной системы Андроид.
Созданная для моего приложения служба Accessibility Service первоначально находится в отключенном состоянии. При запуске своего приложения я проверяю включена ли для моего приложения моя служба Accessibility Service с заданным именем. Если соответствующая служба не включена, я вызываю Активити с системными настройками Андроида, где пользователь может вручную включить службу Accessibility Service для моего приложения. После того, как пользователь нажмёт на кнопку включения моей службы в Настройках, мне необходимо отследить событие соответствующее тому, что произошло изменение состояния моей службы. Т.е. сразу же после включения в Настройках моей службы Accessibility Service, необходимо осуществить проверку того, что эта служба оказалась включенной. Для этого я использую подход, связанный с использованием обратного вызова метода, который отрабатывает AccessibilityStateChangeListener для созданного мной экземпляра AccessibilityManager. Ниже будет приведен фрагмент кода из файла MainActivity.java моего приложения, который отвечает за регистрацию обратного вызова метода onAccessibilityStateChanged, проверяющего состояние того, включена ли моя служба Accessibility Service. По какой-то непонятной причине при первом вызове этого метода моя служба не появляется в списке включенных служб, получаемых при помощи вызова метода getEnabledAccessibilityServiceList(). При последующем нажатии кнопки "Выкл.", а затем "Вкл." для службы Accessibility Service моего приложения вызов метода onAccessibilityStateChanged() начинает корректно отображать состояние включенности моей службы. 1. Скажите, по какой причине метод getEnabledAccessibilityServiceList() при первоначальном отработке события обратного вызова onAccessibilityStateChanged() возвращает некорректные сведения о состоянии включенности моей службы? Таким образом, чтобы обойти этот артефакт я предполагаю осуществить вызов события обратного вызова метода onAccessibilityStateChanged() ВРУЧНУЮ. Только я не понимаю, как это можно сделать. 2. Подскажите, пожалуйста, каким образом можно ВРУЧНУЮ (т.е. программным образом) осуществить вызов метода onAccessibilityStateChanged() в самом конце метода onCreate() класса MainActivity моего приложения?
0
|
||||||
| 20.03.2017, 13:27 | |
|
Ответы с готовыми решениями:
12
Не удалось найти значение для обратного вызова или не был реализован ICallbakEventHandler При попытке вызова метода ничего не происходит. Код не отрабатывает. Выбор метода для вызова с varags параметрами |
|
Модератор
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
|
|
| 20.03.2017, 13:35 | |
|
InessaSuper, при включении службы вызывается какой-либо метод самой службы (риторический вопрос) - почему бы просто не ловить ее состояние в этом методе вместо того что бы цеплять слушатели?
0
|
|
|
2884 / 2296 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
|
||
| 20.03.2017, 14:19 | ||
|
Добавлено через 31 минуту а вообще если делать через слушатель, как в коде выше то там прилетает переменная onAccessibilityStateChanged(boolean b) которая показывает включили сервис или нет и я не понимаю зачем там этот дикий цикл с перебором
1
|
||
|
97 / 4 / 0
Регистрация: 09.05.2015
Сообщений: 70
|
|
| 20.03.2017, 16:49 [ТС] | |
|
Первоначально я тоже предполагала использовать обработчик событий onServiceConnected в запущенной мною службе.
При этом в обработчике события onServiceConnected в классе своей службы AppAccessibilityService я планировала изменять значение соответствующего флага isEnabled в true, индицирующего таким образом, что служба запущена. Но я столкнулась с тем, что в документации по API для Accessibility Services не определен обработчик события onServiceDisconnected как для обычных служб. Таким образом, у меня нет возможности изменить значение флага isEnabled в false для созданной моим приложением службы Accessibility Service в том случае, когда пользователь отключает разрешение на её использование в Настройках. Я пыталась использовать унаследованный от обычной службы обработчик события onDestroy(), но для служб Accessibility Services это событие отрабатывает, когда служба удаляется вместе с деинсталляцией использующего её приложения. А когда же я просто в Настройках отключаю свою службу Accessibility Service, то управление не передаётся обработчику события onDestroy(). И нет никакого другого обработчика события отключения службы Accessibility Service, в котором я могла бы перевести значение соответствующего флага isEnabled в fasle. Поэтому мне всё равно необходимо было бы использовать слушатель AccessibilityStateChangeListener для того, чтобы проверять значение флага isEnabled в ссылке на экземпляр класса своей службы AppAccessibilityService. Таким образом, мне в любом случае необходимо использовать обработчик onAccessibilityStateChanged() для слушателя AccessibilityStateChangeListener, т.к. я не могу передавать поток управления ходом выполнения операций из своего приложения куда-либо (в том числе и в запущенной мною службу, которая "живёт своей жизнью"). Каким образом я осуществляю проверку "запущенности" моей службы Accessibility Service в своём приложении - это вопрос вторичный. Цикл с перебором для всех запущенных служб с помощью вызова метода getEnabledAccessibilityServiceList() в обработчике события onAccessibilityStateChanged используется мной потому, что обработчик onAccessibilityStateChanged отрабатывает при изменении ЛЮБОЙ из установленных на мобильном устройстве служб Accessibility Service, но не конкретизирует какая именно служба изменила своё состояние. Главный мой вопрос заключается в том, каким образом я могу вызвать обработчик onAccessibilityStateChanged() вручную программным образом, чтобы исключить влияние описанного мною выше артефакта?
0
|
|
|
2884 / 2296 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
|
|||
| 20.03.2017, 16:55 | |||
|
Добавлено через 1 минуту вместо стрёмных статических флагов оттуда лучше кидать интент, который будет ловить активити или сервис - смотря как надо реагировать
0
|
|||
|
97 / 4 / 0
Регистрация: 09.05.2015
Сообщений: 70
|
|
| 20.03.2017, 17:58 [ТС] | |
|
Мне кажется я нашла причину возникновения описанного мною артефакта, но не могу понять как мне с ним бороться.
Я обратила внимание, что в протоколе LogCat при первоначальном включении моей службы происходит сначала запуск обработчика метода onAccessibilityStateChanged() для слушателя AccessibilityStateChangeListener из класса MainActivity, а затем уж отрабатывает обработчик метода onServiceConnected() из класса моей службы AppAccessibilityService. Поэтому какой бы подход я не использовала для определения того, запущена ли моя служба: во время её первого запуска, по какой-то причине, всегда отрабатывает "НЕПРАВИЛЬНАЯ" последовательность событий: Последовательность 1 - MainActivity.accessibilityManager.Access ibilityStateChangeListener.onAccessibili tyStateChanged() - AppAccessibilityService.onServiceConnect ed() А вот уже затем после выключения и последующего включения моей службы всё отрабатывает ПРАВИЛЬНО и как надо в следующей последовательности: Последовательность 2 - AppAccessibilityService.onServiceConnect ed() - MainActivity.accessibilityManager.Access ibilityStateChangeListener.onAccessibili tyStateChanged() Вопрос заключается в следующем. Какова причина возникновения описанного мною артефакта и как можно сделать так, чтобы запуск необходимых мне обработчиков запускался сразу в соответствии со 2-й последовательностью?
0
|
|
|
2884 / 2296 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
|
||
| 20.03.2017, 18:24 | ||
|
зачем вообще в MainActivity вешается этот слушатель? есть сервис - пусть он кидает интенты при старте/останове и на них уже реагирует активити
0
|
||
|
97 / 4 / 0
Регистрация: 09.05.2015
Сообщений: 70
|
||||||
| 20.03.2017, 18:59 [ТС] | ||||||
|
Я завела этот слушатель в MainActivity для того, чтобы в потоке выполнения приложения сделать как бы "остановку", пока пользователь не включит мою службу AppAccessibilityService.
Сразу же после того, как пользователь "включает" мою службу, я в обработчике слушателя передаю выполнение исполняемого потока своего приложения далее. Пока моя служба не включена, я не могу передавать поток управления своего приложения далее, т.к. "включаемая" мною служба мониторит активити других приложений, запускаемых в дальнейшем в свою очередь из моего приложения. Подскажите, пожалуйста, что имется ввиду под высказыванием "есть сервис - пусть он кидает интенты при старте/останове и на них уже реагирует активити"? Я ещё не волшебница, а только учусь... Ниже приведен мой класс AppAccessibilityService, который отслеживает activityName в запускаемых приложениях на Андроид устройстве. Скажите, каким образом необходимо изменить классы AppAccessibilityService и MainActivity, чтобы реализовать рекомендуемый подход с "киданием интентов при старте/останове и реагировании на них активити"?
0
|
||||||
|
2884 / 2296 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
|
|||||||||||
| 20.03.2017, 19:59 | |||||||||||
|
ну вот например есть сервис, я оттуда все лишнее вытер, оставил строки, которые надо перенести в свой сервис
1
|
|||||||||||
|
97 / 4 / 0
Регистрация: 09.05.2015
Сообщений: 70
|
||||||
| 21.03.2017, 10:53 [ТС] | ||||||
|
Приведенный выше код отлично работает.
Для того, чтобы его запустить мне понадобилось добавить ещё одну строчку кода в метод sendMessageToActivity() класса MyAccessibilityService (intent.setFlags(Intent.FLAG_ACTIVITY_NE W_TASK) , чтобы избежать следующей ошибки возникшей при компиляции:android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? Теперь метод sendMessageToActivity() выглядит следующим образом:
Adding Intent.FLAG_ACTIVITY_NEW_TASK will solve your error, but make sure if you need this flag or not as it will trigger the activity as new task which you may not want in your scenario. Start new Activity outside the Activity context (см. 3-й ответ) http://stackoverflow.com/quest... ty-context Я хочу понять, что критичного в том, что в моём случае MainActivity будет запускаться как новый таск? Какие проблемы может за собой повлечь использование этого подхода в дальнейшей работе моего приложения?
0
|
||||||
|
Модератор
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
|
|
| 22.03.2017, 08:53 | |
|
InessaSuper, новый таск это к примеру у вас уже запущена активити со своим стеком возвратов и тут бац ещё одна такая же на пустом месте
0
|
|
| 22.03.2017, 10:39 | |
|
Не по теме: да там на самом деле проще просто прочитать внимательно что написано в подсказке по Ctrl+Q для каждого из вариантов (и на флагах и в манифесте), а не ждать пока на форуме кто-то потрудится настрочить пол страницы текста
0
|
|
| 22.03.2017, 11:00 | |
|
0
|
|
| 22.03.2017, 11:00 | |
|
Помогаю со студенческими работами здесь
13
Процедура обратного вызова Функция обратного вызова Интерфейсы обратного вызова Функция обратного вызова Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
|
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма).
На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
|
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ *
Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам
Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
|
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым.
Но восстановить их можно так.
Для этого понадобится консольная утилита. . .
|
|
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
|
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11
— это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
|
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11
Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
|
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
|