Powered by Google

2011年8月1日月曜日

Android 位置情報取得処理


私のほうの合宿でのアプリは完成できてませんので代わりに
Androidアプリ開発における備忘録です。

少し前にAndroidもユーザの位置情報をGoogleに送信しているとか
騒がれていましたが、実際の位置情報を取得する処理については
どんなものなのか。アプリ開発のために調べました。

結論から言うと思った以上に簡単に実装できます。
ただし、Android の位置情報は端末や OS のバージョンによって
微妙にとれるタイミングやプロバイダがちがうので iPhoneよりは
いくつか考慮が必要になります。

処理手順は

①AndroidManifest.xmlにGPS利用のパーミッションを追加する
②LocationManagerインスタンスを取得
③LocationProviderを取得
④LocationListenerをセット
⑤位置情報が取得できたときの処理を実装


具体的には
①AndroidManifest.xmlにGPS利用のパーミッションを追加する

GPSによる位置情報取得の許可

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

ネットワークによる位置情報取得の許可

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



②LocationManagerインスタンスを取得
LocationManagerって何?と思われるかもしれませんが、android
のパッケージに含まれている位置情報取得処理用に用意されている
クラスとなります。
つきつめても意味ないので、そういうもんだということで気にせず
使用します。

LocationManagerの取得にはgetSystemServiceメソッドの引数に
Context.LOCATION_SERVICEを与えます。何故か?そういうもんだからです。


locationManager
= (LocationManager)getSystemService(Context.LOCATION_SERVICE);



③LocationProviderを取得
LocationProviderって何?となりますが
一般的なAndroid端末で取得できる位置情報は GPS、3G、Wi-Fiの3種類
GPS は「gps」、3G および Wi-Fi は「network」という文字列で取得できます。
Android ではこの「gps」や「network」のことをプロバイダと呼びます。

このLocationProviderの取得で手間取りました。サンプルプログラム
はゴロゴロしているのですが、どうも端末によって動かない。
※XperiaとHTC Desireで検証

位置情報の更新を取得するには、requestLocationUpdates()メソッドを
呼び出すのですが、この第一引数にLocationProviderを指定する必要が
あります。この第一引数にもってくるための処理がたいがいのサンプル
では、直接 gpsかnetworkをそのまま指定していました。

※直接引数に与えるプロバイダはGPS の場合は
 LocationManager.GPS_PROVIDER

 ネットワークからの位置情報取得の場合は
 LocationManager.NETWORK_PROVIDER を利用します。

直接してしまうと、そのときの状況に応じて対応できませんので
gpsかnetworkのそのときの最適なものを取得できるように実装したいですね。

ではどうするかですが、getBestProvider()メソッドを用いてのLocationProvider
取得というのがネット上のサンプルでは多いです。
ですが、たまたま検証しているDesireでは端末自体に不具合があるらしく
このメソッドを使用しても取得できませんでした。この端末で検証してないと
気付かないところです。

色々探してみると


List providers = locationManager.getProviders(true);
for( String provider : providers )
{
locationManager.requestLocationUpdates(provider, time, distance, this);
}


こういうソースがあったので実装するとDesireでも取得できました。
getBestProvider()ではなくgetProviders()メソッドを使用する方が多くの端末
に対応できそうです。
requestLocationUpdatesの第二引数は更新情報検知のための最小時間間隔、
第三引数は最小距離間隔です。それ以下での変化では検知しないような設定の
ようです。

④LocationListenerをセット
⑤位置情報が取得できたときの処理を実装
LocationListenerのセットは下記のようにActivity自体にimplementしておけば
よいです。

public class XXXXXX extends Activity implements LocationListener


すると位置情報が更新された場合にはonLocationChangedが呼ばれますので
この中に取得した位置情報をどうするかの処理を実装すればよいです。
下記は緯度、経度をログ出力しています。


public void onLocationChanged(Location location) {
Log.v("Latitude", String.valueOf(location.getLatitude()));
Log.v("Longitude", String.valueOf(location.getLongitude()));
}


ここで重要なのが、常に位置情報を取得したい場合でなければ
onLocationChanged()で位置情報を取得後にremoveUpdates()メソッドで
位置情報の更新取得を止めておきます。
止めておきませんとバッテリの減りが尋常じゃなくなりますし、そのまま
アプリが終了されると、次回の挙動が何やらおかしくなることがあります。

以上で、位置情報の取得はできます。
もっと複雑なことができるんでしょうが、とりあえずボタンクリックしたら
位置情報を取得する処理みたいなものを実装したい場合には上記で十分です。


あとAndroidではセキュリティ上システム設定を勝手に変更できませんので
位置情報を取得するには下記のような設定画面でGPSやWi-Fiによる位置情報
取得を許可設定しておく必要があります。

アプリからは直接操作できませんので、設定されていない場合は、設定を
促すメッセージダイアログを出力するなどの処理をいれておいたほうが
いいかもしれません。






0 件のコメント:

コメントを投稿