monkeyrunner неправильно обрабатывает определенные символы при построении команд оболочки

В идеале, чтобы открыть браузер по умолчанию и перейти к Google Maps (для Тайбэя 101), вы можете просто выполнить:

startActivity(action='android.intent.action.VIEW', data='http://maps.google.com/?q=25.033611,121.565000&z=19')

Однако это утверждение не (всегда) работает. После отслеживания исходных кодов monkeyrunner:

Вот фрагмент, который показывает, что внутри monkeyrunner просто буквально объединяет параметры. Пожалуйста, сосредоточьтесь на #388 и #411.

383    public void startActivity(String uri, String action, String data, String mimetype,
384            Collection<String> categories, Map<String, Object> extras, String component,
385            int flags) {
386        List<String> intentArgs = buildIntentArgString(uri, action, data, mimetype, categories,
387                extras, component, flags);
388        shell(Lists.asList("am", "start",
389                intentArgs.toArray(ZERO_LENGTH_STRING_ARRAY)).toArray(ZERO_LENGTH_STRING_ARRAY));
390    }
...
406    private List<String> buildIntentArgString(String uri, String action, String data, String mimetype,
407            Collection<String> categories, Map<String, Object> extras, String component,
408            int flags) {
409        List<String> parts = Lists.newArrayList();
410
411        // from adb docs:
412        //<INTENT> specifications include these flags:
413        //    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
414        //    [-c <CATEGORY> [-c <CATEGORY>] ...]
415        //    [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
416        //    [--esn <EXTRA_KEY> ...]
417        //    [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
418        //    [-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
419        //    [-n <COMPONENT>] [-f <FLAGS>]
420        //    [<URI>]
421
422        if (!isNullOrEmpty(action)) {
423            parts.add("-a");
424            parts.add(action);
425        }
426
427        if (!isNullOrEmpty(data)) {
428            parts.add("-d");
429            parts.add(data);
430        }
...
479        return parts;
480    }

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

$ am start -a android.intent.action.VIEW -d http://maps.google.com/?q=25.033611,121.565000&z=19
$ Starting: Intent { act=android.intent.action.VIEW dat=http://maps.google.com/?q=25.033611,121.565000 }

[1]   Done                    am start -a android.intent.action.VIEW -d http://maps.google.com/?q=25.033611,121.565000

Вы можете обнаружить, что основной причиной является амперсанд (&). Это специально интерпретируется в среде оболочки, которая выполняет предыдущую команду в фоновом режиме.

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

$ am start -a android.intent.action.VIEW -d http://maps.google.com/?q=25.033611,121.565000\&z=19
Starting: Intent { act=android.intent.action.VIEW dat=http://maps.google.com/?q=25.033611,121.565000&z=19 }

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

startActivity(action='android.intent.action.VIEW', data=r'http://maps.google.com/?q=25.033611,121.565000\&z=19')

Наконец-то это работает!! Тем не менее, я думаю, что monkeyrunner, как дружественный API, должен делать это внутри. Как ты думаешь?


person Jeremy Kao    schedule 02.11.2012    source источник


Ответы (1)


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

device.shell('am start ...')

где, по крайней мере, вы знаете, чего ожидать.

person Diego Torres Milano    schedule 03.11.2012
comment
да. Тем не менее, это похоже на обходной путь, чтобы немедленно вернуться к использованию команд оболочки. Должен быть кто-то еще сталкивается с этой проблемой. Вы знаете, где я могу официально подать заявку? - person Jeremy Kao; 04.11.2012