Androidアプリ-GPS測位と地理的位置取得
7371 ワード
1.関連知識の紹介
LocationManagerServiceで場所を取得できます.このサービスのaidlファイルはframeworks/base/location/java/android/location/で、LocationManager.javaから呼び出す方法が表示されます.位置決め時にどのproviderを採用するかを指定する必要があります.よく使われるのは3種類あります.
LocationManager.GPS_PROVIDER 正確な位置決め、精度は十数メートル以内
LocationManager.NETWORK_PROVIDER 大まかな位置決め、精度は100メートル以上
LocationManager.PASSIVE_PROVIDER こっそり位置決め、すなわち位置決めを開始しませんが、他のアプリケーションがgps/networkを使用して所定の位置に設定するとlocationが通知されます.
LocationManagerServiceを使用するには、まずLocationManagerを取得し、このLocationManagerを使用して位置決めの開始、位置決めのクローズなどの操作を行います.
import android.location.LocationManager;
private LocationManager mLocationManager;
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
次に、LocationManagerで位置決めを開始する方法を見てみましょう.
public void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)
public void requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent)
public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent intent)
minTime-最小時間、ミリ秒単位、
今回得られたlocationが前回のlocationからminTimeより間隔が小さい場合、location Management Serviceはこのlocationを報告しません.
MinDistance-最小距離、単位m、
今回得られたlocationと前回のlocationの距離がminDistanceより小さい場合、location Management Serviceはこのlocationを報告しません.
criteria-高精度、低電力などのproviderのルールを選択し、最後にLocationManagerが提供したルールに従って適切なproviderを選択します.
Listener-locationを受信するためのインタフェースです.onLocationChanged、onStatusChanged、onProviderEnabled、onProviderDisabledの4つの方法を書き換える必要があります.
対応する4つのイベント:location更新、ステータス更新(起動、停止)、providerオープン、providerクローズ(システム設定でGPSをオフにするなど)
intent-PendingIntent.getBroadcast(this,0,new Intent(LOCATION_EVENT)、0)でPendingIntentを取得できます.
このLOCATION_イベントは自分で定義したアクションです
ロケーションイベントが発生すると、LocationManagerServiceからカスタムLOCATION_を送信します.EVENT放送、対応データはIntentのExtraに
putExtra(LocationManager.KEY_LOCATION_CHANGED, new Location(location))
putExtra(LocationManager.KEY_STATUS_CHANGED, status)
putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled)
LocationManagerで位置決めを閉じる方法:
public void removeUpdates(LocationListener listener)
public void removeUpdates(PendingIntent intent)
LocationListenerまたはPendingIntentを使用して位置イベントを受信できますが、一般的にLocationListenerが一般的に使用される方法の1つしか選択できません.
locationを取得した後、locationから経緯度データを取得し、GeocoderのgetFromLocationメソッドで地理的位置情報を取得することができます.
例えば、中国上海市浦東新区浜江大道
Geocoder(Context context, Locale locale) 指定されたLocaleに基づいてGeocoderを構築します.Locale.getDefault()はローカルです.
List getFromLocation(double latitude, double longitude, int maxResults) 指定した緯度付近の地理的位置情報を取得する
AddressはgetAddressLineを提供し、位置文字列Stringを取得します. getAddressLine(int index)
一般位置情報文字列はいくつかのセグメントがあり、index=0は国、1は市街地であり、int getMaxAddressLineIndex()は、最後のセグメントの番号を表示します.
2. インスタンスコード
appを開くとすぐにgps測位を開始し、所定の位置に着いたら最初のlocationの緯度データを2つのEditTextに入れ、この緯度を利用して地理的位置情報を計算し、Toastで表示します.また、EditTextの緯度データを修正し、クエリーをクリックして所定の緯度の地理的位置を得ることができます.
addrList = mGeocoder.getFromLocation(Double.parseDouble(latitude), Double.parseDouble(longitude), 1); if(addrList.size() > 0){ StringBuilder sb = new StringBuilder(); Address addr = addrList.get(0); for(int i=0;i<=addr.getMaxAddressLineIndex();i++){ sb.append(addr.getAddressLine(i)).append(""); } showMessage(sb.toString()); }else{ showMessage("address not found!"); } }catch(IOException e){ e.printStackTrace(); } } @Override protected void onStart(){ super.onStart(); mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, mListener); Log.d(TAG,"start gps"); } @Override protected void onStop(){ mLocationManager.removeUpdates(mListener); Log.d(TAG,"stop gps"); super.onStop(); } private LocationListener mListener = new LocationListener(){ @Override public void onLocationChanged(Location location){ String latitude,longitude; latitude = Double.toString(location.getLatitude()); longitude = Double.toString(location.getLongitude()); Log.d(TAG, "lat: "+ latitude + "long: "+ longitude); if(++fixCount == 1){ mEditLat.setText(latitude); mEditLong.setText(longitude); showAddress(latitude,longitude); } } @Override public void onProviderDisabled(String provider) {//TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) {//TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) {//TODO Auto-generated method stub } }; private void showMessage(String addr){ mHandler.removeMessages(MSG_SHOW); Bundle bundle = new Bundle(); bundle.putString("ADDR", addr); mHandler.sendMessage(Message.obtain(mHandler, MSG_SHOW, bundle)); } public class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ switch(msg.what){ case MSG_SHOW: Bundle bundle = (Bundle)msg.obj; Toast.makeText(getApplicationContext(), bundle.getString("ADDR"), Toast.LENGTH_SHORT).show(); break; } } } }
LocationManagerServiceで場所を取得できます.このサービスのaidlファイルはframeworks/base/location/java/android/location/で、LocationManager.javaから呼び出す方法が表示されます.位置決め時にどのproviderを採用するかを指定する必要があります.よく使われるのは3種類あります.
LocationManager.GPS_PROVIDER 正確な位置決め、精度は十数メートル以内
LocationManager.NETWORK_PROVIDER 大まかな位置決め、精度は100メートル以上
LocationManager.PASSIVE_PROVIDER こっそり位置決め、すなわち位置決めを開始しませんが、他のアプリケーションがgps/networkを使用して所定の位置に設定するとlocationが通知されます.
LocationManagerServiceを使用するには、まずLocationManagerを取得し、このLocationManagerを使用して位置決めの開始、位置決めのクローズなどの操作を行います.
import android.location.LocationManager;
private LocationManager mLocationManager;
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
次に、LocationManagerで位置決めを開始する方法を見てみましょう.
public void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)
public void requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent)
public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent intent)
minTime-最小時間、ミリ秒単位、
今回得られたlocationが前回のlocationからminTimeより間隔が小さい場合、location Management Serviceはこのlocationを報告しません.
MinDistance-最小距離、単位m、
今回得られたlocationと前回のlocationの距離がminDistanceより小さい場合、location Management Serviceはこのlocationを報告しません.
criteria-高精度、低電力などのproviderのルールを選択し、最後にLocationManagerが提供したルールに従って適切なproviderを選択します.
Listener-locationを受信するためのインタフェースです.onLocationChanged、onStatusChanged、onProviderEnabled、onProviderDisabledの4つの方法を書き換える必要があります.
対応する4つのイベント:location更新、ステータス更新(起動、停止)、providerオープン、providerクローズ(システム設定でGPSをオフにするなど)
intent-PendingIntent.getBroadcast(this,0,new Intent(LOCATION_EVENT)、0)でPendingIntentを取得できます.
このLOCATION_イベントは自分で定義したアクションです
ロケーションイベントが発生すると、LocationManagerServiceからカスタムLOCATION_を送信します.EVENT放送、対応データはIntentのExtraに
putExtra(LocationManager.KEY_LOCATION_CHANGED, new Location(location))
putExtra(LocationManager.KEY_STATUS_CHANGED, status)
putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled)
LocationManagerで位置決めを閉じる方法:
public void removeUpdates(LocationListener listener)
public void removeUpdates(PendingIntent intent)
LocationListenerまたはPendingIntentを使用して位置イベントを受信できますが、一般的にLocationListenerが一般的に使用される方法の1つしか選択できません.
locationを取得した後、locationから経緯度データを取得し、GeocoderのgetFromLocationメソッドで地理的位置情報を取得することができます.
例えば、中国上海市浦東新区浜江大道
Geocoder(Context context, Locale locale) 指定されたLocaleに基づいてGeocoderを構築します.Locale.getDefault()はローカルです.
List getFromLocation(double latitude, double longitude, int maxResults) 指定した緯度付近の地理的位置情報を取得する
AddressはgetAddressLineを提供し、位置文字列Stringを取得します. getAddressLine(int index)
一般位置情報文字列はいくつかのセグメントがあり、index=0は国、1は市街地であり、int getMaxAddressLineIndex()は、最後のセグメントの番号を表示します.
2. インスタンスコード
appを開くとすぐにgps測位を開始し、所定の位置に着いたら最初のlocationの緯度データを2つのEditTextに入れ、この緯度を利用して地理的位置情報を計算し、Toastで表示します.また、EditTextの緯度データを修正し、クエリーをクリックして所定の緯度の地理的位置を得ることができます.
package com.example.locationview;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import android.app.Activity;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private final String TAG = "LocationView";
private MyHandler mHandler;
private final int MSG_SHOW = 1;
private EditText mEditLat,mEditLong;
private Button mButtonFind;
private LocationManager mLocationManager;
private Geocoder mGeocoder;
private int fixCount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditLat = (EditText)findViewById(R.id.latitudeEdit);
mEditLong = (EditText)findViewById(R.id.longitudeEdit);
mButtonFind = (Button)findViewById(R.id.findButton);
mHandler = new MyHandler(getMainLooper());
mGeocoder = new Geocoder(getApplicationContext(),Locale.getDefault());
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
fixCount = 0;
mButtonFind.setOnClickListener(new OnClickListener(){
public void onClick(View view){
String latitude,longitude;
latitude = mEditLat.getText().toString();
longitude = mEditLong.getText().toString();
if(!latitude.equals("") && !longitude.equals("")){
showAddress(latitude,longitude);
}
}
});
}
private void showAddress(String latitude,String longitude){
try{
List
addrList = mGeocoder.getFromLocation(Double.parseDouble(latitude), Double.parseDouble(longitude), 1); if(addrList.size() > 0){ StringBuilder sb = new StringBuilder(); Address addr = addrList.get(0); for(int i=0;i<=addr.getMaxAddressLineIndex();i++){ sb.append(addr.getAddressLine(i)).append(""); } showMessage(sb.toString()); }else{ showMessage("address not found!"); } }catch(IOException e){ e.printStackTrace(); } } @Override protected void onStart(){ super.onStart(); mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, mListener); Log.d(TAG,"start gps"); } @Override protected void onStop(){ mLocationManager.removeUpdates(mListener); Log.d(TAG,"stop gps"); super.onStop(); } private LocationListener mListener = new LocationListener(){ @Override public void onLocationChanged(Location location){ String latitude,longitude; latitude = Double.toString(location.getLatitude()); longitude = Double.toString(location.getLongitude()); Log.d(TAG, "lat: "+ latitude + "long: "+ longitude); if(++fixCount == 1){ mEditLat.setText(latitude); mEditLong.setText(longitude); showAddress(latitude,longitude); } } @Override public void onProviderDisabled(String provider) {//TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) {//TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) {//TODO Auto-generated method stub } }; private void showMessage(String addr){ mHandler.removeMessages(MSG_SHOW); Bundle bundle = new Bundle(); bundle.putString("ADDR", addr); mHandler.sendMessage(Message.obtain(mHandler, MSG_SHOW, bundle)); } public class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ switch(msg.what){ case MSG_SHOW: Bundle bundle = (Bundle)msg.obj; Toast.makeText(getApplicationContext(), bundle.getString("ADDR"), Toast.LENGTH_SHORT).show(); break; } } } }