Как обрабатывать события движения (движение джойстика геймпада и т. Д.) Из AccessibilityService

#android #xamarin.android #accessibilityservice

#Android #xamarin.android #accessibilityservice

Вопрос:

У меня есть AccessibilityService, который принимает входные данные от игровых контроллеров (контроллер ps5, контроллер xbox и т. Д.).

Я использую этот onKeyEvent() метод для обработки нажатий и отпусканий кнопок, поэтому я могу легко с ними справиться. Проблема, с которой я сталкиваюсь, заключается в том, как обрабатывать движения джойстика и нажатия верхнего триггера, поскольку я не знаю, как обрабатывать их через AccessibilityService.

Обычно я бы просто использовал onGenericMotionEvent() для обработки этих событий движения, но, к сожалению, AccessibilityService не предоставляет мне такого метода. Я почти 3 недели безуспешно просматривал документы и официальные кодовые таблицы, если бы кто-нибудь мог рассказать мне, как обрабатывать события движения через AccessibilityService, я был бы очень рад.

События движения, которые я хочу обработать, следующие:

AXIS_X, AXIS_Y, AXIS_Y, AXIS_RZ, AXIS_RY, AXIS_RX, AXIS_HAT_X, AXIS_HAT_Y, AXIS_LTRIGGER, AXIS_RTRIGGER, AXIS_BRAKE,AXIS_GAS .

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

С уважением, 0xB01b

Ответ №1:

API не поддерживает их, потому что AccessibilityServices может фильтровать только ключевые события, а кнопки, как вы говорите, не создают ключевые события.

Можете ли вы объяснить, что вы создаете? Понимание влияния добавления этого API на жизнь людей с ограниченными возможностями помогло бы нам расставить приоритеты в этой работе наряду с другими вещами, которые мы планируем.

Комментарии:

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

Ответ №2:

В службе специальных возможностей вы можете получать и фильтровать только ключевые события, события движения не могут быть обработаны внутри этой службы

Один из возможных способов — создать сервис, реализующий интерфейс InputMethodService. Это похоже на создание виртуальной клавиатуры. Вы можете обрабатывать KeyEvent или MotionEvent в службе глобально. Я имею в виду, что вы можете узнать, что вводится в каждом действии после включения InputMethodService (например, изменение ввода с клавиатуры). И затем служба специальных возможностей может использоваться для отправки касания или салфетки.

Эта комбинация (InputMethodService AccessibilityService) позволяет сопоставлять джойстик для касания и прокрутки по всему миру.

Однако, чтобы заставить его действовать как настоящий джойстик, я думаю, что служба специальных возможностей не может помочь вам смоделировать событие движения, как вы ожидали. Возможно, только InjectInputEvent может делать именно то, что вы хотите. Но это приводит к старой проблеме: разрешению INJECT_EVENTS.

Комментарии:

1. Итак, я создаю другой сервис, который расширяет InputMethod Service, а затем использую его в своем AccessibilityService? И использовать InjectInputEvent() вместо DispatchGesture() ?

2. Нет. Две службы независимы. В AccessibilityService действия с касанием и движением можно имитировать с помощью dispatchGesture с описанием жестов. StrokeDescription. InputMethodService можно использовать для обработки ввода (KeyEvent и MotionEvent), который вы берете с джойстика. И внутри метода, который вы использовали для его обработки, вы можете вызвать метод для отправки жеста в AccessibilityService. Что касается InjectInputEvent, я до сих пор не знаю, как ввести его без root или специального разрешения.

3. Еще одна проблема с AccessibilityService заключается в том, что невозможно создать путь, который будет отправлен для имитации действия выпуска в событии ACTION_UP. Я имею в виду, что moveto() и lineto () можно использовать в ACTION_DOWN для нажатия и удержания значения willContinue, но тогда как отпустить нажатие в ACTION_UP?

4. Для освобождения крана, который я использую continueStroke() с помощью stoke, который не имеет продолжительности, он кажется немного глючным, но пока работает. Также, если я активирую свой accessibilityservice с помощью двух одновременно нажатых регуляторов громкости, могу ли я программно активировать InputMethod Service? или пользователь должен активировать обе службы отдельно? Кроме того, как мне вызвать их метод для отправки жестов из моего InputMethodService, у меня не может быть статического метода для этого, и я не уверен, смогу ли я просто сделать из него объект.

5. InputMethodService также необходимо активировать отдельно, но он не требует активации при каждом запуске, как служба специальных возможностей. Это похоже на виртуальную клавиатуру, поэтому, если вы измените метод ввода по умолчанию на этот, пользователю не нужно снова его активировать.

Ответ №3:

Чтобы создать InputMethodService, вы можете обратиться к этому официальному документу.

Сначала добавьте сервис в Manifest.xml:

 <service android:name=".IMService"
        android:permission="android.permission.BIND_INPUT_METHOD">
        <intent-filter>
            <action android:name="android.view.InputMethod"/>
        </intent-filter>
        <meta-data
            android:name="android.view.im"
            android:resource="@xml/method"/>
    </service>
 

Далее, method.xml нужно ли создавать в папке res/xml /:

     <?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
    android:isDefault="false"
    android:settingsActivity=".MainActivity">
    <subtype
        android:icon="@mipmap/ic_launcher"
        android:imeSubtypeLocale="en_US"
        android:imeSubtypeMode="keyboard"
        android:label="@string/app_name"/>
</input-method>
 

В этом случае раскладка клавиатуры не требуется.

Затем создайте класс IMService, реализующий InputMethodService.

Следующий код написан на Kotlin (например):

 class IMService: InputMethodService() {
companion object {
    private const val TAG = "IMService"
}

override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
    if(event.action == KeyEvent.ACTION_DOWN) {
        if (event.source and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD) {
            // process key down event here
            return true   // return true if you want the key event to be filtered
        }
    }
    return super.onKeyDown(keyCode, event)
}

override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
    if(event.action == KeyEvent.ACTION_UP) {
        if (event.source and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD) {
            // process key up event here
            return true
        }
    }
    return super.onKeyUp(keyCode, event)
}

override fun onGenericMotionEvent(event: MotionEvent): Boolean {
    if(event.action == MotionEvent.ACTION_MOVE) {
        if (event.source and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK) {
            // process motion event here
            return true
        }
    }
    return super.onGenericMotionEvent(event)
}
}
 

Жизненный цикл службы начинается после того, как вы включили и изменили метод ввода по умолчанию в настройках / ../ Language and keyboard / Список клавиатур и по умолчанию.

Комментарии:

1. Я сделал, и это сработало, я мог установить его из списка клавиатуры, я также перевел его на C # framework, который я использую. Однако по какой-то причине методы не запускаются, когда они являются событиями нажатия и нажатия клавиш с моей клавиатуры, когда я проверяю их с помощью точки останова?

2. Я не уверен, как преобразовать в Xamarin android. Вы можете проверить этот пример для справки: github.com/Vaikesh/CustomKeyboard

3. Я имею в виду и для обычного Android sdk, точки останова, которые я устанавливаю в Android studio, не попадают, когда я нажимаю кнопку вниз на клавиатуре, у вас такая же проблема? Кроме того, спасибо за эту ссылку

4. Привет, Конг. Пока нет, но, к счастью, это дало мне время поработать над другим нужным мне кодом

5. Привет, onGenericMotionEvent, onKeyDown и onKeyUp не вызываются ни на одном из моих вводов с клавиатуры / контроллера. Я подозреваю, что InputMethodService активен только тогда, когда он вызывается как ввод IME, например, в TextView. Я не уверен, что именно поэтому. Знаете ли вы, почему у меня это не работает?

Ответ №4:

Чтобы создать службу специальных возможностей, которая может сочетаться со службой методов ввода, вы можете попробовать следующий фрагмент:

 var tapService: TapService? = null

class TapService : AccessibilityService() {
    companion object {
        private const val TAG = "TapService"
    }

    override fun onAccessibilityEvent(event: AccessibilityEvent?) { }

    override fun onInterrupt() { }

    override fun onServiceConnected() {
        super.onServiceConnected()
        Log.d(TAG, "onServiceConnected")

        tapService = this

        startActivity(Intent(this, MainActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
    }

    override fun onUnbind(intent: Intent?): Boolean {
        Log.d(TAG, "onUnbind")
        tapService = null
        return super.onUnbind(intent)
    }

    override fun onDestroy() {
        Log.d(TAG, "onDestroy")
        tapService = null
        super.onDestroy()
    }

    fun tap(x: Int, y: Int, hold: Boolean) {
        // create path and build the GestureDescription then dispatch it
    }

    fun swipe(fromX: Int, fromY: Int, toX: Int, toY: Int, duration: Long) {
        // similar to tap function
    }
}
 

когда пользователь запускает TapService в меню настройки специальных возможностей, он вызывает функцию onServiceConnected и назначает объект tapService службе.

Следовательно, вы можете вызвать метод tapService.tap() или tapService.swipe() в другом месте службы методов ввода, чтобы ввести действие касания.

Однако из-за ограничений службы специальных возможностей имитация сенсорного действия не соответствует ожиданиям.