자 이제 MapView를 통해 구글이 제공하는 지도를 볼 수 있다는 것을 알았고, 그 위에 마커를 올려줄 수 있다는 것을 확인했다.
근데 Map 예제를 보면서 왜 지도가 세계지도로 나올까? 난 이게 참 궁금했다.
확인해보니 Map과 관련된 Control을 관리해 주어야 하는 구만.
그럼 지금부터는 진짜 지도를 보자.
MapView를 사용하기 위해서는 manifest.xml에
<uses-library android:name="com.google.android.maps" /> 과
<uses-permission android:name="android.permission.INTERNET" /> 를 추가해 주어야 한다는 것을 이미 배웠다.
이런 식으로 GPS를 확인하기 위해 다음과 같은 permission이 추가되어야 한다.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
하나씩 설명하기 어려우니 작성한 소스를 올린다.
package com.bloodlee;
/**
* MapView를 위한 Sample을 작성합니다.<br>
* 1. 현재 GPS 정보를 조회하여 Map을 그립니다.<br>
* 2. GPS 정보가 변경되면 해당 위치를 다시 그립니다.<br>
* 3. 혠 wjdqh
* @author bloodlee
*/
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import com.bloodlee.R;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class MapviewSample extends MapActivity implements LocationListener{
MapController mc;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// MapView 생성
MapView mapView = (MapView) findViewById(R.id.mapview);
// MapView 하단에 Zoom 생성
mapView.setBuiltInZoomControls(true);
// LocationManager를 구한다.
LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// 현재 시스템의 LocationManager에서 활성화된 Provider를 조회한다.
List<String> providers = locManager.getProviders(true);
for(int i=0; i < providers.size();i++)
Log.i("Providers in LocationManager",providers.get(i));
// Provider의 조건으로 최적의 Provider를 조회한다.
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = locManager.getBestProvider(criteria, true);
Log.i("BestProvider",provider);
// Provider에 저장된 최종 위치 정보를 조회한다.
Location loc = locManager.getLastKnownLocation(provider);
GeoPoint p = null;
// Provider를 통해 현재 위치를 조회한다.
if(loc != null){
int lat = (int)(loc.getLatitude()* 1E6);
int lng = (int)(loc.getLongitude() * 1E6);
p = new GeoPoint(lat, lng);
Log.i("GPS Information","[" + lat + "],[" + lng + "]");
}
else{ // 현재 위치를 조회할 수 없는 경우 기본값(명동)을 설정한다.
Log.i("GeoPoint","Location is null");
p = new GeoPoint(37559978,126985806);
}
Log.i("Address",getAddress(p));
mc = mapView.getController();
mc.animateTo(p);
// Zoom Level을 설정한다. 1 ~ 21까지. 21이면 최대 확대
mc.setZoom(15);
// GPS 정보가 변경을 조회한다. GPS가 변경되면 onLocationChanged 호출
locManager.requestLocationUpdates(provider, 1000L, 500.0f, this);
}
/**
* LocationListener를 통해 GPS 정보가 변경되는 경우 호출
*/
public void onLocationChanged(Location loc) {
if (loc != null) {
int lat = (int)(loc.getLatitude()* 1E6);
int lng = (int)(loc.getLongitude() * 1E6);
GeoPoint p = new GeoPoint(lat, lng);
mc.animateTo(p);
Log.d("onLocationChanged","[" + lat + "],[" + lng + "]");
Log.i("Address",getAddress(p));
}
}
public void onProviderDisabled(String provider) {
// required for interface, not used
}
public void onProviderEnabled(String provider) {
// required for interface, not used
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// required for interface, not used
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
/**
* 취치 정보로 해당 주소 정보를 조회한다.
*/
private String getAddress(GeoPoint p){
// 주소 정보를 조회합니다.
// 한국 주소가 잘 안나오는 것 같다.
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
StringBuilder sb = new StringBuilder();
try{
List<Address> addrList = geocoder.getFromLocation((double)(p.getLatitudeE6() / 1E6),
(double)(p.getLongitudeE6() / 1E6),
10);
if (addrList.size() > 0) {
Address addr = addrList.get(0);
/* 잘 안나옴.
for (int i = 0; i < addr.getMaxAddressLineIndex(); i++)
sb.append(addr.getAddressLine(i)).append(", ");
Log.i("addr.getAddressLine(i))", sb.toString());
sb.append(addr.getAdminArea()).append(", ");
if(addr.getAdminArea() != null)
Log.i("addr.getAdminArea()", addr.getAdminArea());
sb.append(addr.getSubAdminArea()).append(", ");
if(addr.getSubAdminArea() != null)
Log.i("addr.getSubAdminArea()", addr.getSubAdminArea());
sb.append(addr.getPremises()).append(", ");
if(addr.getPremises() != null)
Log.i("addr.getPremises()", addr.getPremises());
*/
sb.append(addr.getFeatureName()).append(", "); // 번지
sb.append(addr.getLocality()).append(", "); // 시, 군
sb.append(addr.getPostalCode()).append(", ");
sb.append(addr.getCountryName());
Log.i("Address", sb.toString());
Toast.makeText(MapviewSample.this, sb.toString(), Toast.LENGTH_LONG).show();
}
}catch(IOException ioe){
Log.e("Exception on getting Geocoder", ioe.getLocalizedMessage());
}
return sb.toString();
}
}