인터넷 접근을 막아둔 상태에서 현재 시각이 필요한 상황.
gps를 이용해 현재위치를 가져오고 현재위치의 경도 값으로 시간을 가져오기로 했다.
1. Manifest에 위치 기반 서비스를 이용하기 위한 permission 추가
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
2. FINE_LOCATION에 접근하기 위해 명시적 퍼미션
var permissionLauncher = registerForActivityResult<String, Boolean>(ActivityResultContracts.RequestPermission(),
object : ActivityResultCallback<Boolean?> {
override fun onActivityResult(result: Boolean?) {
result?.let {
// 위치 정보 제공 허용했을 경우
return
}
// 위치 정보 제공 거부했을 경우
}
})
위치 정보 퍼미션을 요청하고 그에 대한 결과를 받아오는 작업을 하는 permissionLauncher를 만든다.
val checkPermission = checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
if (checkPermission == PackageManager.PERMISSION_DENIED) permissionLauncher.launch(android.Manifest.permission.ACCESS_FINE_LOCATION)
onCreate() 되었을때, 퍼미션이 거부되어있다면 permissionLauncher를 이용하여 퍼미션 작업을 한다.
3. 위치 정보 받아오는 메소드
위치 정보 관리자 역할을 하는 locationManager
객체를 생성한다.
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
다른 메소드에서도 불러서 사용할 수 있도록 전역변수에 대입해주었다.
private fun findLocation() {
if (ActivityCompat.checkSelfPermission(
this, android.Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this, android.Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) return
locationManager!!.apply {
when {
isProviderEnabled("fused") -> location = getLastKnownLocation("fused")
isProviderEnabled("gps") -> location = getLastKnownLocation("gps")
isProviderEnabled("network") -> location = getLastKnownLocation("network")
}
}
location?.let {
latitude = location!!.latitude
longitude = location!!.longitude
}
Toast.makeText(this@MainActivity, "$latitude, $longitude", Toast.LENGTH_SHORT).show()
}
퍼미션을 체크해주고, 해당하는 provider로 대응하기위해 분기문으로 나누어 작업한다.(gps겠지만...)
받아온 location 값이 null이 아니라면 전역변수에 있는 위도/경도 변수에 대입해주고 토스트를 띄운다 🍞
4. 받아온 경도 값 이용하여 현재 시각 가져오기
private fun findTime() {
location?.let {
latitude = location!!.latitude
longitude = location!!.longitude
}
val timeZone = getTimeZone(latitude, longitude)
val currentTime = getCurrentTime(timeZone)
Toast.makeText(this@MainActivity, currentTime, Toast.LENGTH_SHORT).show()
}
전역변수에 넣어둔 값을 가져와서 다음 메소드를 이용해 값을 찾아오면 된다.
private fun getTimeZone(latitude: Double, longitude: Double): TimeZone {
return TimeZone.getTimeZone(
TimeZone.getAvailableIDs((longitude * 10000).toInt()).firstOrNull { it.contains('/') }
?: TimeZone.getDefault().id)
}
private fun getCurrentTime(timeZone: TimeZone): String {
val calendar: Calendar = Calendar.getInstance(timeZone)
val hour: Int = calendar.get(Calendar.HOUR_OF_DAY)
val minute: Int = calendar.get(Calendar.MINUTE)
val second: Int = calendar.get(Calendar.SECOND)
return String.format("%02d:%02d:%02d", hour, minute, second)
}
위도는 날씨, 경도는 시간이라고 배웠으니...
경도값을 기준으로 TimeZone을 리턴받고 여기서 리턴받은 TimeZone 객체를 이용하여 Calendar 객체에게 시/분/초 값을 원하는 포맷으로 받아온다. 끝!