접기
실시간으로 위치 추적을 할 때, 여러 Test와 조사 결과 다음과 같이 나왔다.
1. 강제적으로 Update를 시키지 말고, LocationListener를 통하여 받도록 하자.
2. GPS Update 시간은 1초 이상, 반경은 10m 이상이 좋다.
( GPS 송수신하는데 준비 과정에서만 약 1초가 소요 된다고 함. )
3. distanceBetween를 이용하면 거리가 나온다.
4. getSpeed 함수는 m/s 단위이다.
km/h 변경은 3600을 곱하라. (60초 * 60분)
기본적인 GPS 셋팅 소스
전제 조건 : 클래스에서 LocationListener을 상속 받는다.
....
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.POWER_LOW);
criteria.setAltitudeRequired(true);
criteria.setBearingRequired(false);
criteria.setSpeedRequired(false);
criteria.setCostAllowed(true);
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.getBestProvider(criteria, true);
if (!locationManager.isProviderEnabled(provider)
&&locationManager.getLastKnownLocation(provider)!=null) {
locationManager.requestLocationUpdates(
provider,
1000,
10, this);
} else {
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
provider = locationManager.getBestProvider(criteria, true);
locationManager.requestLocationUpdates(
provider,
1000,
10, this);
}
@Override
public void onLocationChanged(Location location) {
// GPS 변경에 따른 코딩 구현.
}
위 코드에서 속도를 구할 때, onLocationChanged가 언제 불러질지 확실한 시간을 알 수 없으므로,
불러지기 전 시간과 불러진 후 시간을 체크 하여 다시 계산 해주면 정확한 m/s 속도를 구할 수 있다.
private long startTime = -1;
private Location beforeLocation;
private Location curLocation;
@Override
public void onLocationChanged(Location location) {
// GPS 변경에 따른 코딩 구현.
if (startTime == -1) {
startTime = location.getTime();
}
// 현재 위치 거리 및 속도 구하기.
float distance[] = new float[1];
Location.distanceBetween(beforeLocation.getLatitude(), beforeLocation.getLongitude(),
location .getLatitude(), location.getLongitude(), distance);
long delay = location.getTime() - startTime;
double speed = distance[0]/delay;
double speedKMH = speed * 3600;
// 전 위치 저장.
beforeLocation = location;
}
참고하세요.
그럼 오늘도 즐코딩.
접기 접기
# 현재의 좌표를 읽어오기 위해선 AndroidManifest.xml에서 location관련 허가가 반드시 필요하다.
# 또한 provider(GPS or Network)와 locationListener 에 대한 개념이 중요하다.
# 오류가 날 수 있는데 provider=null이라고 오류가 난다면 관련 허가를 해주었는지 보아야 할 것이다.
# 실기기는 gps를 탑재하고 있지만 avd는 gps가 없기 때문에 사진과 같이 DDMS에서 수동으로 입력해주어야 한다.
**************************************** MainActivity.java ********************************************
package test.day13.location;
import java.security.KeyStore.LoadStoreParameter;
import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class Day13_locationActivity extends Activity {
TextView statusText, result;
//위치정보를 공급하는 근원
String locationProvider;
//위치 정보 매니져 객체
LocationManager locationManager;
int count; //위치 정보 갱신 횟수를 세기 위한 변수
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//필요한 객체의 참조값 얻어오기
statusText = (TextView)findViewById(R.id.status);
result = (TextView)findViewById(R.id.result);
//위치 정보 매니져 객체 얻어오기
locationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
//위치정보 공급자 얻어오기
locationProvider = locationManager.getBestProvider(new Criteria(), true);
Toast.makeText(this, "위치정보 공급자:"+locationProvider, 0).show();
//가장 최근의 Location 객체 얻어오기
Location location = locationManager.getLastKnownLocation(locationProvider);
}
@Override
protected void onResume() {
super.onResume();
//(위치 정보 공급자, 갱신주기, 갱신거리, 리스너)
locationManager.requestLocationUpdates(locationProvider, 5000, 10, listener);//5초, 10미터 마다
}
@Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(listener);
}
//locationListener객체 만들기
LocationListener listener = new LocationListener() {
//상태가 바뀌었을 때
public void onStatusChanged(String provider, int status, Bundle extras) {
String msg = "";
switch(status){
case LocationProvider.OUT_OF_SERVICE :
msg = "서비스 지역이 아닙니다.";
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE :
msg = "일시적으로 위치 정보를 사용할 수 없습니다.";
break;
case LocationProvider.AVAILABLE :
msg = "서비스 가능 지역입니다.";
break;
}
statusText.setText(msg);
}
//공급자가 공급 가능하게 되었을 때
public void onProviderEnabled(String provider) {
statusText.setText("현재 상태: 위치정보 이용가능");
}
//공급자가 공급 못하게 되었을 때
public void onProviderDisabled(String provider) {
statusText.setText("현재 상태: 위치정보 이용불가");
}
//위치 정보가 바뀌엇을때 호출되는 메소드
public void onLocationChanged(Location location) {
count++;
StringBuffer buffer = new StringBuffer();
buffer.append("수신횟수:"+count+"\r\n");
buffer.append("위도:"+location.getLatitude()+"\r\n");
buffer.append("위도:"+location.getLongitude()+"\r\n");
//위치정보 출력하기
result.setText(buffer.toString());
}
};
}
**************************************** main.xml ********************************************
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android "
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:id="@+id/status" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:id="@+id/result" />
</LinearLayout>
**************************************** AndroidManifest.xml ********************************************
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android "
package="test.day13.location"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".Day13_locationActivity"
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>
</manifest>
접기 지도 서비스 이용시 GPS 설정을 하지 않으면 현재 위치 기능을 이용할 수 없다.
앱 실행시 GPS 설정이 되어 있지 않으면 설정 화면으로 이동하게 해주는 코드..
해당 함수를 원하는 위치에서 콜 해주면 된다.