位置情報サービスチュートリアル

このドキュメントでは位置情報サービスについて扱う。位置情報サービスは高精度のGPS、基地局からの測位、セルベースの測位、WIFIアクセスポイントによる測位といろいろなレベルで提供されている。応用はいろいろあるが基本は一パターンしかないため、その基本を実例で説明する。

誰も自分のいる位置を勝手に知られたりするのは不快だろう。当然の帰結として位置情報アクセスには権限が必要となっている。そのためマニフェストに以下の宣言をする。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.suddenAngerSystem"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".LocationService"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-sdk android:minSdkVersion="3" />
<!-- 精度が良い位置情報 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!-- 精度が悪い位置情報 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
</manifest>
	

次にソース側である。位置情報はAndroidのシステムサービスとなっているため、getSystemServiceを使用してマネージャを取得している。その後、Criteriaクラスのインスタンスを作成している。これは、位置情報は最初に説明した様に沢山の種別があり、最適な位置情報のプロバイダーを選択するための要求事項をまとめたものとなる。そして、getBestProviderメソッドを使用して適切な位置情報プロバイダー名を取得している。プロバイダー名を取得した後はrequestLocationUpdatesで位置が更新された際のイベントリスナーを登録している。

package com.suddenAngerSystem;

import android.app.Activity;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class LocationService extends Activity {
	private LocationManager locationService_;
	private TextView gpsDisplay_;
	private String bestProvider_;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //位置情報サービスマネージャを取得
        locationService_ = (LocationManager)getSystemService(LOCATION_SERVICE);
        gpsDisplay_ = (TextView)findViewById(R.id.gpsDisplay);

        //位置情報サービスの要求条件をピックアップする
        //速度、電力消費などから適切な位置情報サービスを選択する
        Criteria criteria = new Criteria();
        //使える中で最も条件にヒットする位置情報サービスを取得する
        final String bestProvider_ = locationService_.getBestProvider(criteria, true);

        //以前に取得した位置情報を取得
        final Location location = locationService_.getLastKnownLocation(bestProvider_);
        //位置情報の表示
        displayLocation(location);
        final LocationListener listener = new LocationListener() {
        	@Override
        	public void onLocationChanged(Location location) {
        		displayLocation(location);
        	}
			@Override
			public void onProviderDisabled(String provider) {
			}
			@Override
			public void onProviderEnabled(String provider) {
			}
			@Override
			public void onStatusChanged(String provider, int status,
					Bundle extras) {
			}
        };
        //位置更新の際のリスナーを登録。省電力のために通知の制限をする。
        //最小で15000msec周期、最小で1mの位置変化の場合(つまり、どんなに変化しても15000msecのより短い間隔では通知されず、1mより小さい変化の場合は通知されない。)
        locationService_.requestLocationUpdates(bestProvider_, 15000, 1, listener);
    }

    private void displayLocation(final Location location) {
    	if(location == null) {
    		return;
    	}
        final String gpsString =
        	"緯度:" + Double.toString(location.getLatitude()) + "\n" +
        	"経度:" + Double.toString(location.getLongitude()) + "\n" +
        	"高度:" + Double.toString(location.getAltitude()) + "\n" +
        	"精度:" + Double.toString(location.getAccuracy()) + "\n";
        gpsDisplay_.setText(gpsString);
    }
}
	

次に、エミュレータ環境での位置情報サービスの試験について説明する。通常のPCにはGPSがついているわけではないため、位置情報を通知するためのスタブが用意されている。使い方は以下の様にビューの表示でEmulator Controlを選択する。

そうすると、以下の様に位置情報の変化をAndroid側に通知することができる。

参考資料