[[ワーキンググループ/勉強会]] * GPSで現在地を取得してみよう [#rb0a559b] GPSから現在位置を取得するAPIを用いて、ロケーションベースサービスの基礎となるアプリケーションを作成してみましょう。 アンドロイドでは、携帯電話の現在位置を取得するサービスを、位置情報サービス(LBS: Location-Based Services)と呼んでいます。LBSは、通常は人工衛星の配置を利用したGPS(Global Positioning System)を利用して位置情報を取得します。しかし、無線LANのアクセスポイントを解析して位置を特定するなど、今後新たに登場する位置情報取得サービスを考慮して、GPSという名前ではなく、より一般化されたLBSという名前を使用しています。 以下、作成のポイントです。 - getSystemService(Context.LOCATION_SERVICE)で、LocationManagerを取得します - requestLocationUpdatesで、位置情報が変化したときに通知を受け取るためのリスナーを登録します - GPSなどにアクセスするために、android.permission.ACCESS_FINE_LOCATIONのパーミッションが必要です。 - エミュレータでの開発時にテスト用のGPSを使用するために、android.permission.ACCESS_MOCK_LOCATIONが必要です ** 手順1: 新規のプロジェクトを作成する [#j1193e08] - "File -> New -> Project"を選択して、開いたダイアログで"Android Poroject"を選択して、"Next"ボタンを押します。 - 開いたダイアログで、以下のように入力してFinishボタンを押します。 -- Project Name: HelloGps -- Package name: jp.hews.hellogps -- Activity Name: HelloGpsActivity -- Application Name: ハローGPS ** 手順2: マニフェストファイルを設定する [#p28d85fc] - このアプリケーションは、GPSにアクセスするので、manifestの子要素に、以下のパーミッションの使用を宣言します <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> -- ManifestEditorの下のPermissionタブを押して、addボタンで追加して、プルダウンメニューで値を設定します。 - 開発時にテスト用のGPSのエミュレータ(MOCK_LOCATION)を使用するので、manifestの子要素に、以下のパーミッションの使用を宣言します <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/> -- ManifestEditorの下のPermissionタブを押して、addボタンで追加して、プルダウンメニューで値を設定します。 -- マップで現在値を表示するために、GoogleMapを表示するのに必要な設定を行います。設定内容は、[[勉強会/GoogleMap]]を参照してください。 - 上記の設定をしたマニフェストファイルの全体は、以下のようになります。 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="jp.hews.hellogps" android:versionCode="1" android:versionName="1.0.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".HelloGpsActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <uses-library android:name="com.google.android.maps"/> </application> <uses-permission android:name="android.permission.INTERNET"/> <!-- GPSを使用するために必要なパーミッション --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/> </manifest> ** 手順3: レイアウトを決定する [#y896312d] - レイアウトの設定は、[[勉強会/GoogleMap]]と同様に、以下のmain.xmlを使用します。 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 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:enabled="true" android:clickable="true" android:apiKey="<取得したAPIキー>" /> </LinearLayout> ** 手順4: MapActivityを継承して、LocationListenerを実装します。 [#zcc32804] 現在位置の変化を受け取るために、LocationListnerを実装します。また、現在位置を表示するために、MapActivityを継承します。 - srcの下のjp.hews.hellomapのHelloGpsActivity.javaを開いて、Activityを継承している部分を、以下のように置き換えます。 public class HelloGpsActivity extends MapActivity implements LocationListener { - 未実装のメソッドがあることが通知されるので、以下の未実装のメソッドを追加します。エラーの自動修正を利用すると便利です。 protected boolean isRouteDisplayed() {} public void onLocationChanged(Location location) {} public void onProviderDisabled(String provider) {} public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extras) {} ** 手順5: LocationManagerにリスナーを登録します。 [#mb7fbc40] - ロケーションマネージャーは、getSystemService(Context.LOCATION_SERVICE)で取得します。 LocationManager l = (LocationManager)getSystemService(Context.LOCATION_SERVICE); - GPSからの現在位置の変更通知を受け取るためのリスナーを登録します。 l.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); ** 手順6: 現在位置を表示するために、MapViewを表示可能にします。 [#uc734a7f] - 現在位置を表示するために取り出したMapControllerをフィールドに保持しておきます。その他の設定は、[[勉強会/GoogleMap]]と同様です。 public class HelloGpsActivity extends MapActivity implements LocationListener { // フィールドを追加 MapController m_controller; public void onCreate(Bundle savedInstanceState) { ...; // 解説はHelloMapを参照 MapView m = (MapView)findViewById(R.id.mapview); m_controller = m.getController(); m_controller.setZoom(15); ZoomControls zc = (ZoomControls) m.getZoomControls(); zc.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT)); zc.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); m.addView(zc); } ** 手順7: 位置情報の変化を地図に表示します [#e2a55b24] - onLocationChangedを実装します。引数のLocationをGeoPointに変換して、MapControllerに設定します。 - GeoLocationは、経度と緯度を10万倍して整数にしたものを使用します。 - 地図の表示は、animateToメソッドにGeoPointを渡すことで、現在位置からスムーズに指定した位置に移動します。 public void onLocationChanged(Location location) { GeoPoint gp = new GeoPoint((int)(location.getLatitude()*1E6), (int)(location.getLongitude()*1E6)); m_controller.animateTo(gp); } - ここまでで、全体のソースコードは、以下のようになっています。 package jp.hews.hellogps; import android.content.Context; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.view.Gravity; import android.view.ViewGroup; import android.widget.ZoomControls; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; public class HelloGpsActivity extends MapActivity implements LocationListener { // フィールドを追加 MapController m_controller; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 現在位置が変化に、メソッドが呼び出されよう登録する。 LocationManager l = (LocationManager)getSystemService(Context.LOCATION_SERVICE); l.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); // 解説はHelloMapを参照 MapView m = (MapView)findViewById(R.id.mapview); m_controller = m.getController(); m_controller.setZoom(15); ZoomControls zc = (ZoomControls) m.getZoomControls(); zc.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT)); zc.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); m.addView(zc); } @Override protected boolean isRouteDisplayed() { return false; } public void onLocationChanged(Location location) { GeoPoint gp = new GeoPoint((int)(location.getLatitude()*1E6), (int)(location.getLongitude()*1E6)); m_controller.animateTo(gp); } public void onProviderDisabled(String provider) { // TODO } public void onProviderEnabled(String provider) { // TODO } public void onStatusChanged(String provider, int status, Bundle extras) { // TODO } } - プロジェクトを右クリックして、"Run As"->"Android Application"で実行してみましょう。MapActivityの初期値に設定されている地図が表示されます。 #ref(gps.001.DefaultMapActivity.png) ** 手順5: エミュレータから現在位置を指定する [#k4c58187] - EclipseのDDMS画面を開いて、Emulator Controlの中の、Location Controlから緯度と、経度の設定ができます。 #ref(gps.002.EmulatorControl.jpg) ** 手順6:KMLファイルで経路を設定する [#ae23b25d] - Google Earthで経路をKMLファイルで作成して、Emulator Controlの中の、Location Controlから設定できます。 - http://earth.google.co.jp/からGoogle Earthをダウンロードして実行します - 場所のウィンドウのお気に入りを右クリックして新しいフォルダーを作成します - 好きな地点を表示して、フォルダーを右クリックして、「追加->目印」で、ポイントを追加します。ポイント名は英数字にするほうが無難です。 #ref(gps.003.GoogleEarth.jpg) - 数か所追加したら、フォルダーの右クリックで、「名前をつけて場所を保存」で、種類をKMLにしてファイルを保存します #ref(gps.004.SaveKML.jpg) - サンプルのKMLファイルをこのページに添付してあります。 #ref(Minato.kml) - Emulator Controlの中の、Location ControlのKMLタブを開いて、Load KMLでファイルをロードする #ref(gps.005.KML.jpg) - KMLタブの下方の緑の開始ボタンを押すと、GPSの移動が開始します。