戌印-INUJIRUSHI- (Androidあれこれ)

Androidのプログラミングをメインにしてます。記事に貼られたソースコードはダブルクリックすることで行番号をはずしてコピーすることができます。

 
1
2
3
4
6
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
12

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

MapFragment に現在地表示、マーカー表示などの機能を追加する

MapFragment / SupportMapFragment への機能追加は簡単に行えます。

この記事では『屋内マップの表示切替』『現在地表示機能』『マーカー表示』『アニメーションによるカメラ移動』の実装コードを記載しています。

MapFragment_marker_mylocation.png

以下のソースコードは Google Play services に含まれているサンプルソースを参考に作っています。
${ANDROID_SDK}/extras/google/google_play_services/samples/maps/src/com/example/mapdemo/

マーカーをタップで吹き出し表示。
マップ長押しで東京駅へカメラがアニメーション移動します。
package jp.inujirushi.android.mapsv2;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class ProgrammaticActivity extends FragmentActivity {

private static final String TAG_MAP_FRAGMENT = "MAP_FRAGMENT";
private static final LatLng TOKYO = new LatLng(35.681382, 139.766084);

private SupportMapFragment mMapFragment;
private GoogleMap mMap;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// 登録したタグから MapFragment を取得する(デバイス回転などの再生成対策)
mMapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentByTag(TAG_MAP_FRAGMENT);
if (mMapFragment == null) {
// MapFragment がなければ作成する
mMapFragment = SupportMapFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, mMapFragment, TAG_MAP_FRAGMENT)
.commit();
}
}

@Override
protected void onResume() {
super.onResume();

if (mMap == null) {
// MapFragment から GoogleMap を取得する
mMap = mMapFragment.getMap();
if (mMap != null) {
// マップをハイブリッド表示にする
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

// 屋内マップ表示を無効にする(標準は true)
mMap.setIndoorEnabled(false);

// 現在地表示ボタンを有効にする
mMap.setMyLocationEnabled(true);
// UiSettings にボタン表示設定があるが標準は true なので設定不要
// mMap.getUiSettings().setMyLocationButtonEnabled(true);

// 東京駅にマーカーをつける
mMap.addMarker(new MarkerOptions()
.position(TOKYO)
.title("東京駅")
.snippet("2012年10月1日に復元工事が完了")
.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_BLUE)));

// カメラの位置を東京駅に変える
this.moveCameraToTokyo(false);

// 地図の長押しでカメラを東京駅まで移動する
mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng point) {
moveCameraToTokyo(true);
}
});
}
}
}

/**
* カメラを東京駅に移動する
*
* @param isAnimation
* アニメーション移動するかの判定。true でアニメーション移動。
*/
private void moveCameraToTokyo(boolean isAnimation) {
// カメラの位置情報を作成する
CameraUpdate camera = CameraUpdateFactory
.newCameraPosition(new CameraPosition.Builder()
.target(TOKYO)
.zoom(18.0f).build());
if (isAnimation) {
// アニメーション移動する
mMap.animateCamera(camera);
} else {
// 瞬間移動する
mMap.moveCamera(camera);
}
}
}
各機能の実装の仕方はソースコードのコメントを読んでください。

マップ右上に出ている現在地表示ボタンの表示は勘違いしそうですが…
GoogleMap#setMyLocationEnabled(boolean enabled)
に true を設定することで表示されます。デフォルトは false が設定されています。

他のコントロールは UiSettings クラスで設定されており、現在地表示ボタンも同様に設定できます。
UiSettings#setMyLocationButtonEnabled(boolean enabled)
この現在地表示ボタンはデフォルトで true が設定されていますが、GoogleMap#setMyLocationEnabled(boolean enabled) が有効(true)になっていなければ表示されません。

現在地表示を無効にしているのだからボタンを表示しても意味はないのですが、なんかモヤモヤします…
スポンサーサイト

MapFragment を動的に実装する

MapFragment / SupportMapFragment を動的に実装する方法。


MapFragment を使うには Google Play Services (rev.3 ~) のライブラリ・プロジェクトが必要です。
まだ作成されてない方は以下の記事を参考に作成してください。
Google Maps Android API v2 試してみた
Google Maps Android API v2 導入の仕方


以下のソースコードは『MapFragment を静的に実装する(レイアウトXML定義)』で設定できるものを対象としています。
※ この記事では SupportMapFragment を例として扱っていますが MapFragment も同じです。

【アクティビティクラス】
package jp.inujirushi.android.mapsv2;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.UiSettings;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;

public class MainActivity extends FragmentActivity {

private static final String TAG_MAP_FRAGMENT = "MAP_FRAGMENT";

private SupportMapFragment mMapFragment;
private GoogleMap mMap;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// 登録したタグから MapFragment を取得する(デバイス回転などの再生成対策)
mMapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentByTag(TAG_MAP_FRAGMENT);
if (mMapFragment == null) {
// GoogleMapのオプションを設定する
GoogleMapOptions options = new GoogleMapOptions();
options.useViewLifecycleInFragment(false);
options.zOrderOnTop(false);

// MapFragment を作成する(デフォルトの GoogleMapOption の場合は引数無し)
mMapFragment = SupportMapFragment.newInstance(options);
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, mMapFragment, TAG_MAP_FRAGMENT)
.commit();
}
}

@Override
protected void onResume() {
super.onResume();

if (mMap == null) {
// MapFragment から GoogleMap を取得する
mMap = mMapFragment.getMap();
if (mMap != null) {
// マップの種類を設定する
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);

// カメラの位置を変える
mMap.moveCamera(CameraUpdateFactory
.newCameraPosition(new CameraPosition.Builder()
.bearing(30.0f)
.target(new LatLng(35.681382, 139.766084))
.zoom(20.0f)
.tilt(60)
.build()));

// UI の有効/無効設定を行う
UiSettings ui = mMap.getUiSettings();
ui.setCompassEnabled(true);
ui.setRotateGesturesEnabled(true);
ui.setScrollGesturesEnabled(true);
ui.setTiltGesturesEnabled(true);
ui.setZoomControlsEnabled(true);
ui.setZoomGesturesEnabled(true);
}
}
}
}
GoogleMapOptionsUiSettings はデフォルト値を設定しています。

【結果】
MapFragment_xml_layout.png

【ソースコード解説】
※ 一般的な Fragment に関するところ(getSupportFragmentManager()を使うところ)は割愛します。

SupportMapFragment の生成
SupportMapFragment#newInstance() からインスタンスの作成を行います。
ここでは GoogleMapの構成を担う GoogleMapOptions クラスを渡す SupportMapFragment#newInstance(GoogleMapOptions options) を使っています。

GoogleMapOptions クラス
GoogleMapOptions は名前のとおり GoogleMap のオプションクラスです。
SupportMapFragment のインスタンス生成時にのみ設定できます。
ユーザー操作の初期設定もここで行う。この記事では後述の UiSettings クラスで設定しています。

GoogleMapOptions#useViewLifecycleInFragment(boolean useViewLifecycleInFragment)
マップのライフサイクルをフラグメントのビューに渡すかの判定。
デフォルトは false が設定されており、フラグメント自体のライフサイクルに依存する。

GoogleMapOptions#zOrderOnTop(boolean zOrderOnTop)
マップの表示優先度を上げて前面に表示するかの判定。
デフォルトは false 。 true で前面に表示される。
※ ドキュメントが無いので詳細は不明。前面に表示したときズームコントロールとロケーションボタンが背面に移動されて表示されなくなるが、コンパスは表示された。

GoogleMap クラス
MapFragment に表示されているマップは GoogleMap クラスで、SupportMapFragment#getMap() から取得できます。
マップに対する設定(以降の設定)はこのクラスに対して行われます。

GoogleMap#setMapType(int type)
マップの表示種類。
"MAP_TYPE_NONE":無し、"MAP_TYPE_NORMAL":標準、"MAP_TYPE_SATELLITE":衛星写真、"MAP_TYPE_TERRAIN":地形図
XMLでは設定できなかった "MAP_TYPE_HYBRID":ハイブリッド(地名などが表示される衛星写真) が設定できます。

GoogleMap#moveCamera(CameraUpdate update)
カメラを移動します。

CameraUpdateFactory#newCameraPosition(CameraPosition cameraPosition)
カメラの位置を設定します。

--------------------------------------------------
CameraPosition.Builder#bearing(float bearing)
カメラの向き(東西南北)。
北から時計周りの角度を指定します。

CameraPosition.Builder#target(LatLng location)
地図の中心となる座標(緯度、経度)

CameraPosition.Builder#tilt(float tilt)
カメラの角度(傾き)。
地図を真上から見た位置を0として傾ける角度を指定します。

CameraPosition.Builder#zoom(float zoom)
カメラのズームレベル。
大きいほど拡大表示されます。
--------------------------------------------------

UiSettingsクラス
ユーザーによる操作(UI)の設定を行う UiSettings クラスは、GoogleMap#getUiSettings() から取得します。

UiSettings#setCompassEnabled(boolean enabled);
コンパスの有効/無効。

UiSettings#setRotateGesturesEnabled(boolean enabled);
ジェスチャーによる地図の回転の有効/無効。

UiSettings#setScrollGesturesEnabled(boolean enabled);
ジェスチャーによる地図のスクロールの有効/無効。

UiSettings#setTiltGesturesEnabled(boolean enabled);
ジェスチャーによる地図の傾きの有効/無効。

UiSettings#setZoomControlsEnabled(boolean enabled);
ズームコントロール(画面右下の+-ボタン)の有効/無効。

UiSettings#setZoomGesturesEnabled(boolean enabled);
ジェスチャーによる地図のズームイン、ズームアウトの有効/無効。


レイアウトXMLで定義できる設定は以上となります。

MapFragment を静的に実装する(レイアウトXML定義)

MapFragment / SupportMapFragment を静的に実装(レイアウトXMLで定義)するには <fragment> タグを使います。


MapFragment を使うには Google Play Services (rev.3 ~) のライブラリ・プロジェクトが必要です。
まだ作成されてない方は以下の記事を参考に作成してください。
Google Maps Android API v2 試してみた
Google Maps Android API v2 導入の仕方


レイアウトXMLで定義できる情報は以下のとおり。

【構文】(例として東京駅を中心とした値を入れています)
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"
map:cameraBearing="20.0"
map:cameraTargetLat="35.681382"
map:cameraTargetLng="139.766084"
map:cameraTilt="60.0"
map:cameraZoom="15.0"
map:mapType="terrain"
map:uiCompass="false"
map:uiRotateGestures="true"
map:uiScrollGestures="true"
map:uiTiltGestures="true"
map:uiZoomControls="true"
map:uiZoomGestures="true" />
【構文の実行結果】
MapFragment_xml_layout.png
構文の layout.xml を Activity#setContentView(int layoutResID) から呼ぶだけでOKです。
この Activity は Fragment を有した Activity (Android 3.0~ or FragmentActivity) です。

【要素】
<fragment> タグで MapFragment を指定する場合には以下の class 指定を行います。
class="com.google.android.gms.maps.MapFragment"
or
class="com.google.android.gms.maps.SupportMapFragment"

Android 3.0 (API 12 HonyComb) 以上のみを対象とする場合は MapFragment
サポートパッケージを利用する場合は SupportMapFragment を指定します。

map 要素を使うには、xmlns:map を指定する必要があります。
xmlns:map="http://schemas.android.com/apk/res-auto"

【map 要素】
map:cameraBearing="[float]"
カメラの向き(東西南北)。
北から時計周りの角度を指定します。

map:cameraTargetLat="[double]"
地図の中心となる座標(緯度)。

map:cameraTargetLng="[double]"
地図の中心となる座標(経度)。

map:cameraTilt="[float]"
カメラの角度(傾き)。
地図を真上から見た位置を0として傾ける角度を指定します。

map:cameraZoom="[float]"
カメラのズームレベル。
大きいほど拡大表示されます。

map:mapType="[none | normal | satellite | terrain]"
マップの表示種類。
"none":無し、"normal":標準、"satellite":衛星写真、"terrain":地形図
XMLから hybrid は指定できない(エラーになる)

map:uiCompass="[true | false]"
コンパスの有効/無効。

map:uiRotateGestures="[true | false]"
ジェスチャーによる地図の回転の有効/無効。

map:uiScrollGestures="[true | false]"
ジェスチャーによる地図のスクロールの有効/無効。

map:uiTiltGestures="[true | false]"
ジェスチャーによる地図の傾きの有効/無効。

map:uiZoomControls="[true | false]"
ズームコントロール(画面右下の+-ボタン)の有効/無効。

map:uiZoomGestures="[true | false]"
ジェスチャーによる地図のズームイン、ズームアウトの有効/無効。

map:useViewLifecycle="[true | false]"
マップのライフサイクルをフラグメントのビューに渡すかの判定。
デフォルトは false が設定されており、フラグメント自体のライフサイクルに依存する。

map:zOrderOnTop="[true | false]"
マップの表示優先度を上げて前面に表示するかの判定。
デフォルトは false 。 true で前面に表示される。
※ ドキュメントが無いので詳細は不明。前面に表示したときズームコントロールとロケーションボタンが背面に移動されて表示されなくなるが、コンパスは表示された。


MyLocation の設定は無いみたいです。

Twitter はじめました

いまさらですが、サイト用にTwitterはじめました。
https://twitter.com/tom_inujirushi

ブログの更新報告とかに使う予定です。
あとはプログラミングとか…?

夕飯なう。とか個人的なことはつぶやかないと思います。
特定されるの怖いので!!

1日1回は覗きますが、それほど頻繁に見るわけではないので返信とか期待しないでください。
でもフォローとかしてくれると嬉しいです。

Google Maps Android API v2 導入の仕方

2012/12/3、米Googleより Google Maps Android API v2 が発表されました。
AndroidDevelopers - New Google Maps Android API now part of Google Play services(English)


Google Maps Android API v2の主な機能として、2Dと3Dに対応したベクターベースのマップを利用したり、簡単な動作で地図を傾けたり回転させたりできるほか、主要空港やショッピングセンターといった建物のインドアマップを自分のアプリに取り入れることも可能。デベロッパから要望が多かった Map Fragment もサポートし、広い画面を備えたタブレット端末では、複数のパーツを組み合わせて複雑なユーザーインターフェイスを構成できる。
@IT - Google Maps Android APIがアップデート より


待ちに待った MapFragment / SupportMapFragment。
この Google Maps Android API v2 を利用するには以下の手続きが必要になります。

① Google Play Services (rev.3~)のダウンロード
② Google Play Services のライブラリ・プロジェクトの作成
③ Google API Console でのプロジェクト作成
④ API key の作成 ※ アプリのプロジェクト作成後に行います

Google Maps Android API v2 では openGL ES 2.0 を使用しているため Android 2.2 (API 8 Froyo) ~ からのサポートとなります。

実行には Google Play services が必要でエミュレータでのテストもできません
インストールされていないときに表示される「Play開発者サービスを入手」を押すとエラーで落ちます。
海外でエミュレータで実行された方がいました(リンク先はクロアチア語)

Google Play services は Google Play ストアがインストールされた Android2.2 以降の全端末にまもなく導入されています。
Chimtty.net - Google Play開発者サービスについて・・・
Google Play services がインストールされているかは GooglePlayServicesUtil#isGooglePlayServicesAvailable(Context context) でチェック可能。


① Google Play Services (rev.3~)のダウンロード
Google Maps Android API v2 は Google Play Services (rev.3 ~) が必要になるので Android SDK Manager からダウンロードを行います。

MapFragment_sdk.png


② Google Play Services のライブラリ・プロジェクトの作成
Google Play Services はライブラリ・プロジェクトとして提供されています。
ダウンロードした以下のプロジェクトをインポートしてください。

${ANDROID_SDK}/extras/google/google_play_services/libproject/google-play-services_lib

MapFragmentLib_import.png


③ Google API Console でのプロジェクト作成
Google API を利用するには Google APIs Console からプロジェクトを作成する必要があります。
https://code.google.com/apis/console/

Google APIs Console にGoogleアカウントでログインしたら、最初に大きく表示されている [Create Project..] からプロジェクトを作成します。

プロジェクトを作成すると [Services] の [All Services] が表示されるので、そこから Google Maps Android API v2 を探してONにします。
(表示されていない方は左のタブから [Services] を選択してください)
MapFragment_GoogleAPI_Console.png

Google API(ここでは Google Maps Android v2)にアクセスするアプリのプロジェクトを作成していない方はここで一旦終了です。
アプリのプロジェクトを作成してから(またはパッケージ名が決まってから)④を行ってください。


④ API key の作成
アプリから Google API を利用するための API key を作成します。
API key はアプリのプロジェクト、証明書単位に作成します。

まずは API key 作成に必要な SHA-1 を作成します。
IT用語辞典 e-word SHA-1 とは

SHA-1 を作成するには、アプリの証明書となるキーストアを使用します。
デバッグ用の debug.keystore でもOKです。

debug.keystore は Eclipse の設定([ウィンドウ(W)] - [設定(P)])にある [Android - ビルド] の「デフォルト・デバッグ・キーストア」に書かれたパスに保存されています。
(Windows 7 の場合)C:\Users\[ユーザー名]\.android\debug.keystore

--------------------------------------------------
SHA-1 をコマンド・プロンプトを使って作成する
--------------------------------------------------
スタートメニューから [アクセサリ - コマンドプロンプト] を起動。
以下のコマンドを実行して作成します(パスは各自の環境に合わせてください)

1. JDKのインストールフォルダに移動
cd C:\Program Files\Java\jdk1.7.0_09\bin

2. keytool 実行
keytool -v -list -keystore "[キーストアのパス]"

3. 作成された『証明書のフィンガプリント』をコピー
SHA1: の後ろが必要なハッシュ値になります。
--------------------------------------------------

次に API key を作成します。
API key は Google APIs Console から作成を行います。

③ で作成したプロジェクトにログインして、左のタブから [API Access] を選択。
[Create new Android key…] ボタンで API key を作ります。

[Create new Android key…] ボタンを押すと以下のダイアログが立ち上がるので、入力欄に [SHA-1] + ";" + [アプリパッケージ名] を入力します。
例) abcdefghijklmnopqrstuvwxyz0123456789ABC;jp.inujirushi.android.mapsv2
MapFragment_APIKey.png

[Create]を押すと画面に Key for Android apps (with certificates) が追加されます。
そこに表示されている API key がアプリからアクセスするために必要な API key になります。


これで Google Maps Android API v2 を利用する準備が整いました。
あとは Google Maps Android API v2 を利用したいプロジェクトから②で作成したライブラリ・プロジェクトを参照すればOKです。

MapFragmentLib_add.png
プロフィール

とむ・やむくん

Author:とむ・やむくん
管理人について

Windows 7 / 64bit
Eclipse 4.2 Juno (日本語パッチ済)

スポンサーサイト
最新トラックバック
検索フォーム
ブロとも申請フォーム
QRコード
QR
Twitter
2013/01/04 19:00 カウント開始

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。