Androidアプリ開発時にGPSの位置情報を取得する場合、GPSやNETWORKのプロバイダを指定してrequestLocationUpdatesを呼び出し単独のプロバイダで位置情報を取得しますが、ここではGPSやNETWORKといった複数のプロバイダから同時に位置情報を取得する方法を紹介します。

GPSでもNETWORKでも、どっちでもいいから早く取得できた方の位置情報を使いたいといった考えのアプリとかだとこういった方法が使えるかと思います。

まずは位置情報を取得するproviderのリストを作る

まずは位置情報を取得するproviderのリストを作ります。Criteriaを指定して要求する精度から対象とするプロバイダのリストを取得したり、自分でリストを作ったりとやり方はいくつかあると思います。コードのイメージは以下のようになります。

LocationManager locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); 

//Criteriaを指定する場合
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE); // ここで条件を指定
...
List<String> providers = locationManager.getProviders(criteria, true);

// 自分でGPSとNETWORKのリストを作る場合の関数
// こっちのやり方だと明確にGPSとNETWORKだけ指定できる
private List<String> getGpsProviders(LocationManager lm) {
  Array<String> providers = new Array<String>();

  if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
    providers.add(LocationManager.GPS_PROVIDER);
  }

  if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
    providers.add(LocationManager.NETWORK_PROVIDER);
  }
  return providers;
}

作成したproviderのリストを全てrequestLocationUpdatesに渡す

通常は単一のプロバイダをLocationManagerのrequestLocationUpdatesdeに渡し測定を開始しますが、これを必要なprovider分だけ呼び出せば並行して測定が行われます。

全部のプロバイダで同じリスナを使っていれば、removeUpdatesは一度呼び出せば全部のプロバイダの測定が停止します。

List<String> providers = locationManager.getProviders(true); // Criteriaを指定したリストの取得でもよい

// 全てのプロバイダをrequestLocationUpdatesに渡す
for (String provider : providers) {
  locationManager.requestLocationUpdates(provider, 1000, 0, locationListener); //リスナの定義は割愛
}

// removeUpdatesで全て停止
lm.removeUpdates(locationListener);