mGoogleMap = ((SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map)).getMap();
이코드에서 에러가 발생하였는데요 혹시 왜 이런문제가 생겼는지 아시는분 계신가요
아래는 전체 코드입니다.
package wacon.fragment;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowCloseListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener;
import com.google.android.gms.maps.GoogleMap.SnapshotReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Matrix;
import android.location.Address;
import android.location.Geocoder;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.Toast;
import wacon.common.CheckPermission;
import wacon.common.GoogleMapInfo;
import wacon.common.InternetConnectCheck;
import wacon.common.Record;
import wacon.common.SmartPhoneGpsSenser;
import wacon.common.SmartPhoneGpsSenser.OnGpsLocationChangedListener;
import wacon.evnet_eye.R;
public class GoogleMapFragment extends Fragment implements OnMarkerClickListener, OnMarkerDragListener ,
OnClickListener, OnGpsLocationChangedListener, OnInfoWindowCloseListener {
/**
* 이 클래스를 객 채로 사용하기 위해서는 onCreate에서 생성을 해야함
*/
View view;
protected GoogleMap mGoogleMap;
private GoogleMapInfo mapInfo;
private ArrayList<MarkerOptions> arrMarker;
private MarkerOptions currentMarker;
protected MarkerOptions marker;
protected Marker addMarker;
private CameraPosition cp;
private LatLng locCameraFocus;
private ImageButton btnSetCurrentPoint, btnMapSendExternalApp, btnZoomIn, btnZoomOut;
private boolean isGetCenterLocation = false;
PolylineOptions mPolylineOptions;
private LatLng latlngCameraCenter;
//구글맵 초기 화면 값
public static final double CAMERA_LATITUDE_BASE = 36.350062;
public static final double CAMERA_LONGITUDE_BASE = 127.415690;
public static final int CAMERA_LEVEL = 6;
protected Marker currentLocation;
private SmartPhoneGpsSenser gpsSenser; //GPS 센서와 연동하는 클래스
private int nGpsRequstKind = 0; //GPS 요청시 현재위치를 중심으로 화면을 이동할지, 이동하지 않을지 구분하기 위한 변수
private boolean followLocation = false; //현재위치를 지도 카메라가 따라갈지 여부를 결정하는 변수
protected InternetConnectCheck mInternetConnectCheck;
//마커의 말풍선 동작 상태를 전달하는 사용자 콜백 리스너
protected OnGetMarkerInfoWindowStateListener mOnGetMarkerInfoWindowStateListener;
public interface OnGetMarkerInfoWindowStateListener {
/**
* 마커의 말풍선 동작 상태를 전달하는 사용자 콜백 리스너
*/
public void onGetMarkerInfoWindowState(Record rec, boolean isInfoWindowShow, int eventState);
}
public void setOnGetMarkerInfoWindowStateListener(OnGetMarkerInfoWindowStateListener listener) {
mOnGetMarkerInfoWindowStateListener = listener;
}
// 마커 클릭시 호출되는 사용자 콜백 리스너
private OnMarkerClickListener mOnMarkerClickListener;
public interface OnMarkerClickListener {
/**
* 마커 클릭시 호출되는 사용자 콜백 리스너
*/
public void onMarkerClick(double latitude, double longitude);
}
public void setOnMarkerClickListener(OnMarkerClickListener listener) {
mOnMarkerClickListener = listener;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
view = inflater.inflate(R.layout.google_map_fragment, container, false);
btnSetCurrentPoint = (ImageButton)view.findViewById(R.id.btn_set_current_point);
btnSetCurrentPoint.setOnClickListener(this);
btnMapSendExternalApp = (ImageButton)view.findViewById(R.id.btn_map_send_external_app);
btnMapSendExternalApp.setOnClickListener(this);
btnZoomIn = (ImageButton)view.findViewById(R.id.btn_zoom_in);
btnZoomIn.setOnClickListener(this);
btnZoomOut = (ImageButton)view.findViewById(R.id.btn_zoom_out);
btnZoomOut.setOnClickListener(this);
mInternetConnectCheck = new InternetConnectCheck(getContext());
mGoogleMap = ((SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map)).getMap();
mGoogleMap.setOnMarkerClickListener(this);
mGoogleMap.setOnInfoWindowCloseListener(this);
mapInfo = new GoogleMapInfo();
mPolylineOptions = new PolylineOptions();
//화면 초기위치 지정
locCameraFocus = new LatLng(CAMERA_LATITUDE_BASE, CAMERA_LONGITUDE_BASE);
cp = new CameraPosition.Builder().target(locCameraFocus).zoom(CAMERA_LEVEL).build();
//좌표 초기 지정
latlngCameraCenter = new LatLng(CAMERA_LATITUDE_BASE, CAMERA_LONGITUDE_BASE);
mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cp)); //지정 위치로 맵 이동
//생성한 마커를 보관하기 위한 객체 생성
arrMarker = new ArrayList<MarkerOptions>();
return view;
}
private int getPixelsFromDp(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dp * scale + 0.5f);
}
public void setCenterLocation() {
isGetCenterLocation = true;
}
/**
* 마커를 입력 하는 메소드
*/
public void setMarkers(ArrayList<Record> markerInfo, String LattitudeKey, String LongitudeKey, float color, boolean isShowInfoWindow) {
for(int i=0 ; i < markerInfo.size() ; i++) {
Record rec = markerInfo.get(i);
setMarker(new LatLng(Double.parseDouble(rec.get(LattitudeKey)), Double.parseDouble(rec.get(LongitudeKey))), color, isShowInfoWindow);
}
}
/**
* 마커 지도에 표시
*/
public MarkerOptions setMarker(LatLng loc, float color, boolean isShowInfoWindow) {
marker = new MarkerOptions().position(loc);
marker.icon(BitmapDescriptorFactory.defaultMarker(color));
addMarker = mGoogleMap.addMarker(marker);
if (isShowInfoWindow) {
setInfoWindowAdapter();
}
return marker;
}
/**
* 마커 클릭시 표시할 InfoWindow(말풍선)을 Setting 하늠 메소드
*/
public void setInfoWindowAdapter() {
// 마커 클릭시 표시되는 snippet(말풍선) settting
mGoogleMap.setInfoWindowAdapter(new InfoWindowAdapter() {
@Override
public View getInfoContents(Marker marker) {
return null;
}
@Override
public View getInfoWindow(Marker selectMarker) {
return showInfoWindow(selectMarker);
}
});
}
/**
* 마커 클릭시 나타나는 infoWindow 팝업
*/
protected View showInfoWindow(Marker selectMarker) {
return null;
}
/* //마커 지도에 표시
public void setMarker(Record markerInfo, int mode) {
//이벤트가 정상일 경우 맵에 표시 안함
if (markerInfo.containsKey("state") && markerInfo.get("state").equals("0")) {
return;
}
if (markerInfo.containsKey("event_point_latitude") && !markerInfo.get("event_point_latitude").equals("")) {
LatLng loc = new LatLng(Double.parseDouble(markerInfo.get("event_point_latitude")),
Double.parseDouble(markerInfo.get("event_point_longitude")));
marker = new MarkerOptions().position(loc);
//마커 색 지정
if (markerInfo.containsKey("state")){
int state = Integer.parseInt(markerInfo.get("state"));
if (state == 0) { //정상
marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory. HUE_GREEN));
} else if (state == 1) { //누수
marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory. HUE_BLUE));
} else if (state == 2) { //파손
marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory. HUE_RED));
} else if (state == 3) { //예방 시트 파손
marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW));
}
}
if (mode == Common.SETTING) {
mGoogleMap.setOnMarkerDragListener(this); //마커 드래그 될때마다 호출되는 리스너 연결
marker.draggable(true); //마커 드래그 가능하도록 지정
} else {
marker.draggable(false); //마커 드래그 불가능 하도록 지정
// }
} else {
//=============================================현장에 저장된 기본 좌표값 적용
}
if (mode == 0) {
addMarker = mGoogleMap.addMarker(marker);
} else if (mode == 1) {
addMarker = mGoogleMap.addMarker(marker);
addMarker.showInfoWindow();
//카메라 뷰 이동
setCamera(Double.parseDouble(markerInfo.get("event_point_latitude")),
Double.parseDouble(markerInfo.get("event_point_longitude")), 17);
//선택된 마커정보 초기화
Common.SELECT_RTD_ID = null;
Common.SELECT_CHANNEL_ID = null;
}
}
*/
/**
* 맵에 마커를 추가하는 메소드
*/
public void addMarker(MarkerOptions options) {
mGoogleMap.addMarker(options);
}
//이벤트 발생 위치 정보인 위도, 경도로 텍스트 주소를 알아내는 메소드
protected String getMarkerLocation(String latitude, String longitude) {
List<Address> locationInfoList = null;
String location = latitude + "," + longitude;
Geocoder geocoder = new Geocoder(getContext());
try {
locationInfoList = geocoder.getFromLocationName(location, 3);
return locationInfoList.get(0).getAddressLine(0) ;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
//마커 드래그시 호출되는 리스너
@Override
public void onMarkerDrag(Marker markerPosition) {
latlngCameraCenter = markerPosition.getPosition();
}
@Override
public void onMarkerDragEnd(Marker markerPosition) {}
@Override
public void onMarkerDragStart(Marker markerPosition) {}
//마커의 위도 출력
public double getMarkerLatitude() {
if (marker != null) {
return latlngCameraCenter.latitude;
} else return 0;
}
//마커의 위도 출력
public double getMarkerLongitude() {
// marker.position(marker.getPosition());
if (marker != null) {
return latlngCameraCenter.longitude;
} return 0;
}
//마커 클릭시 처리되는 리스
@Override
public boolean onMarkerClick(Marker marker) {
setCamera(marker.getPosition().latitude, marker.getPosition().longitude, 19);
// mOnMarkerClickListener.onMarkerClick(marker.getPosition().latitude, marker.getPosition().longitude);
return false;
}
/**
* 구글 맵에 표시된 정보 전부 지움
*/
public void setGoogleMapClear() {
mGoogleMap.clear();
}
/**
* 폴리 라인 옵션 설정
*/
public PolylineOptions setPolyLineOption(int colorNum) {
PolylineOptions mp = new PolylineOptions();
mp.width(mapInfo.getStrokeweight());
mp.color(mapInfo.getChnnelColor(colorNum));
return mp;
}
/**
* 폴리라인 그리기
*/
public void addPolyline(PolylineOptions options) {
mGoogleMap.addPolyline(options);
}
//GoogleMap에 표시할 카메라 위치 , 크기 지정
public void setCameraLocation(String startLatitude, String startLongitude, String endLatitude, String endLongitude) {
// 시작 좌표와 끝좌표가 존재 하지 않을경우 처리 미적용===============================================================
int zoom = getCameraZoom(startLatitude, startLongitude, endLatitude, endLongitude);
setCamera(startLatitude, startLongitude, endLatitude, endLongitude, zoom);
}
//좌표 값을 계산해 화면 줌 크기 결정 (줌 범위는 2 ~ 21 - 숫자가 클수록 확대)
public int getCameraZoom(String startLatitude, String startLongitude, String endLatitude, String endLongitude) {
int zoom = 0;
//시작좌표와 끝좌표가 입력되었으면
if (startLatitude != null && !startLatitude.equals("") && endLatitude != null && !endLatitude.equals("")) {
//시작 위도와 끝 위도의 차를 구함
double diflat = (Double.parseDouble(startLatitude) - Double.parseDouble(endLongitude)) * 100000;
//시작 경도와 끝 경도의 차를 구함
double difLon = (Double.parseDouble(startLongitude) - Double.parseDouble(endLongitude)) * 100000;
// 구한 값을 무조껀 +부호로 변환
int differenceLatitude = (int) Math.abs(diflat);
int differenceLongitude = (int) Math.abs(difLon);
//위도 값에 따라 zoom 계산
int zoomLatitude = 21 - (differenceLatitude / 2000000);
//경도 값에 따라 zoom 계산
int zoomLongitude = 21 - (differenceLongitude / 2000000);
if (zoomLatitude < zoomLongitude) {
zoom = zoomLatitude;
} else {
zoom = zoomLongitude;
}
return zoom;
} else { //시작좌표와 끝좌표가 입력 되지 않았으면
return 20;
}
}
//Map의 카메라 위치를 지정 (줌 범위는 2 ~ 21 - 숫자가 클수록 확대)
public boolean setCamera(double latitude, double longitude, int zoom) {
locCameraFocus = new LatLng(latitude, longitude);
cp = new CameraPosition.Builder().target(locCameraFocus).zoom(zoom).build();
if (mGoogleMap != null) {
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cp);
mGoogleMap.moveCamera(cameraUpdate); //지정 위치로 맵 이동
}
return true;
}
//Map의 카메라 위치를 지정
public void setCamera(String startLatitude, String startLongitude, String endLatitude, String endLongitude, int zoom) {
double averageLat;
double averageLog;
//시작좌표와 끝좌표가 입력되었으면
if (startLatitude != null && !startLatitude.equals("") && endLatitude != null && !endLatitude.equals("")) {
//시작 위도와 끝 위도의 평균을 구함
averageLat = (Double.parseDouble(startLatitude) + Double.parseDouble(endLatitude)) /2;
//시작 경도와 끝 경도의 평균을 구함
averageLog = (Double.parseDouble(startLongitude) + Double.parseDouble(endLongitude)) /2;
} else {
//현장의 좌표를 읽어와 화면에 출력
//---------------------------임시로 본사 좌표 지정
averageLat = 37.402258;
averageLog = 126.709513;
}
LatLng locCameraFocus = new LatLng(averageLat, averageLog);
CameraPosition cp = new CameraPosition.Builder().target(locCameraFocus).zoom(zoom).build();
mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cp)); //지정 위치로 맵 이동
}
//지도 내용 초기화
public void setInitialization() {
mGoogleMap.clear();
latlngCameraCenter = new LatLng(CAMERA_LATITUDE_BASE, CAMERA_LONGITUDE_BASE);
marker = null;
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_set_current_point) {
setCurrentLocationMarker(nGpsRequstKind);
} else if (v.getId() == R.id.btn_map_send_external_app) {
CaptureMapScreen();
} else if (v.getId() == R.id.btn_zoom_in) {
mGoogleMap.animateCamera(CameraUpdateFactory.zoomIn()); //카메라 확대
} else if (v.getId() == R.id.btn_zoom_out) {
mGoogleMap.animateCamera(CameraUpdateFactory.zoomOut()); //카메라 축소
}
}
/**
* 지도에 현재 위치를 표시하는 메소드
*/
public void setCurrentLocationMarker(int gpsRequstKind) {
if (gpsSenser == null) {
gpsSenser = new SmartPhoneGpsSenser(getActivity(), getContext()); //스마트폰의 GPS 센서와 통신하는 클래스 생성
gpsSenser.setOnGpsLocationChangedListener(this);
}
LatLng location = null;
switch (gpsRequstKind) {
case 0 : //GPS가 켜져있지 않을 경우
//GPS좌표 재요청 (GPS센서가 ON 되어있지 않을 경우 GPS 설정 다이얼로그 팝업
location = gpsSenser.getLocation(2);
if (location != null) {
//현재위치로 카메라 이동
setCamera(location.latitude, location.longitude, 18);
btnSetCurrentPoint.setSelected(true);
gpsRequstKind = 1;
}
break;
case 1 :
double currentLetitude = Math.round(currentLocation.getPosition().latitude * 10000d) / 10000d;
double currentLongitude = Math.round(currentLocation.getPosition().longitude * 10000d) / 10000d;
latlngCameraCenter = mGoogleMap.getCameraPosition().target;
double cameraLetitude = Math.round(latlngCameraCenter.latitude * 10000d) / 10000d;
double cameraLongitude = Math.round(latlngCameraCenter.longitude * 10000d) / 10000d;
//현재 위치를 화면에 표시하지 않았거나 현재 화면의 중심과 현재위치가 같으면
if (currentLetitude != cameraLetitude || currentLongitude != cameraLongitude) {
//현재위치로 카메라 이동
setCamera(currentLetitude, currentLongitude, 18);
followLocation = false;
} else {
//현재위치를 실시간으로 따라가도록 적용
//현재위치로 카메라 이동
setCamera(currentLetitude, currentLongitude, 18);
currentLocation.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.follow_position));
followLocation = true;
gpsRequstKind = 2;
}
break;
case 2 :
currentLocation.remove();
gpsSenser.setStopGps();
btnSetCurrentPoint.setSelected(false);
followLocation = false;
gpsRequstKind = 0;
break;
}
if (location != null) {
if (currentMarker == null) {
currentMarker = new MarkerOptions();
}
currentLocation = mGoogleMap.addMarker(currentMarker.position(location).
icon(BitmapDescriptorFactory.fromResource(R.drawable.pointer)));
}
nGpsRequstKind = gpsRequstKind;
}
// GPS 센서로 수신받은 현재 위치가 변경되었을때 처리되는 리스너
@Override
public void onGpsLocationChanged(LatLng location) {
setCurrentLocationPoint(location);
if (followLocation) {
//현재위치로 카메라 이동
setCamera(location.latitude, location.longitude, 18);
}
}
//맵에 현재 위치를 표시하는 메소드
private void setCurrentLocationPoint(LatLng location) {
currentLocation.setPosition(location);
}
//현재 화면을 스크린샷 해서 리턴하는 메소드
private void CaptureMapScreen() {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M && !CheckPermission.checkPermissionWriteExternalStorage(getActivity())) { //SD카드에 쓰기 권한 요청 메소드
Toast.makeText(getActivity(), "지도 화면 공유 기능을 사용하려면 저장장치 사용 권한을 허용해야 합니다.\n허용 후 다시 시도해 주세요.", Toast.LENGTH_LONG).show();
return;
};
SnapshotReadyCallback callback = new SnapshotReadyCallback() {
@Override
public void onSnapshotReady(Bitmap snapshot) {
//세로 사이즈 줄이기
Matrix m = new Matrix();
Bitmap bitmap = Bitmap.createBitmap(snapshot, 0, 0, snapshot.getWidth(), snapshot.getHeight() - 400, m, false);
String fileName = System.currentTimeMillis() + ".png";
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 50, bytes); //PNG파일을 50 Quality로 지정
FileOutputStream fileOutputStream = new FileOutputStream("/mnt/sdcard/Download/" + fileName);
fileOutputStream.write(bytes.toByteArray()); //PNG 파일로 저장
File image = new File("/mnt/sdcard/download/" + fileName);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(image)); //PNG 파일의 URI를 Intent에 적용
shareIntent.setType("image/png");
startActivity(Intent.createChooser(shareIntent, "구글지도 이미지"));
} catch (Exception e) {
e.printStackTrace();
}
}
};
mGoogleMap.snapshot(callback);
}
@Override
public void onDestroyView() {
super.onDestroyView();
((ViewGroup) view.getParent()).removeView(view);
}
@Override
public void onInfoWindowClose(Marker marker) {
mOnGetMarkerInfoWindowStateListener.onGetMarkerInfoWindowState(null, false, 0);
}
}