システムに独自の測位データを挿入するために、Android で独自のロケーション プロバイダーを作成しようとしています。そのために、システムで LocationManager 関数を再利用し、呼び出されると予想されるリスナーをそこに登録していますが、常に呼び出されるとは限りません。私はいくつかの調査を行いましたが、システムがイベントをトリガーするために使用するパターンを理解できず、Google からの広範な公式文書もありません。
システム (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" />
私はその問題に多くの時間を費やし、コードを最小限の式に単純化したので、少なくとも見ていただければ幸いです。
ありがとう!