권한 허용 여부를 묻는 창을 초기 화면으로 하고 모든 권한을 동시에 물으면 개발하기에는 편하지만 UX에는 좋지 않을 수 있다. 그래서 위치 권한이 필요한 지도 화면을 띄울 때나 갤러리에 접근하기 직전에 요청을 받아오기로 했다.
@Override
public void onMapReady(@NonNull NaverMap naverMap) {
this.naverMap = naverMap;
// 위치 권한 허용 여부 묻는 창
checkAndRequestLocationPermission();
// 지도가 멈출 때마다 가시적인 마커들을 표시
naverMap.addOnCameraIdleListener(() -> displayVisibleMarkers(naverMap));
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mapView.setVisibility(View.VISIBLE);
setMarkerAndMoveCameraToCurrentLocation(naverMap); // 권한이 허용되면 현재 위치로 마커를 찍는다.
} else {
mapView.setVisibility(View.VISIBLE); // 권한 거부에도 맵은 보여준다.
setMarkerAndMoveCamera(getDefaultLocation(), naverMap); // 권한이 거부되면 강남역에 마커를 찍는다.
}
}
}
private void setMarkerAndMoveCameraToCurrentLocation(NaverMap naverMap) {
getCurrentLocation(new LocationCallback() {
@Override
public void onLocationResult(LatLng location) {
if (location != null) {
setMarkerAndMoveCamera(location, naverMap);
} else {
setMarkerAndMoveCamera(getDefaultLocation(), naverMap);
}
}
});
}
// 주어진 위치에 마커를 설정하고 카메라를 해당 위치로 이동
private void setMarkerAndMoveCamera(LatLng markerPosition, NaverMap naverMap) {
currentLocationMarker.setPosition(markerPosition);
currentLocationMarker.setMap(naverMap);
currentLocationMarker.setIconTintColor(Color.RED);
naverMap.moveCamera(CameraUpdate.scrollTo(markerPosition).animate(CameraAnimation.Fly, 500));
}
// 기본 위치인 강남역의 좌표를 반환
private LatLng getDefaultLocation() {
return DEFAULT_LOCATION;
}
//위치를 반환하기 위한 콜백 인터페이스
public interface LocationCallback {
void onLocationResult(LatLng location);
}
// 현재 사용자의 위치를 가져오는 메소드
private void getCurrentLocation(LocationCallback callback) {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationClient.getLastLocation()
.addOnSuccessListener(getActivity(), location -> {
if (location != null) {
LatLng currentLocation = new LatLng(location.getLatitude(), location.getLongitude());
callback.onLocationResult(currentLocation);
} else {
callback.onLocationResult(null); // 위치 정보를 가져올 수 없을 경우
}
});
} else {
// 권한 요청 또는 권한 거부에 따른 추가 작업
requestLocationPermission();
}
}
// 위치 권한을 요청하는 메소드
private void requestLocationPermission() {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION);
}