なぜかLollipopでは自分の現在位置の表示ができませんでした。
試しにこんなコードを書いてみたところ、onConnectedは呼ばれるがやはりonLocationChangedは呼ばれない。
var locationEngine: LocationEngine? = null
fun startLocationEngine() {
locationEngine = LocationEngineProvider(mapView?.context).obtainBestLocationEngineAvailable()
info { "locationEngineType:${locationEngine?.javaClass?.simpleName}" }
locationEngine?.setPriority(LocationEnginePriority.LOW_POWER)
locationEngine?.setFastestInterval(1000)
locationEngine?.addLocationEngineListener(this)
locationEngine?.activate()
}
override fun onConnected() {
info { "onConnected" }
}
override fun onLocationChanged(location: Location?) {
info { "onLocationChanged:${location.toString()}" }
}
locationEngineType:AndroidLocationEngine
というLocationEngineが使われているようだ。
使用されるEngineは以下のように2種類あるらしい。
LocationEngineProvider.java
private Map<LocationEngine.Type, LocationEngineSupplier> obtainDefaultLocationEnginesDictionary() {
ClasspathChecker classpathChecker = new ClasspathChecker();
Map<LocationEngine.Type, LocationEngineSupplier> locationSources = new HashMap<>();
locationSources.put(LocationEngine.Type.GOOGLE_PLAY_SERVICES, new GoogleLocationEngineFactory(classpathChecker));
locationSources.put(LocationEngine.Type.ANDROID, new AndroidLocationEngineFactory());
return locationSources;
}
というわけでもう一つの方を試してみようと、タイプ指定でLocationEngineの取得を試みるも、なぜかnullになる。
locationEngine = LocationEngineProvider(mapView?.context).obtainLocationEngineBy(LocationEngine.Type.GOOGLE_PLAY_SERVICES)
どうやら、locationEngineSupplier.hasDependencyOnClasspath
の分岐で除外されているようだ。
LocationEngineProvider.java
private void initAvailableLocationEngines(Context context) {
locationEngineDictionary = new HashMap<>();
Map<LocationEngine.Type, LocationEngineSupplier> locationEnginesDictionary =
obtainDefaultLocationEnginesDictionary();
for (Map.Entry<LocationEngine.Type, LocationEngineSupplier> entry : locationEnginesDictionary.entrySet()) {
LocationEngineSupplier locationEngineSupplier = entry.getValue();
if (locationEngineSupplier.hasDependencyOnClasspath()) {
LocationEngine available = locationEngineSupplier.supply(context);
locationEngineDictionary.put(entry.getKey(), available);
}
}
}
実装はこんな感じになっていて、クラスの名前解決ができないと使用されないらしい。
class GoogleLocationEngineFactory implements LocationEngineSupplier {
private static final String GOOGLE_LOCATION_SERVICES = "com.google.android.gms.location.LocationServices";
private final ClasspathChecker classpathChecker;
GoogleLocationEngineFactory(ClasspathChecker classpathChecker) {
this.classpathChecker = classpathChecker;
}
@Override
public LocationEngine supply(Context context) {
return GoogleLocationEngine.getLocationEngine(context);
}
@Override
public boolean hasDependencyOnClasspath() {
return classpathChecker.hasDependencyOnClasspath(GOOGLE_LOCATION_SERVICES);
}
}
build.gradleにおなじみのimplementationを追記してビルドすることで、GoogleLocationEngineが使用されるようになり、無事に現在地が表示されるようになりました。
build.gradle
implementation "com.google.android.gms:play-services-location:16.0.0"
ちなみに AndroidLocationEngine で動かない理由は調べてません。