Developing Myself Everyday
article thumbnail

이 글에서는 Android의 4대 컴포넌트인 BroadCast receiver에 대해 더 자세하게 알아보고자 합니다.


 

 

BroadCast


Android 앱은 Android 시스템 및 기타 Android 앱에서 브로드캐스트 메시지를 받거나 보낼 수 있습니다. 관심 있는 이벤트가 발생할 때 이러한 브로드캐스트 메시지가 전송됩니다.

 

예를 들어 Android 시스템은 시스템 부팅 또는 기기 충전 시작, 배터리 부족과 같은 다양한 시스템 이벤트가 발생할 때 브로드캐스트 메시지를 전송합니다. 이런 브로드캐스트를 시스템 브로드캐스트 메시지라 합니다.

 

또한 앱은 맞춤 브로드캐스트 메시지를 전송하여 관련 앱에 알릴 수 있습니다. 앱 내에서 정의하고 발송해, 다른 앱이나 시스템에서 이를 수신하여 특정 작업을 수행하도록 유도합니다.

 

우리가 음악을 듣고 있을 때, 전화가 온다면 시스템은 모든 앱들에게 전화가 왔다는 것을 브로드캐스트 메시지로 알려줍니다. 그럼 음악 앱은 이것을 보고 음악을 멈추게 됩니다.

다만 브로드캐스트를 사용할 때 주의해야할 점이 있습니다.

 

브로드캐스트가 모든 앱에게 메시지를 전송한다는 점입니다. 따라서 브로드캐스트를 남용하거나 불필요한 상황에서 사용할 경우 앱 성능 저하나 배터리 소모 등의 문제가 발생할 수 있습니다. 또한, 보안과 관련된 이슈도 고려해야 합니다. 따라서 브로드캐스트 사용 시에는 신중하게 설계하고 관리해야 합니다.

 

 

 

 

 

BroadCast Recevier


우리의 앱에도 안드로이드 시스템에서 브로드캐스트 메시지가 보내질 때, 이를 수신해 반응하게 하고 싶습니다.

 

브로드캐스트를 수신하는 리시버를 등록하는 방법은 정적(Static) 등록동적(Dynamic) 등록가 있습니다.

 

 

동적 등록

동적 등록는 앱의 런타임 중에 동적으로 등록하는 방법입니다. 이는 앱이 실행되는 동안에만 활성화 되며, 앱이 종료되면 해당 리시버도 자동으로 해제됩니다.

 

시스템으로부터 비행기 모드로 변경했다는 브로드캐스트 메시지가 전송되었다고 생각해 보겠습니다. 동적 리시버를 구현하기 위해서는 `BroadcastReciver()` 클래스를 상속한 클래스를 만들어야 합니다.

class AirPlaneModeReceiver: BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action == Intent.ACTION_AIRPLANE_MODE_CHANGED) {
            val isTurnedOn = Settings.Global.getInt(
                context?.contentResolver,
                Settings.Global.AIRPLANE_MODE_ON
            ) != 0
            Log.d("TAG", "비행기 모드가 켜져있나요? $isTurnedOn")
        }
    }
}

리시버가 브로드캐스트 메시지를 수신하는 메서드가 바로 `onReceive()`입니다. 이 메서드를 통해 컨텍스트 정보와 브로드캐스트 메시지에 관한 정보를 가진 `intent`를 받습니다.

 

'Settings.Global.getInt(context?.contentResolver, Settings.Global.AIRPLANE_MODE_ON) != 0' 구문은 Settings.Global.AIRPLANE_MODE_ON 설정 값을 읽어와서 비행기 모드가 켜져 있는지 여부를 확인합니다. 비행기 모드가 켜져 있을 경우 값은 1, 꺼져 있을 경우 값은 0입니다.

 

 

이젠 브로드캐스트 리시버를 등록해 활성화해야 합니다.

class MainActivity : AppCompatActivity() {

    private val airPlaneModeReceiver = AirPlaneModeReceiver()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        registerReceiver(
            airPlaneModeReceiver,
            IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)
        )
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(airPlaneModeReceiver)
    }
}

 

`registerReceiver` 를 통해 브로드캐스트 리시버를 등록하고 활성화 합니다. 그리고 액티비티가 파괴될 때 더 이상 리시버는 필요하지 않으므로 `unregisterReceiver`를 통해 리시버를 해제해 줍니다.

 

 

리시버는 우리가 원할 때 동적으로 등록하고 해제합니다. 그렇기 이 리시버를 동적 리시버라 부릅니다.

 

 

 

정적 등록

앱이 실행되었을 때에는 동적 리시버를 사용하면 됩니다. 그렇다면 앱이 실행되지도 않은 시점에 안드로이드 시스템이 보내는 브로드캐스트 메시지를 수신하려면 어떻게 해야할까요? 이를 도와주는 것이 정적 리시버입니다.

 

다만 정적 리시버가 있는 경우 모든 앱은 브로드캐스트 메시지를 항상 확인하기 위해 수신기와 서비스가 백그라운드에 있어야 합니다. 그렇기에 안드로이드는 몇 가지 예외 또는 특별한 앱을 위해서만 정적 수신지를 사용하도록 합니다.

 

리시버를 정적으로 등록하는 방법은 manifest의 <application>에서 등록하면 됩니다.

<receiver
    android:name=".AirPlaneModeReceiver">
    <intent-filter>
        <action android:name="android.intent.action.AIRPLANE_MODE" />
    </intent-filter>
</receiver>

다만 위의 예시는 동작하진 않습니다. 비행기 모드를 수신하는 리시버는 오직 동적으로 등록해야 합니다. 

 

 

 

 

BroadCast 메시지 보내기


브로드캐스트 메시지를 전송하는 법은 매우 간단합니다. Intent를 사용하면 됩니다.

sendBroadcast(
    Intent("TEST_ACTION")
)

브로드캐스트 메시지를 보낼 때 Intent도 다르지 않습니다. putExtra로 원하는 데이터를 보낼 수도 있고 여러가지를 할 수 있습니다.

 

이를 수신하는 리시버를 만드는 것은 위에서 했던 내용의 반복입니다.

class TestReceiver: BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action == "TEST_ACTION") {
            Log.d("TAG", "테스트 브로드캐스트 메시지 수신 완료")
        }
    }
}

 

 

마무리하며


이렇게 브로드캐스트와 브로드캐스트 리시버에 대해 알아보았고, 어떻게 메시지를 받고 수신하는지 알아보았습니다. 아직 저도 프로젝트에서 해당 컴포넌트를 사용해 본적은 없지만, 이렇게 잘 짚고 넘어가면 언제든 다시 가져와서 사용할 수 있을 것이라 생각합니다.

 

 

 

 

 

 

 

profile

Developing Myself Everyday

@배준형

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!