안녕하세요 완전 초보인데요 이번에 회사에서 앱 개발에 들어가기에 앞서서 테스트중인데요
프로그램 구조는 일단 이렇습니다.
어플리케이션 실행 -> GPS_PROVIDER로 현재 위치값 가져오기 -> 가져온 위치값이 null이 아니면 sdcard에 파일을 이어 쓰기
버튼 클릭시 -> 지도에 현재 위치 표시하기
여기서 크게 두가지 문제가 있는데요 하나는 GPS_PROVIDER로 설정했음에도 GPS가 켜지지 않고 3G 통신으로
값을 가져 오구여, 그리고 현재 위치를 지도에 표시 할때 정확하게 표시가 안된다는 점입니다.
제가 봤을땐 형변환의 문제가 아닌가 싶은데요..
소스가 좀 길지만 보시고 고칠점 있으면 조언 부탁드립니다.
-------------------------------------GPSTest.java START-----------------------------------------------
public class GPSTest extends Activity implements OnClickListener{
LocationListener LocationListener;
LocationManager lm;
Location location;
TextView textview_Latitude;
TextView textview_Longitude;
TextView textview_Atitude;
String bestProvider;
String provider;
Button btn;
String strPath = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
//현재 자신의 위치정보를 텍스트 뷰 안에 표시한다.
//만약 지속적으로 위치를 이동할 경우
//현재 위치에 대한 업데이트를 하기 위하여 리스너를 구현한다.
//이 경우 중요한것이 액티비티가 활성화되어 있지 않은 경우에도
//지도를 업데이트 받게 되니 반드시 onPause, onResume 메소드를 구현하여 컨트롤하자
//GPS 위치정보를 가져온다 아래의 파랑과 주황중 택일해서 사용해 보자 둘다 된다.
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
// 프로바이더는 PASSIVE, NATWORK, GPS 가 있다.
// 우리는 GPS를 사용할 것이다. GPS_PROVIDER
provider = LocationManager.GPS_PROVIDER;
//provider = LocationManager.NETWORK_PROVIDER;
location = lm.getLastKnownLocation(provider);
//프로바이더 중에 설정한 조건에 적합한 것을 가져온다. - 이 소스는 이부분을 사용했다
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE); // 정확도
criteria.setPowerRequirement(Criteria.POWER_LOW); // 전원 소리량
criteria.setAltitudeRequired(false); // 고도
criteria.setBearingRequired(false); // ..
criteria.setSpeedRequired(false); // 속도
criteria.setCostAllowed(true); // 금전적 비용
//두번째 파라미터를 true 로 해야 활성화된 프로바이더를 가져온다.
bestProvider = lm.getBestProvider(criteria, true);
location = lm.getLastKnownLocation(bestProvider);
//화면에 위도와 경도와 고도를 표시한다.
textview_Latitude = (TextView)findViewById(R.id.latitude);
textview_Longitude = (TextView)findViewById(R.id.longitude);
textview_Atitude = (TextView)findViewById(R.id.atitude);
if(location != null){
//위도 / 경도 / 고도
textview_Latitude.setText (Double.toString(location .getLatitude()));
textview_Longitude.setText (Double.toString(location .getLongitude()));;
textview_Atitude.setText (Double.toString(location .getAltitude()));;
//SD 카드의 현재상태
String state = Environment.getExternalStorageState();
Log.w("test2",state);
if(state.equals(Environment.MEDIA_MOUNTED)){
/*state -> MEDIA_MOUNTED 장착되고 읽고 쓰기 가능
* MEIDA_UNMOUNTED 이면 반대
*/
strPath=Environment.getExternalStorageDirectory().getAbsolutePath();
fileWrite(Double.toString(location .getLatitude()),Double.toString(location .getLongitude()),Double.toString(location .getAltitude()));
}
}
//이동시 현재 위치업데이트를 위한 리스너 구현
LocationListener = new DispLocListener();
//10초 단위, 10.0f 거리 이동 시 위치를 업데이트 한다.
lm.requestLocationUpdates(bestProvider, 10000L, 10.0f, LocationListener);
btn.setOnClickListener(this);
}
//액티비티가 중지 되었을 경우
public void onPause(){
super.onPause();
//현재 위치 업데이트 중지
lm.removeUpdates(LocationListener);
}
//액티비티가 다시 활성화 되었을 경우
public void onResume(){
super.onResume();
//현재 위치 업데이트 활성화
lm.requestLocationUpdates(bestProvider, 10000L, 10.0f, LocationListener);
}
//현재 위치 업데이트를 위한 리스너
public class DispLocListener implements LocationListener{
//위치가 변했을 경우에 실행하는 메소드만 구현하고 나머지는 놔두자
public void onLocationChanged(Location location) {
//현재 위치를 다시 표시한다.
//위도 / 경도 / 고도
textview_Latitude.setText (Double.toString(location .getLatitude()));
textview_Longitude.setText (Double.toString(location .getLongitude()));;
textview_Atitude.setText (Double.toString(location .getAltitude()));;
String state = Environment.getExternalStorageState();
if(state.equals(Environment.MEDIA_MOUNTED)){
strPath=Environment.getExternalStorageDirectory().getAbsolutePath();
fileWrite(Double.toString(location .getLatitude()),Double.toString(location .getLongitude()),Double.toString(location .getAltitude()));
}
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
public void fileWrite(String latitude, String longtitude,String dfdf) {
//파일 쓰기
FileWriter fileWriter = null;
BufferedWriter bufferedWriter = null;
try{
Log.w("test",getToday("yyyyMMddHHmmss"));
fileWriter = new FileWriter(new File(strPath+File.separator,"note.txt"), true);
bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(getToday("yyyyMMddHHmmss")+"|"+latitude+"|"+longtitude+"|"+dfdf);
bufferedWriter.newLine(); //한줄 추가.
}catch(Exception e){
e.printStackTrace();
}finally{
try{
bufferedWriter.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* 입력받은 형식에 맞는 현재날짜(시간) 가져오기
*
* @param fmt
* 날짜형식
* @return 현재일자
*/
public static String getToday(String fmt) {
SimpleDateFormat sfmt = new SimpleDateFormat(fmt);
return sfmt.format(new Date());
}
public void onClick(View view) {
// TODO Auto-generated method stub
Intent intent = new Intent(this,BlogMap.class);
Bundle myData = new Bundle();
myData.putString("latitude", Double.toString(location .getLatitude()));
myData.putString("longitude", Double.toString(location .getLongitude()));
myData.putString("altitude", Double.toString(location .getAltitude()));
intent.putExtras(myData);
startActivity(intent);
}
}
-------------------------------------GPSTest.java END-----------------------------------------------
-------------------------------------BlogMap.java START-----------------------------------------------
public class BlogMap extends MapActivity {
MapView mvMap;
MapController mc;
MyLocationOverlay myLocationOverlay;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mapitem);
Intent intent = getIntent();
Bundle myBundle = intent.getExtras();
String latitude = myBundle.getString("latitude");
String longitude = myBundle.getString("longitude");
String altitude = myBundle.getString("altitude");
Log.w("test",latitude+","+longitude+","+altitude);
Log.w("test",latitude);
System.out.println();
//mapmain 아이디로 맵을 가져온다
mvMap = (MapView) findViewById(R.id.map_view);
//확대축소를 가능하게 한다.
mvMap.setClickable(true);
mvMap.setEnabled(true);
//위성모드로 표시한다.
//mvMap.setSatellite(true);
mvMap.setStreetView(true);
//optional 01 ----------------------------------------------------------
//지도의 특정 위치를 표시한다.
//http://www.mygeoposition.com/ <- 위도와 경도 찾기
GeoPoint p = new GeoPoint((int)(numberFormat((Double.parseDouble(latitude)*1000000.0))),(int)(numberFormat((Double.parseDouble(longitude)*1000000.0))) );
mc = mvMap.getController();
//지도를 해당위치의 적당한 줌으로 맞춘다.
//mc.animateTo(p);
//화면 중앙에 위치시킴
mc.setCenter(p);
//지도의 줌은 1 에서 21 사이의 값을 지원한다.
//숫자가 클수록 확대이다.
//i - 확대, o - 축소
mc.setZoom(17);
ImageView dest = new ImageView(this);
dest.setImageResource(R.drawable.marker);
MapView.LayoutParams lp = new MapView.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
p, MapView.LayoutParams.CENTER);
mvMap.addView(dest, lp);
// 상단에 설명 문자열 배치
TextView title = new TextView(this);
title.setText(makeAddress((int)(numberFormat((Double.parseDouble(latitude)*1000000.0))),(int)(numberFormat((Double.parseDouble(longitude)*1000000.0)))));
title.setTextSize(40);
title.setTextColor(Color.BLACK);
MapView.LayoutParams lp2 = new MapView.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
10,10, MapView.LayoutParams.LEFT | MapView.LayoutParams.TOP);
mvMap.addView(title, lp2);
//optional 02 ----------------------------------------------------------
//MyLocationOverlay 를 생성한다.
//자신의 위치가 변할 때마다 지도를 지동으로 업데이트 해주면, 사용자의 위치에서 가장 유용한 위치제공자를
//찾아서 서비스를 요청한다.
//이 경우 중요한것이 액티비티가 활성화되어 있지 않은 경우에도
//지도를 업데이트 받게 되니 반드시 onPause, onResume 메소드를 구현하여 컨트롤하자
myLocationOverlay = new MyLocationOverlay(this, mvMap);
myLocationOverlay.runOnFirstFix(
new Runnable(){
public void run(){
//현재위치로 지속적 업데이트
mc.animateTo(myLocationOverlay.getMyLocation());
mc.setZoom(16);
}
}
);
}
//액티비티가 중지 되었을 경우
public void onPause(){
super.onPause();
//현재 위치 업데이트 중지
myLocationOverlay.disableMyLocation();
}
//액티비티가 다시 활성화 되었을 경우
public void onResume(){
super.onResume();
//현재 위치 업데이트 활성화
myLocationOverlay.enableMyLocation();
}
@Override
protected boolean isRouteDisplayed(){
return false;
}
//키보드 입력으로 지도 뷰의 모드를 전환
public boolean onKeyDown(int keyCode, KeyEvent event){
//위성 뷰
if(keyCode == KeyEvent.KEYCODE_M){
mvMap.setSatellite(true);
}
//스트리트 뷰
if(keyCode == KeyEvent.KEYCODE_S){
mvMap.setStreetView(true);
}
//교통정보 뷰
if(keyCode == KeyEvent.KEYCODE_T){
mvMap.setTraffic(true);
}
//1 확대
if(keyCode == KeyEvent.KEYCODE_I){
mc.zoomIn();
}
//1 축소
if(keyCode == KeyEvent.KEYCODE_O){
mc.zoomOut();
}
//특정 좌표로 줌한다.
if(keyCode == KeyEvent.KEYCODE_H){
mc.zoomToSpan((int)(37.478221*1000000.0),(int)(127.038099*1000000.0));
}
//화면의 특정 위치를 고정한채로 확대
if(keyCode == KeyEvent.KEYCODE_A){
//현재 화면에서 100픽셀,*100픽셀에 해당하는 부분을 중심으로 확대함
mc.zoomInFixing(100, 100);
}
//화면의 특정 위치를 고정한채로 축소
if(keyCode == KeyEvent.KEYCODE_S){
//현재 화면에서 100픽셀,*100픽셀에 해당하는 부분을 중신으로 축소함
mc.zoomOutFixing(100, 100);
}
return super.onKeyDown(keyCode, event);
}
public static long numberFormat(double n) {
// 큰 숫자일 경우에는 long 형으로
long i64;
i64 = (long) n;
System.out.println(i64);
return i64;
// 출력 결과: 1230000000000000
}
public String makeAddress(int lat, int lng) {
final Geocoder geocoder = new Geocoder(getApplicationContext(),Locale.KOREA);
List<Address> addresses;
String addressName="주소학인안됨";
try {
addresses = geocoder.getFromLocation(((double)(lat))/1000000, ((double)(lng))/1000000, 5);
StringBuilder sb = new StringBuilder();
if(addresses!=null && addresses.size()>0){
Address address=addresses.get(0);
sb.append(address.getAddressLine(0));
addressName=sb.toString();
addressName=addressName.substring(3, addressName.length());
addressName=addressName.replace("특별", "");
return addressName;
}
} catch (IOException e) {
e.printStackTrace();
}
return addressName;
}
}
-------------------------------------BlogMap.java END-----------------------------------------------