您如何在Android中测试 GPS 应用程序?我们可以使用Android 模拟器对其进行测试吗?
6 回答
是的。
如果您使用 Eclipse ADT 插件进行开发,请在启动模拟器后打开 DDMS 透视图并查找 Emulator Control 视图。有一个位置控制部分允许您发送固定的纬度和经度坐标,或者如果您想定期发送多个坐标(以模拟特定路线的行驶),则可以发送 GPX(GPS 交换格式)或 KML(钥匙孔标记语言)文件.
或者,您可以简单地 telnet 到模拟器并从命令行使用 geo 命令,该命令支持固定的经纬度坐标以及 NMEA 数据语句:
telnet localhost 5554
geo fix -82.411629 28.054553
geo nmea $GPGGA,001431.092,0118.2653,N,10351.1359,E,0,00,,-19.6,M,4.1,M,,0000*5B
也许你想使用单元测试,所以你可以试试这个:
public class GPSPollingServiceTest extends AndroidTestCase {
private LocationManager locationManager;
public void testGPS() {
LocationManager locationManager = (LocationManager) this.getContext().getSystemService(Context.LOCATION_SERVICE);
locationManager.addTestProvider("Test", false, false, false, false, false, false, false, Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
locationManager.setTestProviderEnabled("Test", true);
// Set up your test
Location location = new Location("Test");
location.setLatitude(10.0);
location.setLongitude(20.0);
locationManager.setTestProviderLocation("Test", location);
// Check if your listener reacted the right way
locationManager.removeTestProvider("Test");
}
}
为此,您还需要 AndroidManifest.xml 所需的权限:
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
除了 Mallox 代码之外,这是除了真实 gps 位置之外的模拟位置:TEST_MOCK_GPS_LOCATION 是一个字符串
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = null;
List providers = lm.getAllProviders();
for (Object provider : providers) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location loc = lm.getLastKnownLocation((String) provider);
if (provider.equals(TEST_MOCK_GPS_LOCATION)) {
mLastLocation = loc;
}
}
在测试类中是:
public class GPSPollingServiceTest extends AndroidTestCase {
private LocationManager locationManager;
public void testGPS() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
LocationManager locationManager = (LocationManager) this.getContext().getSystemService(Context.LOCATION_SERVICE);
List providers = locationManager.getAllProviders();
if(!providers.contains(TEST_MOCK_GPS_LOCATION)) {
locationManager.addTestProvider(TEST_MOCK_GPS_LOCATION, false, false, false, false, false, false, false, Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
locationManager.setTestProviderEnabled(TEST_MOCK_GPS_LOCATION, true);
// Set up your test
Location location = new Location(TEST_MOCK_GPS_LOCATION);
location.setLatitude(34.1233400);
location.setLongitude(15.6777880);
location.setAccuracy(7);
location.setTime(8);
location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
locationManager.setTestProviderLocation(TEST_MOCK_GPS_LOCATION, location);
Method locationJellyBeanFixMethod = Location.class.getMethod("makeComplete");
if (locationJellyBeanFixMethod != null) {
locationJellyBeanFixMethod.invoke(location);
}
} else {
// Check if your listener reacted the right way
locationManager.removeTestProvider(TEST_MOCK_GPS_LOCATION);
}
}
}
希望对你有帮助
在模拟器的扩展控件中(单击模拟器旁边控制栏上的“...”)有位置选项卡,您可以在其中手动输入各个位置(纬度/经度/高度)并将它们发送到虚拟设备,或从您可以导入的 GPX 或 KML 文件中以所需的速度设置 GPS 数据播放。
编辑:这是我正在谈论的默认 Android 模拟器。
我建议您编写将位置对象发送到您要测试的侦听器类的测试。考虑到这一点,您将需要一些能够生成位置对象的辅助方法。
例如:
首先,您发送一个具有固定坐标的位置(例如纽约中心)。
// 测试是否一切正常
比你发送一个距离第一个坐标 100m 的坐标。您可以使用我最近实现的功能来做到这一点:https ://stackoverflow.com/a/17545955/322791
// 测试是否一切正常
GPS方法通常与时间有关。我建议您在侦听器类上实现方法 getNow() 并在需要当前时间时调用它。
long getNow() {
if (isUnitTesting) {
return unitTestTime;
} else {
System.getcurrenttimemillis();
}
}
在单元测试环境中,您只需将 obj.isUnitTesting=true 和 obj.unitTestTime 设置为您想要的任何时间。之后,您可以将第一个位置发送给侦听器,然后更改时间(+x 秒)并发送另一个位置...
以这种方式测试您的应用程序会容易得多。