InfoFragment와 MapFragment는 다음과 같이 기본 View Binding 구성에 텍스트뷰 하나만 표시하도록 하겠습니다. 프래그먼트에서 View Binding을 사용하는 방법에 대해서는 findViewById 대신 View Binding 사용하기를 참조하시기 바랍니다.
프래그먼트 클래스는 액티비티에서 구현할 때처럼 OnMapReadyCallback 을 구현하게 합니다. 우선은 onViewCreated에서 getMapAsync를 이용해 MapView를 초기화합니다. 그리고 OnMapReady에서 나머지 처리를 수행하면 됩니다. 여기서는 맵이 시작되면 카메라의 초기위치로 서울시청을 보여주도록 하였습니다. 그리고 onSaveInstanceState 설정을 하여 맵이 위치를 기억할 수 있도록 합니다.
LOCATION 관련 권한이 2개이므로 한번에 요청하도록 하겠습니다. 요청할 모든 권한을 REQUIRED_PERMISSIONS에서 배열형태로 준비합니다. 그리고 checkSelfPermission을 이용해 현재 앱이 REQUIRED_PERMISSIONS에서 정의한 모든 권한을 가지고 있는지 순회하면서 체크하고 만약 false가 반환되었다면 requestMultiplePermissions를 실행해 권한을 획득하도록 합니다. 권한 요청은 맵 프래그먼트가 시작되기 전에 이루어져야하기 때문에 메인액티비티에서 수행하도록 하겠습니다. 권한 요청에 대한 더 구체적인 설명은 Runtime Permission 이해하고 요청 구현하기를 참고하시기 바랍니다.
companionobject{privatevalREQUIRED_PERMISSIONS=arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION,)}overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(binding.root)setBottomNavigation()if(!isAllPermissionsGranted()){requestPermissionLauncher.launch(REQUIRED_PERMISSIONS)}}privatefunisAllPermissionsGranted():Boolean=REQUIRED_PERMISSIONS.all{permission->ContextCompat.checkSelfPermission(this,permission)==PackageManager.PERMISSION_GRANTED}privatevalrequestPermissionLauncher=registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()){permissions->permissions.entries.forEach{permission->when{permission.value->{Snackbar.make(binding.root,"Permission granted",Snackbar.LENGTH_SHORT).show()}shouldShowRequestPermissionRationale(permission.key)->{Snackbar.make(binding.root,"Permission required to use app!",Snackbar.LENGTH_SHORT).show()}else->Snackbar.make(binding.root,"Permission denied",Snackbar.LENGTH_SHORT).show()}}}
맵에 내 위치 표시하기
getUiSetting 이용하기
GoogleMap에 내장된 getUiSetting 을 이용하면 다음과 같은 위치표시 버튼을 맵에 표시할 수 있습니다. 옵션을 추가함으로써 Zoom control이나 Level picker도 표시하게 할 수 있습니다.
맵 상에 위치표시 버튼을 보여주게 하려면 onMapReady에서 map 객체를 획득한 후 다음 작업을 수행하면 됩니다. 위치권한을 사용해야 하는 작업인데 프래그먼트에서 권한을 획득하는 로직이 없으므로 Missing permissions 경고가 발생합니다. 하지만 권한은 액티비티에서 이미 취득했으므로 경고를 무시하기 위해 @SuppressLint("MissingPermission") 어노테이션을 붙여줍니다.
이 때 lastLocation은 다음과 같은 경우에 null이 될 수 있기 때문에 null 체크를 해 주어야 합니다.
Location is turned off in the device settings. The result could be null even if the last location was previously retrieved because disabling location also clears the cache.
The device never recorded its location, which could be the case of a new device or a device that has been restored to factory settings.
Google Play services on the device has restarted, and there is no active Fused Location Provider client that has requested location after the services restarted. To avoid this situation you can create a new client and request location updates yourself. For more information, see Receiving Location Updates.
생명주기 관리
프래그먼트의 생명주기에 따라 구글맵을 관리하기 위한 처리를 해 줍니다. 맵을 액티비티에서 SupportMapFragment로 구현할 경우에는 신경쓰지 않아도 되는 부분입니다.