2009年12月31日木曜日

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

MyLocationOverlayを継承して、

  • 現在位置の表示を自分で書く
  • GPS情報を取得したら有無言わさずその場所へ移動
するようにしたいと思います。
基本的な構成は前回と変わらず。


MyLocation.java

package com.omkageru.ak.gpschk;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.location.Location;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;

public class MyLocation extends MyLocationOverlay {

 private MapView mapView;
 private Paint locMarkC;
 private Paint textC;
 private GeoPoint p;

 public MyLocation(Context context, MapView mapView) {
  super(context, mapView);
  // TODO 自動生成されたコンストラクター・スタブ
  this.mapView = mapView;

  locMarkC = new Paint();
  locMarkC.setAntiAlias(true);
  locMarkC.setARGB( 255, 0, 0, 255);

  textC = new Paint();
  textC.setARGB( 255, 0, 0, 0);

  p = null;
 }

 /* (非 Javadoc)
  * @see com.google.android.maps.MyLocationOverlay#draw(android.graphics.Canvas, com.google.android.maps.MapView, boolean, long)
  */
 @Override
 public synchronized boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {

  //  onLocationChangedで取得
  //  GeoPoint p = getMyLocation();
  //  isMyLocationEnabled() でのスイッチはだめでした。
  if(p != null && !shadow){
   //   ここでのanimateTo()効果なし?でした。
   //   そのため、onLocationChanged で実行
   //   mapView.getController().animateTo(p);
   //   mapView.invalidate();

   // 現在位置を青い四角で描画
   Point pos = mapView.getProjection().toPixels(p, null);
   Rect r = new Rect( pos.x - 5, pos.y - 5, pos.x + 5, pos.y + 5);
   canvas.drawRect(r, locMarkC);
   canvas.drawText("ここらへん", pos.x + 5, pos.y, textC);
  }

  return true;

  //  現在地を自前で描画するためコメントアウト
  //  return super.draw(canvas, mapView, shadow, when);
 }

 /* (非 Javadoc)
  * @see com.google.android.maps.MyLocationOverlay#onLocationChanged(android.location.Location)
  */
 @Override
 public synchronized void onLocationChanged(Location location) {

  // 現在位置をLocationからGeoPointへ
  p = new GeoPoint( (int)(location.getLatitude() * 1E6), (int)(location.getLongitude() * 1e6));
  if(p != null){
   // 現在地へ移動
   mapView.getController().animateTo(p);
  }
  // TODO 自動生成されたメソッド・スタブ
  super.onLocationChanged(location);
 }

}

MyLocationOverlayを継承したクラスを作成します。
通常のOverlayクラスでも行うように、描画部分を実装します。
とりあえず、
・public synchronized boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when)
ってやつをオーバーライドしました。

今回、getMyLocation()とisMyLocationEnabled()いうMyLocationOverlayクラスに予め用意されていたメソッドに振り回されてしまいました。
isMyLocationEnabled()でtrueならgetMyLocation()は絶対取れるだろうと。
結果は駄目でした。
要は有効になっていても、とりあえず取得できているかは別物だろ?ってことです。
なので結果としてGeoPointがnullかどうかだけ見ることにしました。
まあ、getMyLocation()のJavadocちゃんと読めってことでw
最終的に以下に掲げたonLocationChanged内で取得することにしたのでgetMyLocation()は結局使わないことになりましたが。

とりあえず描画がうまくいったところで、描画内でanimateTo()すりゃいいでしょ?と考えていましたが、
なぜかうまくいかず(たまたまですかね?)、この段階でたonLocationChanged()をオーバーライドすることを考えました。

続いてGPS情報の変更を検知したら、その場所へ移動するという処理を実現するため
・onLocationChanged
をオーバーライド
まあ、見たまんまです。


後は前回のMain.javaのMyLocationOverlayをMyLocationに置き換えて完了
動作画面は以下のとおり
現在地が青い四角になり、すぐ横に「ここらへん」という適当な文字がw


緯度40 経度140.5 に設定 何段階か拡大してます

適当にスクロールした後 緯度41 経度140.5 に設定

ちなみにこのまま実機で動かすと、もうそれはそれは約1秒間隔かそれ以下でGPS情報更新してくれます。

電池の無駄もいいところだw


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

0 件のコメント:

コメントを投稿