位置情報サービスの要求条件を指定して位置情報の更新を通知する


Android SDK 2.3からrequestLocationUpdatesメソッドに位置情報サービスの要求条件を指定するためのCriteriaクラスのオブジェクトを引数として渡せるようになりました。
詳細は以下から

Criteriaクラスの概要

Criteriaクラスは位置情報サービスの要求条件を指定するためのクラスです。

指定できる条件は以下の通りです。

PowerRequirement 消費電力量を指定します
Accuracy 精度を指定します
AltitudeRequired 高度を取得するかどうかを指定します
SpeedRequired スピードを取得するかどうかを指定します
BearingRequired 進行方向を取得するかどうかを指定します
CostAllowed 位置情報の取得に費用がかかることを許可するかどうかを指定します

以下は指定するためのサンプルです。

Criteria criteria = new Criteria();
//Accuracyを指定
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
//PowerRequirementを指定
criteria.setPowerRequirement(Criteria.POWER_LOW);
//SpeedRequiredを指定
criteria.setSpeedRequired(false);
//AltitudeRequiredを指定
criteria.setAltitudeRequired(false);
//BearingRequiredを指定
criteria.setBearingRequired(false);
//CostAllowedを指定
criteria.setCostAllowed(false);

パーミッションの追加

位置情報を取得するにはパーミッションにandroid.permission.ACCESS_COARSE_LOCATIONandroid.permission.ACCESS_FINE_LOCATIONを追加する必要があります。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="org.jpn.techbooster.sample.LocationManagerSample"
      android:versionCode="1"
      android:versionName="1.0">

・・・省略・・・

 <uses-sdk android:minSdkVersion="9" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
</manifest> 

位置情報の更新を通知する

では実際に位置情報の更新を通知してみましょう。
まずは通知元のサンプルコードから。
LocationManagerSample.java

public class LocationManagerSample extends Activity{
	private LocationManager lm;
	private PendingIntent pi;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //LocationManagerオブジェクトの生成
        lm = (LocationManager)getSystemService(LOCATION_SERVICE);

        //ローケーション取得条件の設定
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        criteria.setSpeedRequired(false);
        criteria.setAltitudeRequired(false);
        criteria.setBearingRequired(false);
        criteria.setCostAllowed(false);

        //PendingIntentの生成
        Intent nextIntent = new Intent(this, ReceiveLocation.class);
        pi = PendingIntent.getBroadcast(this, 0x432f, nextIntent,
            PendingIntent.FLAG_UPDATE_CURRENT);

        lm.requestLocationUpdates(1000, 1, criteria, pi);

    }

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

    	lm.removeUpdates(pi);
    }
}

12行目ではLocationを管理するためのLocationManagerオブジェクトの生成を行っています。
15~21行目までは先ほど説明したCriteriaオブジェクトの生成と各要求条件の設定を行っています。
24~26行目ではブロードキャストをPendingIntentに変換しています。
28行目ではAndroid SDK 2.3から追加されたrequestLocationUpdates (long minTime, float minDistance, Criteria criteria, PendingIntent intent)メソッドを使用して、位置情報の更新通知を設定しています。

このメソッドの引数の詳細は以下になります。

minTime 通知する時間の間隔をミリ秒で指定します
minDistance 通知する距離の間隔をメートルで指定します
criteria 要求条件を指定するCriteriaオブジェクトを指定します
intent 通知先のブロードキャストを指定します

サンプルの引数では1秒後もしくは1メートルの距離移動で通知が行われます。
33~37行目ではアプリケーションがフォアグラウンドでなくなった場合に位置情報の通知をしないようにする為の処理が記述されています。

次に通知先のブロードキャストレシーバのサンプルです。
ReceiveLocation.java

public class ReceiveLocation extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		if(intent.hasExtra(LocationManager.KEY_LOCATION_CHANGED)){
			LocationManager lm =
                            (LocationManager)context
                            .getSystemService(Context.LOCATION_SERVICE);

			Location location =
                            lm.getLastKnownLocation(LocationManager
                                .GPS_PROVIDER);

			String message = "Location\n"
			                  + "Longitude:" + location.getLongitude()
                              + "\n"
			                  + "Latitude:" + location.getLatitude();

			Toast.makeText(context, message, Toast.LENGTH_LONG).show();
		}
	}
}

5行目ではKEY_LOCATION_CHANGEDを使用して位置情報の更新が行われたかどうかを判定しています。
10~12行目で更新後のLocationオブジェクトを取得し、15行目のgetLongitude()メソッドで経度を、17行目のgetLatitude()メソッドで緯度を取得しています。

※記事掲載時(2010/12/27)のAndroid2.3エミュレータでは位置情報の取得を行うとバグによってエミュレータがクラッシュする為、実機での確認をお勧めします。

One Comment