2009年12月31日木曜日

Android 自分の位置をMap上に描画3

前回MyLocationOverlayの描画をとりあえず変更してみました。
で、あまりにも頻繁にGPS取得が行われるので取得間隔を変更したい!

ってことでやってみました。

と、いってもやり方は簡単MyLocationOverlay.enableMyLocation()の代わりに、LocationManagerを使用するだけ。
LocationManagerにMyLocationOverlayを登録して完了。


Main.java


package com.omkageru.ak.gpschk;

import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

public class Main extends MapActivity {
 private MapView mapView;
 private MyLocation overlay;
 private LocationManager lm;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  mapView = (MapView)findViewById(R.id.map);
  mapView.setEnabled(true);
  mapView.setClickable(true);
  mapView.setBuiltInZoomControls(true);
  mapView.setSatellite(false);

  overlay = new MyLocation(getApplicationContext(), mapView);
  // LocationManager に任せるのでコメントアウト
  //  overlay.enableMyLocation();

  lm = (LocationManager)getSystemService(LOCATION_SERVICE);
  // マネージャにMyLocation(のListener)を登録
  // 第二引数は取得時間間隔(ミリ秒単位) 第三引数は取得距離間隔(メートル単位)らしい
  lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 1000, overlay);

  // onLocationChanged にすべてを任せたのでコメントアウト
  //  overlay.runOnFirstFix(new Runnable(){
  //
  //   public void run() {
  //    // TODO 自動生成されたメソッド・スタブ
  //    mapView.getController().animateTo(overlay.getMyLocation());
  //   }
  //
  //  });

  mapView.getOverlays().add(overlay);
  mapView.invalidate();
 }

 /* (非 Javadoc)
  * @see com.google.android.maps.MapActivity#onDestroy()
  */
 @Override
 protected void onDestroy() {
  //  overlay.disableMyLocation();
  lm.removeUpdates(overlay);
  mapView.getOverlays().remove(overlay);
  // TODO 自動生成されたメソッド・スタブ
  super.onDestroy();
 }

 @Override
 protected boolean isRouteDisplayed() {
  // TODO 自動生成されたメソッド・スタブ
  return false;
 }
}

上記でも書きましたが、enable/disableMyLocation の代わりにLocationMangerを使用しているだけです。
その他は前回となんら変わらず。
MyLocationクラスにはLog掛けしただけなので、実質変更なし。

果たして本当に変わるのか?
ということでとりあえず、この年末の寒い中、ノートと実機を持ってマンションのベランダへ。
ええ、流石に外に出歩くとかはやりませんよ、ヘンナヒトダトオモワレソウダシ

requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 1000, overlay);
この第二引数と第三引数を弄ってonLocationChangedがどれだけ降ってくるか等を確認しました。

第二:第三 = 10000:0
たま~に、10秒以上取得しないこともあるけど、1秒に一回は取得する。
位置情報が微妙にずれるだけで取得間隔がリセットされるのかな?
端末の画面も細かく再描画されますw

第二:第三 = 0:1000
一度LocationChangedを取得した後は、一度もLocationChangedが発生することはなかった。
結構いけるんじゃね?とか考えたが、通知バーのGPSマークは表示されっぱなし

第二:第三 = 60000:1000
先ほど同様一度LocationChangedを取得した後は、一度もLocationChangedが発生することはなかった。
いったん取得した後、しばらくすると通知バーからもGPSマークは消えた。
その後は約1分間隔でGPSマークが数秒表示という状態に。

というわけで、以下のように推測

  1. GPS情報を取得
  2. いったん取得した後、第三引数で設定範囲内でブレがないことを何回か取得して確認
  3. ブレていれば1へ戻る
  4. ブレがなければ、第二引数で指定した時間分waitして1へ

ってことなんでしょう。たぶん。
まあ、2の「何回か」ってのもだいぶ怪しいけど

いや、もしかしたら例によって英語のドキュメントちゃんと読むとか、LocationManagerのソース読むとかすれば答えはあるかも知れませんが。
ええっと、とりあえず第二引数と第三引数がミリ秒単位とかメートル単位ってのはドキュメントから読み取りましたし、サービスで実行するときは電池の持ちを考えて60秒ぐらいに設定しろとかはかいてありましたけど。

会社同様AndroidSDKのソースを取得すべきか否か・・・。う~ん。

てかここまでやるなら、Overlay、LocationListenerそれぞれ自前実装でも一緒じゃね?


参考 「Android プログラミング入門」
  • 第四部 5.1.7 オーバーレイの表示
  • 第四部 5.2.1 現在位置取得
  • 第四部 5.2.3 MyLocationOverlay

0 件のコメント:

コメントを投稿