Android MockLocation testProvider不调用onLocationChanged
我的目标是GoogleAPI2.3.3,有以下测试类Android MockLocation testProvider不调用onLocationChanged,android,android-emulator,Android,Android Emulator,我的目标是GoogleAPI2.3.3,有以下测试类 import android.content.Context; import android.location.Criteria; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationProvider
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.util.Log;
public class MockLocationManagerTests extends AndroidTestCase implements LocationListener{
private static final String TAG = "MockLocationTests";
private String locationProvider = "TestProvider";
private LocationManager locationManager;
private Location lastLocation;
protected void setUp() throws Exception {
super.setUp();
locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
if (Settings.Secure.getInt(getContext().getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 0) {
fail("Mock location must be enabled");
}
setupLocationManager();
}
private void setupLocationManager() {
if (locationManager.getProvider(locationProvider) != null) {
locationManager.removeTestProvider(locationProvider);
}
locationManager.addTestProvider(locationProvider,
false,
true,
false,
false,
false,
false,
false,
Criteria.POWER_LOW,
Criteria.ACCURACY_FINE);
locationManager.requestLocationUpdates(locationProvider, 0, 0, this);
locationManager.setTestProviderStatus(locationProvider, LocationProvider.AVAILABLE, null, System.currentTimeMillis());
locationManager.setTestProviderEnabled(locationProvider, true);
}
private Location createLocation(double lat, double lon) {
Location location = new Location(locationProvider);
location.setLatitude(lat);
location.setLongitude(lon);
location.setAltitude(0);
location.setTime(System.currentTimeMillis());
return location;
}
protected void tearDown() throws Exception {
super.tearDown();
}
public final void testCanObserveLocationChanging() throws InterruptedException {
Location l = createLocation(19,-2);
locationManager.setTestProviderLocation(locationProvider,l);
synchronized(this){
wait(5000);
}
Location l2 = createLocation(1,-10);
locationManager.setTestProviderLocation(locationProvider,l2);
synchronized(this){
wait(5000);
}
assertEquals(l,lastLocation);
}
public void onLocationChanged(Location location) {
Log.i(TAG,"location changed");
lastLocation = location;
}
public void onProviderDisabled(String provider) {
Log.i(TAG, provider+" disabled");
}
public void onProviderEnabled(String provider) {
Log.i(TAG, provider+" enabled");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.i(TAG,"status changed: "+provider+" to "+status);
}
}
没有人打电话给我,我的谷歌搜索引擎和脑力搜索引擎让我失望。非常感谢您的任何建议
更新
没有捕获任何日志消息,因此onStatusChanged和onProviderEnabled没有触发
如果在调用setTestProviderLocation()
之间调用getLastKnownLocation()
,locationManager将返回我设置的位置
另一次更新
如果我将使用此代码的类添加到我的应用程序中,则会调用onLocationChanged()。
唯一的区别是我没有使用模拟位置。
因此,似乎setTestProviderLocation()并没有导致onLocationChanged()触发您是否在手机或模拟器上启用了模拟位置?
在应用程序/开发/模拟位置中有一个设置。只需单击eclipse的emulator控件选项卡上的“发送”即可将坐标发送到应用程序。在Google API 19上的行为方式相同 AndroidTestCase没有为处理更新事件设置适当的循环器。您必须将其作为测试活动ActivityInstrumentationTestCase2运行,或者向AndroidTestCase添加ThreadLooper以处理更新消息
Looper mLooper;
HandlerThread thread = new HandlerThread("LocationHandlerThread");
thread.start(); // starts the thread.
mLooper = thread.getLooper();
然后在requestLocationUpdates方法中使用新的循环器:
mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, mLocationListener, mLooper);
您使用的是模拟器还是手机?我也看不出有什么不对劲。我假设您已经添加了
权限这是在使用emulator,是的,您已经设置了模拟位置权限。它已启用是的。我认为这是一个错误,setTestProviderLocation没有调用onLocationChanged,因为测试中的类与在模拟器上工作时的类完全相同。它只有在从测试运行时才“工作”。我正在尝试设置自动测试。后来我开始使用robolectric和roboguice,所以我从未真正解决过这个问题