【问题标题】:How to programmatically send GPS location to an Android Studio 2.0 AVD如何以编程方式将 GPS 位置发送到 Android Studio 2.0 AVD
【发布时间】:2016-10-06 17:54:00
【问题描述】:

我有一个使用 Android Studio 2.1.1 创建的 x86 API23 AVD(带有 Google API),我需要向其发送 GPS 坐标。我已经广泛阅读了有关使用命令行中的“adb emu geo fix”命令或通过 telnet 执行此操作的内容——在进行身份验证后,然后在命令中发送 geo fix 命令以及纬度、经度和可选的高度参数也行。

我在 Mac OSX El Capitan 机器上运行我的代码。

问题在于,我的应用程序(需要为我发送的 GPS 坐标提供数据的应用程序)表现得好像没有获取任何数据一样。

如果我使用 AVD 本身的扩展控件通过 SEND 按钮发送相同的当前位置,或者播放从 .gpx 文件加载的路线数据,那么一切正常。该应用程序获取 GPS 数据并按预期运行。

问题是我正在运行测试自动化(Appium、Java、TestNG),它需要启动 AVD,然后发送 GPS 数据,然后验证我的被测应用在输入正确 GPS 时的行为是否符合预期数据。

这意味着我无法手动与 AVD 的扩展手动控件交互。

我必须以编程方式完成这一切。

这就是我现在通过 Telnet 命令所做的事情。代码看起来基本上是这样的,只发送一个“当前位置”:

import org.apache.commons.net.telnet.TelnetClient;

static TelnetClient tc = null;

    public InputStream inptStream;
    public PrintStream outptStream;
    public String prompt = "OK";

//Instantiate the telnet client -- we use this to send geo fix commands to the emulator
            tc = new TelnetClient();

//Connect, this will generate the auth_token if it does not already exist in file system
                System.out.println("Trying to connect to AVD...");
                tc.connect("localhost", 5554);

//Check to see if we are connected
                Boolean areWeConn = tc.isConnected();
                System.out.println("Are we connected?" + areWeConn);

// Get input and output stream references
                System.out.println("Getting input and output streams...");
                inptStream = tc.getInputStream();
                outptStream = new PrintStream(tc.getOutputStream());

                //wait for OK prompt
                System.out.println("Waiting for the OK prompt...");
                //Not including readUntil() code because it's just reading  terminal output
                readUntil(prompt);

                //Send the auth token number
                System.out.println("Sending auth token...");
                outptStream.println("auth " + "3A/Yfazi3pRcvNiB");
                outptStream.flush();

                //wait for OK prompt
                System.out.println("Waiting for the OK prompt...");
                readUntil(prompt);

                //Send current location for our Starting Point
                System.out.println("Sending Current Location - Starting Point");
                outptStream.println("geo" + "fix" + "28.4194 -81.5812");
                outptStream.flush(); 

//Now disconnect from Telnet
                System.out.println("Disconnecting from AVD...");
                tc.disconnect();

//Check to see if we are still connected
                Boolean stillConn = tc.isConnected();
                System.out.println("Are we still connected? " + stillConn);

当上述代码未能触发我的应用程序中的预期行为时,即使它看起来完全没有任何错误,我使用终端启动 AVD 并运行我的应用程序,然后使用另一个终端在 Telnet OK 提示符下使用以下命令(通过身份验证后)手动发送“当前位置”:

telnet localhost 5554

等待确定...

然后通过发送身份验证令牌手动进行身份验证...

等待OK,然后发送:

geo fix "28.4194 -81.5812"

此命令在提示符下似乎运行良好(没有错误),但我的应用显然没有获得任何 GPS 信息。

所以,我尝试使用上述命令的 adb 版本,它的工作原理如下:

adb emu geo fix "28.4194 -81.5812"

但这也失败了。

同样,使用 Appium 自己的 Android 驱动程序,我尝试了以下操作(当然是在创建驱动程序之后):

Location currLocation = new Location(28.41936, -81.5812, 0.0);

            //Set Current Location for
            myDriver.setLocation(currLocation);

但驱动程序似乎在这里“挂起”。我无法获得任何调试输出。它只是......阻塞,直到事情最终超时。

而且,我也用谷歌地图移动应用尝试了上述所有方法,但它也无法对我发送的当前位置坐标做出反应。

所以,我被卡住了!

在使用 Android Studio 2+ 创建的 API23 AVD 上,是否有人真正幸运地以编程方式向他们正在测试的应用发送“geo fix”命令?

Android Studio 2.0 之前的版本创建的 AVD 不能用于我的目的。

任何关于我做错了什么或可能的解决方法的反馈将不胜感激!

谢谢,

乌尔夫

【问题讨论】:

    标签: android gps geolocation appium telnet


    【解决方案1】:

    所以,信不信由你,先发送经度,然后发送纬度,如下所示:

    geo fix "-81.5812 28.4194"
    

    geo fix 命令对我有用!

    因此,修正后的代码如下所示:

    //Send current location for our Starting Point
                    System.out.println("Sending Current Location - Starting Point");
                    outptStream.println("geo fix -81.5812 28.4194");
                    outptStream.flush(); 
    

    呃……要弄清楚这一点,兄弟。天...

    我无法让“adb emu geo fix”命令在我的代码中工作,所以我使用上面的直接“geo fix”命令,这非常适合设置“当前位置”。

    但是,“geo fix”命令似乎不适用于我创建我的应用程序绘制到地图的路线。我有一个简单的坐标数组——现在所有的坐标都得到了修正,然后给出了长,然后我循环播放它们——但这并不能给我一个在我的应用程序中遵循的 ROUTE。

    关于 Android Studio 2.0 中的扩展控件如何将 .gpx 坐标发送到模拟器,以便应用程序将这个信息流作为 ROUTE 读取,而不是一个一个标记的单个当前位置,有什么想法吗?

    我希望这是有道理的。

    ****2016 年 6 月 20 日更新 ****

    所以,上述问题的前提是错误的。在发布上述关于发送“路线”而不是“当前位置”的查询后不久,我发现使用“geo fix”命令逐个发送的一系列位置确实适用于我的应用程序,并且路线显示在我的应用程序的地图就好了!我犯了两个大错误。首先,我一次将整个阵列发送到我的循环,而不是一次发送一个位置命令。第二,在发送下一个“geo fix”命令之前,在发送每个“geo fix”命令之后,我的代码没有等待 Telnet 会话返回“OK”提示。一旦我纠正了这些问题,事情就开始完美了!

    【讨论】:

      【解决方案2】:

      尝试清除此文件:~/.emulator_console_auth_token(或创建一个空文件)


      我也有同样的情况。但是,我发现了一些可能有帮助的东西。在模拟器 25.1.6 的最新版本中,auth 命令现在是使用 Telnet 时必须发出的第一个命令。

      http://tools.android.com/recent/emulator2516releasenotes

      因此,要禁用它,您可以将 ~/.emulator_console_auth_token 设为空文件。这似乎修复了 adb 使用,例如 adb emu geo fix X Y

      我怀疑 adb 没有发出此 auth 命令,并且更愿意使用安全方法。所以我还在研究。

      此外,我还没有尝试过所有场景,但我还在 AVD 设置 > 位置 > 模式中启用了高模式,这样就可以使用 Google 定位服务。

      我测试的方式: 1.清除.emulator_console_auth_token 2. 启动模拟器(API 23, x86_64 qemu) 3.打开谷歌地图应用 4.它被缩小表明它没有位置 5. adb emu 地理修复 37 -122 6. 地图放大位置。

      我希望这会有所帮助。

      【讨论】:

      • 您好 Gilgeson,感谢您的反馈!下次有机会我会试试你的空令牌技巧!但是,在我已经连接了有效的身份验证令牌后,我在代码中使用了 ADB 命令,但它们似乎仍然无法正常工作。不过我本可以做点什么。
      • 酷我很高兴你弄清楚了发送位置和路线!还要感谢纬度/经度的反转。我会检查一下,也许它会让我继续使用身份验证。最后一件事,我在上面注意到您在 adb 的 lat/long 周围使用双引号,但是当我让它工作时,我不会将它们放在双引号中,就像单独的值一样: adb emu geo fix 28.4194 -81.5812 Let我知道这是否对 adb 有帮助
      猜你喜欢
      • 2018-03-28
      • 2015-06-24
      • 2011-06-12
      • 1970-01-01
      • 1970-01-01
      • 2016-06-24
      • 2013-08-13
      • 2012-05-05
      • 2017-03-27
      相关资源
      最近更新 更多