[14. 브로드캐스트 리시버 컴포넌트]
[14-1. 브로드캐스트 리시버 이해하기]
[브로드캐스트 리시버] : 안드로이드 4개의 컴포넌트 中 하나
-브로드캐스트 리시버 : ‘시스템 이벤트’ 발생 시, 실행되는 컴포넌트
즉, 시스템에 특정 이벤트 발생 시, 알림을 받아서 처리하는 수신기
-이 역시 안드로이드의 컴포넌트. 따라서 ‘인텐트’를 시스템에 전달하여 실행 O
-안드로이드 컴포넌트는 매니페스트에 등록해야 시스템이 인지O
[브로드캐스트 리시버 생성]
(1) ‘일반’ 생성 방법
① 브로드캐스트 리시버 객체 생성
-BroadcastReceiver 상속받는 클래스 선언
-내부에 유일한 생명주기 함수 onReceive() 함수가 자동 호출/소멸됨
② 매니페스트 파일에 <receiver> 태그로 등록
<실행할 인텐트 지정> 명시적 인텐트로 실행 -> 클래스명만 등록 암시적 인텐트로 실행 -> <intent-fileter> 선언 필수 |
(2) ‘동적‘ 생성 방법
① 브로드캐스트 리시버 객체 생성
② 코드에서 registerReceiver() 함수로 시스템에 등록
-등록 위치 : 액티비티 or 서비스 컴포넌트의 코드에 함수로 등록
-매니페스트 파일에 <receiver>로 등록되어있지 않아도 시스템에서 리시버 존재 인지함
③ 코드에서 unregisterReceiver() 함수로 해제
-사용한 후 필요없으면 해제 필수
[브로드캐스트 리시버 실행]
-실행을 위해서는 ’인텐트‘ 필요
-시스템에 리시버 등록 시,
1) 명시적. 클래스명만 등록했다 -> 클래스 타입 래퍼런스 이용하여 실행
2) 암시적. 인텐트 필터로 등록했다. -> 암시적 인텐트로 실행
-인텐트는 실행할 브로드캐스트 리시버를 sendBroadcast() 함수로 시스템에 전달함 -시스템은 브로드캐스트 리시버 객체 생성하여 실행해줌 |
-'없으면 말고 있으면 모두 실행'하는 ’독특한 동작원리‘
-시스템에 해당 인텐트로 실행될 리시버 없어도 오류 발생 X. 여러 개 있으면 모두 실행 O
[14-2. 시스템 상태 파악]
구조 : 시스템 상태변화(이벤트 발생) -> 인텐트 발생(리시버 호출) -> 리시버 실행 |
-시스템에서 발생하는 인텐트 종류 多
[부팅 완료 상태]
① 부팅 완료되면
시스템에서 ’android.intent.action.BOOT_COMPLETED‘ 액션문자열 포함 인텐트 발생
② 이때 실행할 ’리시버‘ 등록 시, <action> 의 name 속성에 똑같은 액션문자열 지정 필수
<receiver
android:name = ‘.MyReceiver“
android:enabled=“true”
android:exported=“true”
<intent-filter>
<action android:name=“android.intent.action.BOOT_COMPLETED”/>
</intent-filter>
</receiver>
③ 리시버 실행 권한 필요 : 메니페스트에 퍼미션 추가
<uses-permission android:name=“android.permission.RECEIVE_BOOT_COMPLETED”/>
[화면 켬/끔 상태]
-화면 켬/끔 상황 감지 브로드캐스트 리시버는 매니페스트 파일 등록 시 실행 불가능
-따라서, 액티비티 or 서비스 컴포넌트에서 registerReceiver() 함수로 동적 등록 필수
<화면 켬> 시스템에서 ’android.intent.action.SCREEN_ON‘ 액션문자열 포함 인텐트 발생 <화면 끔> 시스템에서 ‘android.intent,action.SCREEN_OFF’ 액션문자열 포함 인텐트 발생 |
① 화면 켬/끔 상태 판단
-리시버는 자신을 호출한 Intent 객체의 액션 문자열을 토대로 상태 판단 O
receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when(intent?.action) {
Intent.ACTION_SCREEN_ON -> Log.d(“kkang”, “screen on”) //켤 때
Intent.ACTION_SCREEN_OFF -> Log.d(“kkang”, “screen off”) //끌 때
}
}
}
② ’브로드캐스트 리시버‘ 동적 등록
-리시버는 액션문자열 정보 구성한 인텐트 필터와 함께 시스템에 등록함
val filter = IntentFilter(Intent.ACTION_SCREEN_ON).apply{ //이 인텐트 액션 발생 시 실행되어야 하니ᄁᆞ
addAction(Intent.ACTION_SCREEN_OFF)
}
registerReceiver(receiver, filter) //리시버 등록
③ 등록 해제 : unregisterReceiver(receiver) 로 등록 해제함
[배터리 상태]
-기본적으로 시스템 상태 변경으로 인한 ’인텐트‘ 발생 시 ’리시버‘가 실행됨
① 시스템 배터리 상태 변화에 따른 관련 ’액션 문자열‘ 인텐트 발생
<배터리 관련 인텐트 액션 문자열>
BATTERY_LOW | 배터리 ‘낮은’ 상태로 변경되는 순간 |
BATTERY_OKAY | 배터리 ‘정상’ 상태로 변경되는 순간 |
BATTERY_CHANGED | 충전 상태 변경되는 순간 |
BATTERY_POWER_CONNECTED | 전원 공급 ‘시작’되는 순간 |
BATTERY_DISCONNECTED | 전원 공급 ‘끝난’ 순간 |
② 관련 액션 문자열 상태별. 실행될 브로드캐스트 리시버 작성
receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when(intent?.action) {
Intent.ACTION_BATTERY_OKAY -> Log.d(“kkang”, “ACTION_BATTERY_OKAY”)
Intent.ACTION_BATTERY_LOW -> Log.d(“kkang”, “ACTION_BATTERY_LOW”)
Intent.ACTION_BATTERY_CHANGED -> Log.d(“kkang”, “ACTION_BATTERY_CHANGED”)
Intent.ACTION_BATTERY_CONNECTED -> Log.d(“kkang”, “ACTION_BATTERY_CONNECTED”)
Intent.ACTION_BATTERY_DISCONNECTED -> Log.d(“kkang”, “ACTION_BATTERY_DISCONNECTED”)
}
}
}
③ 해당 액션 문자열 인텐트 발생 시, 실행될 리시버를 시스템에 등록
val filter = IntentFilter(Intent.ACTION_BATTERY_LOW).apply {
addAction(Intent.ACTION_BATTERY_OKAY)
addAction(Intent.ACTION_BATTERY_CHANGED)
addAction(Intent.ACTION_POWER_CONNECTED)
addAction(Intent.ACTION_POWER_DISCONNECTED)
}
registerReceiver(receiver, filter) //시스템에 리시버 등록
[시스템 상태 변경 없이도 ’상태 파악‘]
-기본적으로 리시버는 시스템 상태 변경되어 인텐트 발생시켜줘야만 실행이 됨
-BUT. 시스템 상태 변경 없이도 배터리 상태 파악 가능하기도 함
(1) 액션문자열 ’Intent.ACTION_BATTERY_CHANGED’ 로 지정한 IntentFilter 객체 만들고
(2) 인텐트의 엑스트라 정보 이용하여 registerReceiver() 함수로 리시버 등록
val intentFilter = IntentFileter(Intent.ACTION_BATTERY_CHANGED)
val batteryStatus = registerReceiver(null, intentFilter)
<< 인텐트의 엑스트라 정보 이용 -> 배터리 상태 파악 >>
[현재 전원 공급 여부 상태 파악]
-BatteryManager.EXTRA_STATUS 로 얻는 엑스트라값으로 알 수 있음
BatteryManager.BATTERY_STATUS_CHARGING | 전원 공급되는 상태 |
[이미 전원 공급 상태에 한해서 -> 다시 현재 ‘충전 상태 파악’]
-BatteryManager.EXTRA_PLUGGED 로 얻는 엑스트라값으로 알 수 있음
BatteryManager.EXTRA_PLUGGED_USB | 저속 충전 상태 |
BatteryManager.BATTERY_PLUGGED_AC | 고속 충전 상태 |
[배터리 충전량 상태 파악]
val level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
val batteryPct = level/scale.toFloat() * 100 // %로 출력가능
Log.d(“kkang”, “batteryPct : $batteryPct”)
[14-3. 배터리 정보 앱 만들기] : 실습
현재 배터리 상태 파악하여 결과를 화면에 출력 -> 화면에서 버튼 클릭 시 -> 브로드캐스트 리시버 실행하는 코드
class MainActivity : AppCompatActivity() { //메인 액티비티
override fun onCreate(savedInstanceState: Bundle?) { //실행 함수
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//add......................
registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))!!.apply { //리시버 등록 함수 (액션 문자열 -> 배터리 상태 변화 시) 실행될 리시버임
when (getIntExtra(BatteryManager.EXTRA_STATUS, -1)) { //현재 전원 공급 여부 확인용 엑스트라값 get 함
BatteryManager.BATTERY_STATUS_CHARGING -> { // (1) 현재 전원 공급 상태 O
when (getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)) { //(전원 공급상태에 한해서) 현재 충전량 확인용 엑스트라값 다시 get함
BatteryManager.BATTERY_PLUGGED_USB -> { // -> 현재 '저속 충전 상태'
binding.chargingResultView.text = "USB Plugged"
binding.chargingImageView.setImageBitmap(
BitmapFactory.decodeResource(resources, R.drawable.usb))
}
BatteryManager.BATTERY_PLUGGED_AC -> { // -> 현재 '고속 충전 상태'
binding.chargingResultView.text = "AC Plugged"
binding.chargingImageView.setImageBitmap(
BitmapFactory.decodeResource(resources, R.drawable.ac))
}
}
}
else -> { //(2) 현재 전원 공급 상태 X
binding.chargingResultView.text = "Not Plugged"
}
}
val level = getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale = getIntExtra(BatteryManager.EXTRA_SCALE, -1)
val batteryPct = level / scale.toFloat() * 100
binding.percentResultView.text = "$batteryPct %"
}
binding.button.setOnClickListener { //버튼 클릭 이벤트 연결
val intent = Intent(this, MyReceiver::class.java)
sendBroadcast(intent)
}
}
}
[참고] : Do It 안드로이드 앱 프로그래밍 with 코틀린 |
'App(앱)_관련 공부 모음 > [교재] Andorid App_Kotlin 기반' 카테고리의 다른 글
16. [콘텐츠 프로바이더 컴포넌트] (0) | 2022.03.24 |
---|---|
15. [서비스 컴포넌트] (0) | 2022.03.24 |
13. [액티비티 컴포넌트] (0) | 2022.03.18 |
12. [머티리얼 라이브러리] (0) | 2022.03.16 |
11. [제트팩 라이브러리] (0) | 2022.03.14 |