Как использовать делегат доступности для настройки речи?

Я хотел бы использовать AccessibilityDelegateCompatотрегулировать содержание AccessibilityEvent,

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

Это полный код

@Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_more, container, false);

        ViewCompat.setAccessibilityDelegate(mProfilePic,new AccessibilityDelegateCompat(){
            @Override
            public void sendAccessibilityEvent(View host, int eventType) {
                super.sendAccessibilityEvent(host, eventType);
            }

            @Override
            public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) {
                event.getText().add("TEST");
                super.sendAccessibilityEventUnchecked(host, event);
            }

            @Override
            public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
                event.getText().add("TEST");
                return super.dispatchPopulateAccessibilityEvent(host, event);
            }

            @Override
            public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
                event.getText().add("TEST");
                super.onPopulateAccessibilityEvent(host, event);
                event.getText().add("TEST");
            }

            @Override
            public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
                event.getText().add("TEST");
                super.onInitializeAccessibilityEvent(host, event);
            }

            @Override
            public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
                super.onInitializeAccessibilityNodeInfo(host, info);
            }

            @Override
            public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, AccessibilityEvent event) {
                event.getText().add("TEST");
                return super.onRequestSendAccessibilityEvent(host, child, event);
            }

            @Override
            public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View host) {
                return super.getAccessibilityNodeProvider(host);
            }

            @Override
            public boolean performAccessibilityAction(View host, int action, Bundle args) {
                return super.performAccessibilityAction(host, action, args);
            }
        });

        return view;
    }

Как видно, я пытался добавить свой контент в разных местах. Обратите внимание, что mProfilePic имеет описание содержимого, установленное в XML. Я хотел бы добавить к существующему описанию контента, но в коде.

1 ответ

Решение

Получил решение, которое, кажется, работает. Я протестировал это на Nexus 6p с Google Talkback и Samsung S7 с использованием Samsung Voice.

    ViewCompat.setAccessibilityDelegate(mProfilePic, new AccessibilityDelegateCompat() {

     private boolean didPerformAccessibilityAction = false

     @Override
     public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
      super.onInitializeAccessibilityNodeInfo(host, info);
      if (didPerformAccessibilityAction) {
       didPerformAccessibilityAction = false
       info.contentDescription = "MY NEW CONTENT"
      }
     }

     @Override
     public boolean performAccessibilityAction(View host, int action, Bundle args) {
      didPerformAccessibilityAction = super.performAccessibilityAction(host, action, args)
      return didPerformAccessibilityAction
     }
    });

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

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

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

Другие вопросы по тегам