- 追加された行はこの色です。
- 削除された行はこの色です。
[[ワーキンググループ/勉強会]]
* 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の移動が開始します。