AndroidでGoogle Maps を使用したアプリケーションを作成してみましょう。 Androidでは、位置情報を元にしたサービスを、位置情報サービス(LBS:Location-Based Services)と呼んでいます。
Android上に地図を表示して、タップした位置にアイコンを描画するアプリです。
以下のページを参考にしながら、作成してみましょう。
http://developer.android.com/guide/tutorials/views/hello-mapview.html
アプリケーションを作成する手順の概略です。
Google MapsはGoogleが提供するWeb上のサービスです。Androidでは、このサービスにアクセスするための専用のライブラリが提供されています。 このライブラリは、Googleが提供しているものであり、オープンソースのAndroidの一部ではありません。このため、このライブラリを使用するには、Googleに開発者としての登録を行う必要があります。登録を行うと、APIキーという文字列が発行されます。この文字列をアプリケーション内に組み込みむことで、サービスにアクセスすることが可能になります。
APIキーの取得には、アプリケーションの開発時に使用する証明書のハッシュが必要になります。証明書とは、開発者の名前や所属に、秘密鍵で署名したものです。
Androidのアプリケーションのパッケージには、開発者自身の証明書による署名が必要になります。デバッグには、開発ツールが自動的に作成した証明書が使用されてるのであまり意識することがありませんが、エミュレータや携帯端末の実機に転送する前に常に署名がおこなわれています。
証明書のMD5のハッシュは、SunのJDKに含まれているkeytoolという証明書操作用のツールを使用します。まずは、keytoolがインストールされているか、以下のコマンドを実行して確認しましょう。
keytool -help
もし、コマンドが見つからない場合には、JDKをインストールしたディレクトリのbinディレクトリを確認してみましょう。以下の、%JAVA_HOME%をJDKをインストールしたディレクトリに置き換えて実行してみましょう。うまく実行できれば、PATH環境変数に、%JAVA_HOME%\binを追加しておきます。
"%JAVA_HOME%\bin\keytool" -help ...
つぎに、使用している証明書のMD5のハッシュを取ります。デバッグ時に使用される証明書は、使用しているOSに応じて、以下の場所に格納されています。
keytoolの-listコマンドで証明書の一覧を表示します。例えば、SDK1.5のVistaの場合には、以下のコマンドを実行します。パスワードは、入力しないで単純にリターンを押すだけで大丈夫です。(入れたい人は、"android"と入れてください)
> keytool -list -keystore C:\Users\%USERNAME%\.android\debug.keystore キーストアのパスワードを入力してください: android キーストアのタイプ: JKS キーストアのプロバイダ: SUN キーストアには 1 エントリが含まれます。 androiddebugkey, 2008/10/14, PrivateKeyEntry, 証明書のフィンガープリント (MD5): 4B:28:72:FB:D3:2C:86:D5:A5:F8:B4:BA:09:C3:90:29
ここで表示されたフィンガープリントを、以下のページで入力します。
生成したフィンガープリントは、後で使用するので、控えておきます。
アプリケーションの署名は、端末のインストール時と、マーケットへのアップロード時に確認されます。
新規のプロジェクトを作成します。
アイコンは、ユーザーが認識可能なアプリケーションの識別子です。まずは、アイコンを書き換えてみましょう。 res/drawable/icon.pngをペイントなどで編集します。
地図を使用するには、マニフェストのapplication内にライブラリを使用するを宣言します。EclipseのGUIでは、AndroidManifestのApplicationタブの下の「Application Nodes」で設定します。
また、インターネットに接続するために、同じくマニフェスト内で以下のパーミッションの使用を宣言します。EclipseのGUIでは、AndroidManifestのPermissionタブで設定します。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainlayout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.google.android.maps.MapView android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:apiKey="取得したAPI Key" /> <LinearLayout android:id="@+id/zoomview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@id/mapview" android:layout_centerHorizontal="true" /> </RelativeLayout>
ここでは、相対レイアウトの中に、MapViewと、リニアレイアウトを作成しています。リニアレイアウトは、後でマップのズームコントローラを配置するために使用します。
public class HelloMapView extends MapActivity
@Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; }
ここで、アプリケーションを実行して、地図が表示されることを確認しましょう。もし、地図が表示されてない場合には、以下の項目を確認してみましょう。
コンストラクタを以下のように変更します。
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); LinearLayout linearLayout; MapView mapView; ZoomControls mZoom; linearLayout = (LinearLayout) findViewById(R.id.zoomview); mapView = (MapView) findViewById(R.id.mapview); mZoom = (ZoomControls) mapView.getZoomControls(); linearLayout.addView(mZoom); }
実行して、地図を表示してみましょう。タップするとズームコントローラが表示されます。
以下のフィールドを定義します。
// ログ出力用のタグ static final String TAG = "HelloMapActivity"; // 地図の初期値 static final int INITIAL_ZOOM_LEVE = 16; static final int INITIAL_LATITUDE = 35156807; static final int INITIAL_LONGITUDE = 136925412;
コンストラクタに最後に、以下の行を追加します。
// 位置とズームレベルの初期状態を設定する MapController controller = mapView.getController(); GeoPoint point = new GeoPoint(INITIAL_LATITUDE, INITIAL_LONGITUDE); controller.setCenter(point); controller.setZoom(INITIAL_ZOOM_LEVE);
実行してみましょう。
Overlayクラスを使用して、地図上に描画できます。 コンストラクタの最後に以下の呼び出しを追加します。
// イメージを地図上に表示する setOverlay(point);
以下のプライベートメソッドを定義します。
private void setOverlay(GeoPoint point) { // Overlayクラスを生成する Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.icon); IconOverlay overlay = new IconOverlay(icon, point); // 生成したOverlayクラスを追加する MapView map_view = (MapView) findViewById(R.id.mapview); List<Overlay> overlays = map_view.getOverlays(); overlays.add(overlay); } // 地図上に表示されるオーバーレイ private class IconOverlay extends Overlay { // 描画するアイコン Bitmap mIcon; int mOffsetX; int mOffsetY; // アイコンを表示する位置 GeoPoint mPoint; IconOverlay(Bitmap icon, GeoPoint initial) { // アイコンと、アイコンの中心のオフセット mIcon = icon; mOffsetX = 0 - icon.getWidth() / 2; mOffsetY = 0 - icon.getHeight() / 2; mPoint = initial; } // 地図のタップ時に呼び出される @Override public boolean onTap(GeoPoint point, MapView mapView) { // タップされた位置を記録する mPoint = point; Log.i(TAG, "Point = " + point.getLatitudeE6() + " , " + point.getLongitudeE6()); return super.onTap(point, mapView); } // 地図の描画時に、shadow=true, shadow=falseと2回呼び出される @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { super.draw(canvas, mapView, shadow); if (!shadow) { // 地図上の場所と、描画用のCanvasの座標の変換 Projection projection = mapView.getProjection(); Point point = new Point(); projection.toPixels(mPoint, point); point.offset(mOffsetX, mOffsetY); // アイコンを描画 canvas.drawBitmap(mIcon, point.x, point.y, null); } } };
実行してみましょう。