Подтвердить что ты не робот

Неожиданные результаты из одного и того же ввода String

У меня есть BroadcastReceiver, который получает вход от внешнего источника.

Этот ресивер должен затем вести себя как "мышечная" программа и отправлять входные события в систему. У меня есть Root-доступ и разрешения.

Моя проблема в том, что когда я отправляю String, например "input tap 275 410", программа ведет себя корректно, если я даже разделяю строку, такую ​​как "input" + " tap" + " 275" + " 410", она все еще работает...

Однако, когда я собираю строку как желаемую:

"input " + CursorSystem.command + " " + coords[0] + " " + coords[1]

Тогда ничего не происходит... при отладке все наблюдаемые строки точно одинаковы (минус местоположение):

value = {char[26]@830031306976}  0 = 'i' 105 1 = 'n' 110 2 = 'p' 112 3 = 'u' 117 4 = 't' 116 5 = ' ' 32 6 = 't' 116 7 = 'a' 97 8 = 'p' 112 9 = ' ' 32 10 = '2' 50 11 = '7' 55 12 = '5' 53 13 = ' ' 32 14 = '4' 52 15 = '1' 49 16 = '0' 48 17 = '\u0000' 0 18 = '\u0000' 0 19 = '\u0000' 0 20 = '\u0000' 0 21 = '\u0000' 0 22 = '\u0000' 0 23 = '\u0000' 0 24 = '\u0000' 0 25 = '\u0000' 0

Мне хотелось бы, чтобы какое-то руководство или свойство учились, поскольку мои результаты не эффективны. Насколько я могу судить, это не проблема разрешения, и проблема с потоком, поскольку журналы показывают запрос разрешения (и грант), поток живет до тех пор, пока выполняется приемник (но если я отлаживать его слишком долго, затем он забирается через некоторое время [30 + секунд])

Receiver.onReceive:

public void onReceive(Context context, Intent intent) {
    String command = intent.getStringExtra("command");
    String touch = intent.getStringExtra("touch");
    if (Executor.isRootAvailable()) {
        Executor executor = new Executor();
        ArrayList<String> commands = new ArrayList<>();
        if (command != null) {
            if (command.length() > 0) {
                if (commands.add("input " + command)) {
                    executor.execute(commands);
                }
            }
        } else if (touch != null) {
            if (CursorSystem.isAlive) { // Always true for the executions
                CursorSystem.doInput();
                if (CursorSystem.state == CursorSystem.STATE) { // Always true for the executions
                    int[] coords = CursorSystem.coordinates;
                    if (coords != null) {
// This line is where (I guess) that the problem lies.
// CursorSystem.command is "tap", coords[0] and coords[1] is the result of (a view).getLocationOnScreen(coordinates)
// It results in a 2 positions int array with (x, y) coordinates, these values are always correct.
                        if (commands.add("input " + CursorSystem.command + " " + coords[0] + " " + coords[1])) {
                            executor.execute(commands);
                            CursorSystem.doInput();
                        } else {
                            // error...
                        }
                    } else {
                        // error...
                    }
                } else {
                    // error...
                }
            } else {
                error...
            }
        } else {
            error...
        }
    } else {
        error...
    }
}

Executor.execute:

public final boolean execute(ArrayList<String> commands) {
    boolean resp = false;
    try {
        if (commands != null && commands.size() > 0) {
            Process suProcess = Runtime.getRuntime().exec("su");
            DataOutputStream dataOutputStream = new DataOutputStream(suProcess.getOutputStream());
            for (String currCommand : commands) {
                dataOutputStream.writeBytes(currCommand);
                dataOutputStream.writeBytes("\n");
                dataOutputStream.flush();
            }
            dataOutputStream.writeBytes("exit\n");
            dataOutputStream.flush();
            try {
                int suProcessRetval = suProcess.waitFor();
                return (suProcessRetval != 255); // Always yields 0
            } catch (Exception ex) {
                // errors...
            }
        } else {
            // error...
        }
    } catch (IOException ex) {
        Log.w(TAG, "IOException: ", ex);
    } catch (SecurityException ex) {
        Log.w(TAG, "SecurityException: ", ex);
    } catch (Exception ex) {
        Log.w(TAG, "Generic Exception: ", ex);
    }
    return resp;
}
4b9b3361

Ответ 1

Для всех, кого это интересует:

Проблема заключалась в том, что CursorSystem использовал ImageViews, который помог пользователю "настроить", какое взаимодействие было желательным (и где). Во время выполнения команда может быть получена, и изображение будет перемещено туда, где будет выполняться команда, таким образом "получая" событие.

Добавление следующих флагов:

.LayoutParams.FLAG_NOT_FOCUSABLE
.LayoutParams.FLAG_NOT_TOUCHABLE
.LayoutParams.FLAG_LAYOUT_NO_LIMITS

Разрешено системе не рассматривать представления как интерактивные, а также "рисовать" их за пределами границ, чтобы пользователь мог "прокручивать" скрытые меню устройства, а также нажимать на цель, которая потенциально может НЕ существовать, Это заставило некоторые программы "Launcher" перехватить MotionEvent и ничего не делать.

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

Ответ 2

заменить

 if (commands.add("input " + CursorSystem.command + " " + coords[0] + " " + coords[1])) {
                            executor.execute(commands);
                            CursorSystem.doInput();
                        }

с

String newCommand = "input " + CursorSystem.command + " " + coords[0] + " " + coords[1];
newCommand = newCommand.replace("\u0000", "").replace("\\u0000", "");// removes NUL chars and backslash+u0000
if(commands.add(newCommand)){
   executor.execute(commands);
   CursorSystem.doInput();
   }