[Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린] 브로드캐스트 리시버 컴포넌트
안드로이드 앱 프로그래밍에서 브로드캐스트 리시버 컴포넌트의 이해와 구현 방법을 정리했다. 브로드캐스트 리시버는 시스템 이벤트를 처리하는 컴포넌트로, BroadcastReceiver 클래스를 상속받아 구현하며, 매니페스트 파일에 등록하거나 동적으로 등록할 수 있다. 또한, 부팅 완료, 화면 켜짐/꺼짐, 배터리 상태 등의 시스템 상태를 파악하는 방법도 다룬다. 각 상황에 맞는 리시버 등록과 해제 방법, 그리고 배터리 상태를 확인하는 코드 예제도 포함되어 있다.
Aug 19, 2024
🌼브로드캐스트 리시버 이해하기
💡브로드캐스트 리시버 만들기
- 브로드캐스트 리시버는 이벤트 모델로 실행되는 컴포넌트다.
- 이벤트란 액티비티를 다룰 때 발생하는 사용자 이벤트가 아닌 부팅이 완료되는 것과 같은 시스템의 특정한 상황을 의미한다.
- 브로드캐스트 리시버를 만들려면
BroadcastReceiver
를 상속받는 클래스를 선언해야 한다. - 브로드캐스트 리시버의 생명주기 함수는
onReceive()
하나뿐이다. onReceive()
함수는 실행한 후 10초 이내에 완료할 것을 권장하므로 오래 걸리는 작업을 담기에는 부적절하다.
// 브로드캐스트 리시버 만들기 class MyReceiver: BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent){ } }
<intent-filter>
를 선언해 줘야 한다.// 브로드캐스트 리시버 등록 <receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"></receiver>
- 브로드캐스트 리시버는 다른 안드로이드 컴포넌트와 같이 매니페스트에 등록해야 시스템에서 인지하고 어디선가 인텐트가 발생할 때 컴포넌트를 실행해 준다.
- 다만 브로드캐스트 리시버를 매니페스트에 등록하지 않고 코드에서 필요한 순간에 동적으로 등록할 수도 있다.
// 리시버 객체 생성 val receiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?){ } }
registerReceiver()
라는 함수를 이용해 시스템을 등록한다. 이 경우 등록하고자 하는 브로드캐스트 리시버 객체, 인텐트 필더 정보 이외에 공개상태 정보도 명시되어야 한다.// 동적 등록 registerReceiver(receiver, IntentFilter("ACTION_RECEIVER"), RECEIVER_EXPORTED)
registerReceiver()
함수로 등록한 리시버는 사용한 후 필요 없으면 해제해 줘야 한다. 이때 unregisterReceiver()
함수를 이용한다.// 브로드캐스트 리시버 해제 함수 unregisterReceiver(receiver)
특정 상황에서 브로드캐스트 리시버를 항상 실행해야 한다면 매니페스트 파일에 등록해서 사용하면 된다.
그러나 특정한 액티비티나 서비스가 동작할 때만 브로드캐스트 리시버를 실행해야 한다면 해당 컴포넌트가 실행될 때 동적으로 등록하는 방법을 사용한다.
💡브로드캐스트 리시버 실행하기
- 브로드캐스트 리시버를 실행하려면 인텐트가 필요하다. 리시버의 클래스명만 등록했으면 명시적 인텐트로 실행하고, 인텐트 필터를 등록했으면 암시적 인텐트로 실행한다.
- 만약 리시버를 매니페스트 파일에 등록하고 <intent-filter> 태그를 선언했다면 암시적 인텐트로는 실행할 수 없다.
// 리시버 실행 val intent = Intent(this, MyReceiver::class.java) sendBroadcast(intent)
🌼시스템 상태 파악하기
💡부팅 완료
- 안드로이드 기기의 전원을 켜면 시스템이 동작해 부팅이 시작되고 완료되면 사용자가 기기를 사용할 수 있는 상태가 된다.
// 브로드캐스트 리시버와 인텐트 필터 등록 <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"/>
💡화면 컴/끔
- 화면을 켜거나 끄는 상황을 감지하는 브로드캐스트 리시버는 매니페스트에 등록하면 실행되지 않는다. 액티비티나 서비스 컴포넌트의 코드에서 registerReceiver() 함수를 이용해 동적으로 등록해야만 한다.
// 화면 켬/끔 리시버 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") } } }
- 이렇게 정의한 브로드캐스트 리시버 객체는 액션 문자열 정보로 구성한 인텐트 필터와 함께
registerReceiver()
함수로 시스템에 등록한다.
// 리시버 등록 val filter = IntentFilter(Intent.ACTION_SCREEN_ON).apply{ addAction(Intent.ACTION_SCREEN_OFF) } registerReceiver(receiver, filter)
registerReceiver()
함수로 등록한 브로드캐스트 리시버는 필요 없는 순간이 되면unregisterReceiver()
함수로 등록을 해제해 줘야 한다.
// 리시버 등록 해제 unregisterReceiver(receiver)
💡배터리 상태
- 안드로이드 시스템에서 배터리 상태가 변경되면 다음 액션 문자열로 인텐트가 발생한다.
BATTERY_LOW
: 배터리가 낮은 상태로 변경되는 순간BATTERY_OKAY
: 배터리가 정상 상태로 변경되는 순간BATTERY_CHANGED
: 충전 상태가 변경되는 순간ACTION_POWER_CONNECTED
: 전원이 공급되기 시작한 순간ACTION_POWER_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_BATTERY_CONNECTED) addAction(Intent.ACTION_BATTERY_DISCONNECTED) } registerReceiver(receicer, filter)
- 그런데 시스템이 배터리 관련 인텐트를 발생시키지 않아도 현재 배터리 상태가 필요할 때도 있다.
// 시스템 인텐트 없이 배터리 상태 파악하기 val intentFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED) val batteryStatus = registerReceiver(null, intentFilter)
- 이 경우 위의 객체를 이용해서
registerReceiver()
함수의 반환값인 인텐트 객체의 엑스트라 정보로 브로드캐스트 리시버를 등록해야 한다.
// 인텐트의 엑스트라를 이용해 배터리 상태 파악하기 val status = batteryStatus!!.getIntExtra(BatteryManager.EXTRA_STATUS, -1) if(status == BatteryManager.BATTERY_STATUS_CHARGING){ // 전원이 공급되고 있다면 val chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_STSATUS, -1) when(chargePlug){ BatteryManager.BATTERY_PLUGGED_USB -> Log.d("kkang","usb charge") BatteryManager.BATTERY_PLUGGED_AC -> Log.d("kkang","ac charge") } }else{ // 전원이 공급되고 있지 않다면 Log.d("kkang","not charging") }
- 배터리가 얼마나 충전되었는지 알고 싶은 경우는 다음처럼 작성한다.
// 배터리 충전량을 퍼센트로 출력 val level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) val scale = batteryStatus.IntExtra(BatteryManager.Extra_SCALE, -1) val batteryPct = level / scale.toFloat() * 100 Log.d("kkang","batteryPct; $batteryPct")
🏁결론
안드로이드 앱 프로그래밍에서 브로드캐스트 리시버 컴포넌트의 이해와 구현 방법을 정리했다. 브로드캐스트 리시버는 시스템 이벤트를 처리하는 컴포넌트로,
BroadcastReceiver
클래스를 상속받아 구현하며, 매니페스트 파일에 등록하거나 동적으로 등록할 수 있다. 또한, 부팅 완료, 화면 켜짐/꺼짐, 배터리 상태 등의 시스템 상태를 파악하는 방법도 다룬다. 각 상황에 맞는 리시버 등록과 해제 방법, 그리고 배터리 상태를 확인하는 코드 예제도 포함되어 있다.Share article