我正在尝试在 android 中创建自己的位置提供程序,以在系统中注入我自己的定位数据。为此,我在系统中重用 LocationManager 函数,在那里注册一个我希望被调用的侦听器,但它并不总是被调用。我已经做了一些研究,但我无法弄清楚系统用来触发事件的模式,而且谷歌也没有大量的官方文档。
请注意,我不使用系统中的任何位置提供程序(GPS、网络...)。我创建自己的坐标和时间戳并将其发布在假位置提供程序中,所以几乎所有关于这个问题的问题都与这个问题略有不同(所以与 GPS 无关,无论我是否在移动,最小距离范围...)。
在这里,我向您展示代码和生成的日志。您可以很容易地看到某些事件永远不会被触发(例如启用了 onProvider)、在不应该触发时触发(onProviderDisbled)或在错误的时间触发(例如 onStatusChanged,仅在状态更改和位置更改之后触发)。
这是主要代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lm = (LocationManager) getSystemService(Service.LOCATION_SERVICE);
if (!isMockLocationSet()) {
throw new RuntimeException("Mock Locations are disabled!");
}
// 1. Generate a valid random name for the mock provider
providerName = this.generateValidProviderName();
// 2. Create the mock provider
System.out.println("Step 2: Create provider (" + providerName + ")");
try {
if (lm.getProvider(providerName) == null) {
throw new IllegalArgumentException();
}
} catch (IllegalArgumentException e) {// Doesn't exist, create
lm.addTestProvider(providerName, false, false, false, false, false,
false, false, Criteria.POWER_MEDIUM, Criteria.ACCURACY_HIGH);
}
// 3. Register for updates
System.out.println("Step 3: Register for updates");
MyLocationListener l = new MyLocationListener();
lm.requestLocationUpdates(providerName, 0, 0, l);
MyAsyncTask task = new MyAsyncTask();
task.execute();
}
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
Location loc = new Location(providerName);
// 4. Enable it!
System.out.println("Step 4: Enable it");
lm.setTestProviderEnabled(providerName, true);
// 5. Change the status
System.out.println("Step 5: Change the status to AVAILABLE");
lm.setTestProviderStatus(providerName, LocationProvider.AVAILABLE,
null, System.currentTimeMillis());
// 6. Change the status
System.out
.println("Step 7: Change the status to TEMPORARILY_UNAVAILABLE");
lm.setTestProviderStatus(providerName,
LocationProvider.TEMPORARILY_UNAVAILABLE, null,
System.currentTimeMillis());
// 7.1. Change location
System.out.println("Step 7.1: Change Location");
loc.setTime(System.currentTimeMillis());
loc.setLatitude(52.0f);
loc.setLongitude(10.0f);
lm.setTestProviderLocation(providerName, loc);
// 7.2. Change location
System.out.println("Step 7.2: Change Location");
loc.setTime(System.currentTimeMillis());
loc.setLatitude(52.1f);
loc.setLongitude(10.1f);
lm.setTestProviderLocation(providerName, loc);
// 7.3. Change the status
System.out.println("Step 7.3: Change the status to AVAILABLE");
lm.setTestProviderStatus(providerName, LocationProvider.AVAILABLE,
null, System.currentTimeMillis());
// 7.4. Change location
System.out.println("Step 7.4: Change Location");
loc.setTime(System.currentTimeMillis());
loc.setLatitude(52.2f);
loc.setLongitude(10.2f);
lm.setTestProviderLocation(providerName, loc);
// 7.5. Change the status
System.out.println("Step 7.5: Change the status to OUT_OF_SERVICE");
lm.setTestProviderStatus(providerName,
LocationProvider.OUT_OF_SERVICE, null,
System.currentTimeMillis());
// 7.6. Change location
System.out.println("Step 7.6: Change Location");
loc.setTime(System.currentTimeMillis());
loc.setLatitude(52.3f);
loc.setLongitude(10.3f);
lm.setTestProviderLocation(providerName, loc);
try {
// 8. Delete provider
System.out.println("8. Delete provider");
lm.setTestProviderEnabled(providerName, false);
lm.removeTestProvider(providerName);
} catch (IllegalArgumentException e) {
}
return null;
}
}
这里是日志的输出:
07-26 11:31:21.271: I/System.out(8721): Step 2: Create provider (Fake_GPS_92A4)
07-26 11:31:21.271: I/System.out(8721): Step 3: Register for updates
07-26 11:31:21.276: I/System.out(8721): Step 4: Enable it
07-26 11:31:21.276: I/System.out(8721): Step 5: Change the status to AVAILABLE
07-26 11:31:21.276: I/System.out(8721): Step 7: Change the status to TEMPORARILY_UNAVAILABLE
07-26 11:31:21.276: I/System.out(8721): Step 7.1: Change Location
07-26 11:31:21.291: I/System.out(8721): Step 7.2: Change Location
07-26 11:31:21.301: D/MainActivity(8721): onProviderDisabled
07-26 11:31:21.306: I/System.out(8721): Step 7.3: Change the status to AVAILABLE
07-26 11:31:21.306: I/System.out(8721): onLocationChanged
07-26 11:31:21.306: D/MainActivity(8721): onStatusChanged: TEMPORARILY_UNAVAILABLE
07-26 11:31:21.306: I/System.out(8721): Step 7.4: Change Location
07-26 11:31:21.306: I/System.out(8721): Step 7.5: Change the status to OUT_OF_SERVICE
07-26 11:31:21.356: I/System.out(8721): Step 7.6: Change Location
07-26 11:31:21.361: I/System.out(8721): 8. Delete provider
07-26 11:31:21.401: I/System.out(8721): onLocationChanged
07-26 11:31:21.401: I/System.out(8721): onLocationChanged
07-26 11:31:21.436: D/MainActivity(8721): onStatusChanged: AVAILABLE
当然,这不是权限问题:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
我在这个问题上花了很多时间,并将代码简化为最低限度的表达,所以我希望你至少可以看看。
谢谢!