LoginSignup
2
0

More than 5 years have passed since last update.

LollipopでMapboxのLocationLayerPluginが動作しない

Posted at

なぜか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 で動かない理由は調べてません。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0