안드로이드 Q에서 디바이스의 발열 상태를 알 수 있는 API를 제공하기 시작하였습니다. 앱은 PowerManager에 Thermal Status Listener를 등록함으로써 디바이스의 발열 상태 변화를 알 수 있습니다. 발열 상태는 CRITICAL, EMERGENCY, LIGHT, NONE 등 총 7개의 상태가 있습니다.
앱이 디바이스의 Thermal status를 알 수 있도록 API를 제공하는 이유는, 디바이스의 온도가 매우 높아져 CPU, GPU의 클럭이 낮아지는 경우 앱이 원하는 퍼포먼스를 낼 수 없기 때문입니다. 만약 온도가 매우 높아졌다면, 앱은 저하된 디바이스 성능에 맞춰 원활한 퍼포먼스를 유지하기 위해서 작업을 줄여야 합니다. 예를 들어, 스트리밍 앱은 해상도를 낮춰 네트워크 트래픽을 낮출 수 있고, 카메라 앱은 이미지 보정을 줄일 수 있습니다. 또한, 게임 앱은 프레임 속도를 조절하여 저하된 성능에 원하는 퍼포먼스를 낼 수 있습니다.
이런 동작은 디바이스의 시스템을 보호하려고 유도하는 것일 수 있지만, 앱 또한, 실행 중인 앱의 퍼포먼스 관점에서 매우 중요할 수 있습니다. Q 이전 버전의 디바이스에서 삼성, 화웨이 등의 제조사는 개별적으로 제공하는 API가 있었거나, 아니면 제조사만 사용하는 API가 있었을지 모릅니다.
하지만, Q 이후부터는 AOSP(Android Open Source Project) 자체적으로 Public API를 제공합니다. 현재 Android Q 버전의 PIXEL 폰에서 이 API는 정상적인 동작을 보장합니다. 앞으로, 다른 제조사에서도 Thermal API에 대한 동작이 지원될 것 같습니다.
이 글을 쓰는 현재는, 안드로이드 Q 베타를 진행하고 있고 SDK API까지만 공개된 상태입니다. 이런 정보들로 간단히 Thermal Status Listener를 등록하여 상태를 모니터링하는 코드를 구현해보겠습니다.
이 글에서 소개하는 코드는 모두 코틀린으로 작성되었습니다.
Thermal Status
아래와 같이 Thermal 상태는 7개입니다. Android Developer - PowerManager에서 상태와 의미를 가져왔습니다.
- THERMAL_STATUS_NONE: Not under throttling.
- THERMAL_STATUS_LIGHT: Light throttling where UX is not impacted.
- THERMAL_STATUS_MODERATE: Moderate throttling where UX is not largely impacted.
- THERMAL_STATUS_SEVERE: Severe throttling where UX is largely impacted.
- THERMAL_STATUS_CRITICAL: Platform has done everything to reduce power.
- THERMAL_STATUS_EMERGENCY: Key components in platform are shutting down due to thermal condition. Device functionalities will be limited.
- THERMAL_STATUS_SHUTDOWN: Need shutdown immediately.
맨 위의 NONE이 온도가 가장 낮은 것이고, 아래로 갈 수록 온도가 높은 상태입니다.
현재 Thermal Status 가져오기
PowerManager.currentThermalStatus
는 현재의 Thermal status를 리턴하는 API입니다.
val powerManager = getSystemService(Context.POWER_SERVICE) as? PowerManager
Log.d(TAG, "get current Thermal status: ${powerManager?.currentThermalStatus}")
Thermal Listener 등록
아래와 같이 PowerManager에 Listener를 등록하여 Thermal Status 변화를 받을 수 있습니다.
val powerManager = getSystemService(Context.POWER_SERVICE) as? PowerManager
powerManager?.addThermalStatusListener { status ->
when (status) {
PowerManager.THERMAL_STATUS_SHUTDOWN -> {
Log.d(TAG, "THERMAL_STATUS_SHUTDOWN")
}
PowerManager.THERMAL_STATUS_EMERGENCY -> {
Log.d(TAG, "THERMAL_STATUS_EMERGENCY")
}
PowerManager.THERMAL_STATUS_CRITICAL -> {
Log.d(TAG, "THERMAL_STATUS_CRITICAL")
}
PowerManager.THERMAL_STATUS_SEVERE -> {
Log.d(TAG, "THERMAL_STATUS_SEVERE")
}
PowerManager.THERMAL_STATUS_MODERATE -> {
Log.d(TAG, "THERMAL_STATUS_MODERATE")
}
PowerManager.THERMAL_STATUS_LIGHT -> {
Log.d(TAG, "THERMAL_STATUS_LIGHT")
}
PowerManager.THERMAL_STATUS_NONE -> {
Log.d(TAG, "THERMAL_STATUS_NONE")
}
}
}
리스터로 콜백을 받을 때 Main thread가 콜백을 해 줍니다. 만약 다른 스레드에서 동작하길 원한다면 아래 API를 사용해야 할 것 같습니다. 테스트 해보진 않았습니다. 좀 더 자세한 것은 Android Developer - PowerManager에서 확인해주세요.
void addThermalStatusListener(Executor executor, PowerManager.OnThermalStatusChangedListener listener)
Thermal Listener 해제
리스너를 해제할 때는 등록할 때 사용한 OnThermalStatusChangedListener
객체를 인자로 전달해줘야 합니다.
다음과 같이 리스너 객체를 멤버 변수로 선언하고, 이 객체를 등록할 때와 해제할 때 사용하시면 됩니다.
val powerManager = getSystemService(Context.POWER_SERVICE) as? PowerManager
val thermalStatusListener =
PowerManager.OnThermalStatusChangedListener { status ->
when (status) {
//....
}
}
powerManager?.addThermalStatusListener(thermalStatusListener)
powerManager?.removeThermalStatusListener(thermalStatusListener)
정리
안드로이드 Q에서 제공되는 Thermal Status API에 대해서 알아보고, 간단히 구현도 해보았습니다. API에 대한 자세한 내용은 Android Developer에서 확인하실 수 있습니다.
참고
Related Posts
- Android 14 - 사진/동영상 파일, 일부 접근 권한 소개
- Android - adb push, pull로 파일 복사, 다운로드
- Android 14 - 암시적 인텐트 변경사항 및 문제 해결
- Jetpack Compose - Row와 Column
- Android 13, AOSP 오픈소스 다운로드 및 빌드
- Android 13 - 세분화된 미디어 파일 권한
- Android 13에서 Notification 권한 요청, 알림 띄우기
- Android 13에서 'Access blocked: ComponentInfo' 에러 해결
- 에러 해결: android gradle plugin requires java 11 to run. you are currently using java 1.8.
- 안드로이드 - 코루틴과 Retrofit으로 비동기 통신 예제
- 안드로이드 - 코루틴으로 URL 이미지 불러오기
- Android - 진동, Vibrator, VibrationEffect 예제
- Some problems were found with the configuration of task 에러 수정
- Query method parameters should either be a type that can be converted into a database column or a List
- 우분투에서 Android 12 오픈소스 다운로드 및 빌드
- Android - ViewModel을 생성하는 방법
- Android - Transformations.map(), switchMap() 차이점
- Android - Transformations.distinctUntilChanged() 소개
- Android - TabLayout 구현 방법 (+ ViewPager2)
- Android - 휴대폰 전화번호 가져오는 방법
- Android 12 - Splash Screens 알아보기
- Android 12 - Incremental Install (Play as you Download) 소개
- Android - adb 명령어로 bugreport 로그 파일 추출
- Android - adb 명령어로 App 데이터 삭제
- Android - adb 명령어로 앱 비활성화, 활성화
- Android - adb 명령어로 특정 패키지의 PID 찾기
- Android - adb 명령어로 퍼미션 Grant 또는 Revoke
- Android - adb 명령어로 apk 설치, 삭제
- Android - adb 명령어로 특정 패키지의 프로세스 종료
- Android - adb 명령어로 screen capture 저장
- Android - adb 명령어로 System 앱 삭제, 설치
- Android - adb 명령어로 settings value 확인, 변경
- Android 12 - IntentFilter의 exported 명시적 선언
- Android - adb 명령어로 공장초기화(Factory reset)
- Android - adb logcat 명령어로 로그 출력