android - monkeyrunner 在构造 shell 命令时不能正确处理特定字符

标签 android monkeyrunner

理想情况下,要打开默认浏览器并导航到 Google map (对于台北 101),您只需执行:

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

但是,该语句并不(始终)有效。追踪 monkeyrunner 的源代码后:

这是一个 fragment ,显示 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    }

对于这种情况,将执行以下 shell 命令。

$ 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

您可能会发现根本原因是与号 (&)。它在shell环境中被特殊解释,即在后台执行前面的命令。

为避免这种误解,我们可以通过在其前面加上\来转义该特殊字符。

$ 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,应该在内部进行这种转义。你怎么看?

最佳答案

是的,你完全正确。我发现规避这个其他麻烦的方法是使用

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

至少您知道会发生什么。

关于android - monkeyrunner 在构造 shell 命令时不能正确处理特定字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13193555/

相关文章:

android - 应用程序 :mergeTestReleaseResourcesAAPT err(Facade for 495460572) :

android - 如何将缺少的模块导入 monkeyrunner 脚本?

python - MonkeyRunner::如何安装 python 模块?

AndroidViewClient 删除包和 broadcastreceiver

android - MonkeyRunner:更可靠的等待和全长截图?

java - 如何使用模型实现简单的 REST 和 ContentProvider 架构?

android - NoClassDefFoundError 与 Kotlin 中的 ?.let{} block

android - 未处理的异常 : MissingPluginException(No implementation found for method getBatteryLevel on channel *) with flutter1. 12

android - 在android应用程序中存储多个用户数据的最佳方式