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

Я разрабатываю приложение, такое как приложение VoiceAccess. Используя службу специальных возможностей, я могу выполнять все клики, которые находятся в верхней части активности (сторонние приложения). Но у меня проблема с кликами ListItem. Я пробую этот код для приложения FaceBook. ниже мой код. Может ли кто-нибудь помочь мне в этом.

public class MyService extends AccessibilityService {

/**/
private SharedPreferences S_PREF;
private SharedPreferences.Editor editor;

private static final String TAG = MyService.class
        .getSimpleName();

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    clickPerform(getRootInActiveWindow(), 0);
}

public void clickPerform(AccessibilityNodeInfo nodeInfo, final int depth) {

    if (nodeInfo == null) return;

    List<AccessibilityNodeInfo> list = nodeInfo
            .findAccessibilityNodeInfosByViewId("com.facebook.katana:id/bookmarks_tab");
    for (AccessibilityNodeInfo node : list) {

        Log.i(TAG, "ViewID-: bookmarks_tab " + node.getChild(0));

        if (S_PREF.getBoolean("fb_menu", false)) {
            editor.putBoolean("fb_menu", false);
            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }
    }
    List<AccessibilityNodeInfo> list2 = nodeInfo
            .findAccessibilityNodeInfosByViewId("com.facebook.katana:id/bookmarks_list");
    for (AccessibilityNodeInfo node2 : list2) {
        if (node2.getChild(0) != null)
        if (S_PREF.getBoolean("fb_scroll_down", false)) {
            editor.putBoolean("fb_scroll_down", false);
            node2.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
        }
    }
    editor.commit();
    for (int i = 0; i < nodeInfo.getChildCount(); ++i) {
        clickPerform(nodeInfo.getChild(i), depth+1);
    }
}



@Override
public void onInterrupt() {

}

protected void onServiceConnected() {
    S_PREF = getSharedPreferences("S_PREF", Context.MODE_PRIVATE);
    editor = S_PREF.edit();
    AccessibilityServiceInfo info = new AccessibilityServiceInfo();
    info.flags = AccessibilityServiceInfo.DEFAULT;
    info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED | AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
    setServiceInfo(info);
    Toast.makeText(getApplicationContext(), "onServiceConnected", Toast.LENGTH_SHORT).show();
     }
}

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

Я могу получить 7,8,9,10 событий, но начиная с 11 я не получаю элементы списка по отдельности. Мой код возвращает только идентификатор списка.

Заранее спасибо....


person BHARADWAJ Marripally    schedule 31.08.2017    source источник
comment
Но у меня возникла проблема с кликами ListItem Как минимум, вам нужно объяснить, в чем проблема... т.е. (a) что именно вы делаете (я бы угадай произнесите число от 11 до 20, но будьте точны); (b) именно то, что вы ожидаете/надеетесь, что он будет делать; и (c) именно то, что он делает (и если это ничего, скажите об этом явно).   -  person TripeHound    schedule 31.08.2017
comment
проблема в том, что я могу получить идентификатор списка, но не идентификатор элемента списка/размер списка и т. д. Если мы хотим выполнить щелчок по элементу, мы должны знать положение элемента списка или точное представление. Так что только мы можем выполнить щелчок по выбранному элементу. Я не понимаю, как получить представление этого элемента списка. на изображении выше, если мы скажем 11, этот конкретный элемент щелкнет, например, Instagram откроется в браузере и т. д. Вот так я должен выполнять программно... спасибо за ответ...   -  person BHARADWAJ Marripally    schedule 31.08.2017
comment
вы нашли решение для этого? Я столкнулся с той же проблемой   -  person steveen zoleko    schedule 26.12.2017


Ответы (2)


@steveenzoleko

Я нашел решение этой проблемы самостоятельно. Здесь AccessibilityNodeInfo всегда не возвращает полный список или размер списка. Он возвращает VIEW. Это может быть TextView, Button и т. д. Каждое представление имеет несколько методов, таких как getText(), getContentDescription(), getClassName(), getChildCount(), getViewIdResourceName() и т. д. … здесь приложение голосового доступа обнаруживает все представления и дает им некоторые числа. Для списков, используя метод getChildCount() в цикле for, мы можем получитьChildViews/listItems. Бывший:

AccessibilityNodeInfo node = getRootInActiveWindow();
if(node != null) {
   for(int i = 0; i < node.getChildCount(); i++){
      AccessibilityNodeInfo childNode = node.getChild(i);
      if(childNode != null){
        Log.i("childNode", "-----getText->"+childNode.getText()+"---getContentDescription-->"+childNode.getContentDescription() );
      }
   }
}

используйте методы getText() и getContentDescription(), чтобы узнать текст textview, кнопки, флажка.

Метод getClassName() повторно настраивает тип представления, такой как TextView, Button, ImageView, CheckBox и т. д.

person BHARADWAJ Marripally    schedule 26.12.2017
comment
Можете ли вы ответить на этот вопрос stackoverflow.com/q/49734263/4813904 - person Siva; 09.04.2018
comment
@BHARADWAJ Marripally: у меня та же проблема, что и у вас, с элементами из определенных списков. К сожалению, я не могу отправить щелчок с помощью childNode.performAction(AccessibilityNodeInfo.ACTION_CLICK), даже если я попытаюсь отправить щелчок в родительское представление, я не могу, потому что childNode.isClickable() возвращает false. Можете ли вы помочь мне с фрагментом или идеей ссылки? - person dole doug; 04.11.2019

Возможно, вы можете использовать dispatchGesture из AccessibilityService API 7.0.

person ekse    schedule 27.08.2020