개발자가 실내에서 GPS를 이용한 프로그램을 개발하는 경우 GPS를 가상위치에 놓아야 하는 상황이 발생한다. 


이럴때 가장 쉬운 방법은 가상GPS프로그램을 사용하면 된다.


하지만, 이러한 프로그램은 자신의 위치를 계속적으로 컨트롤 하거나 개발자가 필요한 기능을 가지지 않는 경우가 있다.


예를들어 반복적인 위치 움직임을 필요로하는 경우가 있다. 이러한 프로그램은 찾아도 없었다. 따라서 직접 만들어보았다.





해당 프로그램은 백그라운드 작업을 필요로한다. 액티비티가 종료되어도 사용자의 위치는 계속적으로 나타나져야 한다. 따라서 아래와 같이 서비스를 이용하였다.

public class LocationUpdateService extends IntentService




아래는 본격적인 가상위치를 제공하는 코드이다.

public MockLocationProvider(String name, Context ctx) {
providerName = name;
mctx = ctx;

LocationManager lm = (LocationManager) ctx.getSystemService(
Context.LOCATION_SERVICE);
lm.addTestProvider(providerName, true, true, true, true, true,
true, true, Criteria.NO_REQUIREMENT, Criteria.ACCURACY_FINE);
lm.setTestProviderEnabled(providerName, true);
}

가상위치를 설정해주기 위하여 초기화하는 부분이다. addTestProvider함수로 가상위치를 사용할 준비를 한다.


addTestProvider함수는 여러변수를 가지는데 위치제공자의 이름, 필요한 것, 제공하는 값을 나타낸다. 자세한 내용은 아래 링크를 참조하면 된다.



https://developer.android.com/reference/android/location/LocationManager.html#addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int)





아래는 가상위치의 값들을 설정하는 코드이다.

public void pushLocation(double lat, double lon, double alt) {
try {
LocationManager lm = (LocationManager) mctx.getSystemService(
Context.LOCATION_SERVICE);

Location mockLocation = new Location(providerName);
long currentTime = System.currentTimeMillis();
mockLocation.setLatitude(lat);
mockLocation.setLongitude(lon);
mockLocation.setAltitude(alt);
mockLocation.setTime(currentTime);
mockLocation.setAccuracy(1.0f);
mockLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());

lm.setTestProviderStatus(providerName, LocationProvider.AVAILABLE, mockLocation.getExtras(), currentTime);
lm.setTestProviderLocation(providerName, mockLocation);
} catch(RuntimeException e){
e.printStackTrace();
}
}

여러 값을 설정하고 이 값들을 setTestProviderLocation에 넣으면 GPS값이 출력된다.


pushLocation을 지속적으로 호출하여 사용자의 위치를 계속 갱신한다.






마지막으로 Manifest파일에 가상위치를 사용한다고 권한을 설정해주어야한다.

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

ACCES_COARSE_LOCATION과 ACCES_FINE_LOCATION은 위치제공자를 사용하기 위해 필요하다.


ACCES_MOCK_LOCATION은 가상위치를 사용하기 위해 필요하다.






테스트를 하기 위하여 위치사용허가를 해야한다. 


설정 > 시스템 > 개발자옵션 > 모의위치 앱에서 TestMockLocation을 선택한다.


이 내용은 안드로이드 버전에서 약간씩 다르다.






아래 화면에서 버튼을 누르면 가상 위치가 실행된다.


버튼을 누르면 실행


이 상태에서 지도(카카오맵)을 켜면 사용자의 위치가 나타난다.


카카오맵


위치값을 읽는 코드를 이용하여 제대로 작동하는지 확인한다.


이 코드는 아래 github링크를 놓겠다.


받는 데이터




마지막 사진에서 가상위치라고 isFromMockProvider가 true로 나온다. 실제 위치일 경우 false가 나타난다.




이처럼 개발자는 사무실에 있는데 광화문 한복판에 있다.


이러한 기능을 이용하여 GPS를 사용한 앱의 디버깅을 쉽게 할 수 있다.






아래는 참고한 웹페이지이다.


https://mobiarch.wordpress.com/2012/07/17/testing-with-mock-location-data-in-android/





Github


가상위치 : https://github.com/pchan1401-ICIL/TestMockLocation


GPS읽기 : https://github.com/pchan1401-ICIL/LocationReader









+ Recent posts