본문 바로가기
Android 개발/Service, Receiver

Broadcast Receiver 등록하고 시스템 이벤트 받아서 처리하기

by Developer88 2023. 5. 23.
반응형

안드로이드의 시스템은 이벤트가 발생할 때 broadcast를 보내줍니다. 

 

이름이 broadcast이니, 방송을 한다고 해야할까요.

안드로이드 내부적으로 이벤트가 발생을 했다고 알려주는 것인데요,

 

안드로이드 앱에서, 시스템에게 특정한 이벤트에 관해 관심이 있다고 등록을 하면,

broadcast를 수신할 수 있게 되는데요.

 

오늘은 사용자가 이어폰을 스마트폰에서 빼거나 꽂았을 때, 

시스템 이벤트를 받아서 토스트 팝업을 띄우는 방법에 대해서 정리해보겠습니다.

네이버 뮤직 같은 앱들이 헤드폰을 빼거나 꽂았을 때, 플레이를 멈추도록 하는 기능도 broadcastReceiver를 이용했을 거라고 생각이 됩니다.

 

1. BroadCast 받는 방법

안드로이드의 시스템으로부터는 여러가지 broadcast를 받아서 볼 수 있는데요,

 

예를 들면, 사용자가 이어폰을 뺏다던가, 에어플레인 모드를 켯다껏다 하는 이벤트들입니다.

이러한 액션들의 리스트는, 코딩을 하시면서 안드로이드 스튜디오의 도움을 받을수도 있지만,

android의 sdk안에 있는 BROADCAST_ACTIONS.TXT에도 기술이 되어있는데요. 

 

아래 링크에 해당하는 action들의 리스트를 볼 수 있습니다.

>>https://chromium.googlesource.com/android_tools/+/febed84a3a3cb7c2cb80d580d79c31e22e9643a5/sdk/platforms/android-23/data/broadcast_actions.txt

 

2. Broadcast에 등록하는 방법

broadcast를 들을려면, 내가 이러이러한 이벤트에 관심이 있으니 듣겠다고 등록을 해야하는데요.

아래에서 구체적인 방법들을 정리해보겠습니다.

 

2-1. Receiver Class 작성

먼저 BroadcastReceiver클래스를 작성해서, 이벤트를 들으면 어떻게 할지를 적어야 하는데요.

TestousReceiver라는 클래스를 만들고,

BroadcastReceiver를 상속해주면 구현해야할 메소드가 나옵니다.

 

저희가 구현해야할 메소드는 onReceive()인데요.

이름에서 알 수 있듯이, 이벤트가 발생하면 어떻게 할지를 구현해주라는 거죠.

저희는 유저가 헤드폰을 뽑거나 꽂으면, 토스트 팝업을 보여주도록 할 것이기 때문에,

여기서는 인자로 들어오는 context를 가지고, 토스트팝업을 띄우겠습니다.

 

한가지 생각해 두어야 할 점은,

onReceive에서 작동되는 코드는 MainThread에서 실행된다는 점과

안드로이드 시스템에서는 10초를 넘어가는 수준의 과업이 실행되는 것을 원하지 않고,

그럴 경우 앱을 죽일 수도 있다는 점 입니다.

따라서 여기서는 Service를 실행시키거나, 노티피케이션을 보내는 등의 간단한 과업만을 실행 시켜야 겠지요.

 

class TestouseReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "헤드폰을 끼우거나 뽑으셨네요", Toast.LENGTH_LONG).show()
    }
}

 

 

2-2. receiver 등록

이제, Activity로 넘어와서 reciever를 등록해보겠습니다.

등록을 하는데는 registerReceiver()라는 메소드를 사용하면되는데요.

인자로 receiver와 IntentFilter를 넘겨주면 됩니다.

 

저는 사용자가 이어폰을 뽑았을 때, 알려주는 ACTION_HEADSET_PLUG에 관심이 있으므로,

이 액션에 관심이 있다고 필터에 인자로 주도록 하겠습니다.

 

class MainActivity : AppCompatActivity() {

    private lateinit var receiver: TestouseReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        receiver = TestouseReceiver()

        val filter = IntentFilter().apply {
            addAction(Intent.ACTION_HEADSET_PLUG)
        }
        registerReceiver(receiver, filter)
    }

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

 

 

참고로 이렇게 액션이라고 할지라도, 권한을 요청하는 경우가 있는데요, 확인해보아야 합니다.

예를들면,  ACTION_BOOT_COMPLETED같은 경우는 Manifest에서 uses-permission을 해줘야 하구요.

ACTION_HEADSET_PLUG 도 API29 부터는 READ_PHONE_STATE 권한을 필요로 합니다.

READ_PHONE_STATE 권한은 manifest 뿐만이 아니라, 동적으로도 요청해야 하는 권한입니다.

 

2-3. Service 에서의 사용

Service내에서도 Receiver를 등록해 받을 수 있습니다.

 

먼저 receiver를 아래와 같이 선언해 주고요.

화면이 꺼지는 경우에 Intent.ACTION_SCREEN_OFF를 시스템으로부터 받을 수 있는데요.

이것을 등록해서 onReceive 로 받아 보겠습니다.

(아래의 getVibrated라는 메소드는 진동을 울리게 하는 custom 메소드입니다.)

 

private val screenOffReceiver: BroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_SCREEN_OFF) {
            getVibrated()
        }
    }
}

 

 

이렇게 Recevier를 생성해 준 다음,

Service의 onCreate()에서 아래와 같이 registerReceiver메소드를 이용해서 등록해주면 됩니다.

 

val screenOffFilter = IntentFilter().apply {
    addAction(Intent.ACTION_SCREEN_OFF)
}
registerReceiver(screenOffReceiver, screenOffFilter)

 

2-4. onDestroy 에서의 unregister

onCreate()에서 등록해 주었으니,

onDestroy에서 해지도 해 주어야 하겠지요.

 

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

 

이상으로 Broadcast Receiver 를 등록하고 시스템 이벤트를 받아서 처리하는 방법에 대해서 정리해 보았습니다.

 

728x90

댓글