브로드캐스트 리시버, 시스템 상태 파악하기

이윤설·2024년 9월 2일
0

브로드캐스트 리시버

브로드캐스트 리시버(Broadcast Receiver)는 안드로이드 애플리케이션에서 중요한 역할을 하는 컴포넌트다. 브로드캐스트 리시버는 시스템 또는 애플리케이션에서 발송된 브로드캐스트 인텐트를 수신하고 처리하는 역할을 한다.

여기서 브로드캐스트 인텐트는 특정 이벤트가 발생했음을 알리기 위해 시스템이나 애플리케이션이 발송하는 신호다. 이러한 이벤트는 시스템의 상태 변경, 배터리 상태, 네트워크 연결 상태 등 다양한 것들이 될 수 있다.

주요 기능과 특징

  1. 이벤트 수신: 브로드캐스트 리시버는 특정 인텐트를 수신하도록 등록되어 있으며, 등록된 인텐트가 발생하면 리시버가 해당 인텐트를 처리한다. 예를 들어, 배터리 부족 알림, 네트워크 연결 상태 변경 등 다양한 시스템 이벤트를 처리할 수 있다.

  2. 앱의 백그라운드 처리: 브로드캐스트 리시버는 앱이 백그라운드에 있을 때도 동작할 수 있어, 사용자에게 알림을 표시하거나 다른 처리를 수행할 수 있다.

  3. 등록 방식:

    • 매니페스트 등록: 애플리케이션의 AndroidManifest.xml 파일에 리시버를 선언하고, 이 파일에서 어떤 인텐트를 수신할지 정의한다. 이 방법은 시스템 부팅 완료, 네트워크 연결 상태 변경 등과 같은 전역적인 이벤트를 수신하는 데 사용된다.
    • 동적 등록: 애플리케이션 코드에서 registerReceiver() 메서드를 호출하여 동적으로 등록한다. 이 방법은 앱이 실행 중일 때만 이벤트를 수신하며, 앱이 종료되면 자동으로 리시버가 해제된다.
  4. 수명 주기: 브로드캐스트 리시버는 독립적으로 실행되지 않으며, 시스템에 의해 호출될 때만 활성화된다. 이벤트를 수신하고 처리한 후, 자동으로 종료된다.

  5. 퍼미션: 일부 브로드캐스트 인텐트는 퍼미션이 필요하다. 앱이 이러한 인텐트를 수신하기 위해서는 해당 퍼미션을 선언하거나, 인텐트를 발송할 때 퍼미션을 명시해야 한다.

예제 코드

1. 매니페스트에 리시버 등록하기

매니페스트 파일 (AndroidManifest.xml)에서 리시버를 등록하는 것은
앱이 어떤 종류의 알림을 받아야 하는지 시스템에 알려주는 일이다. 이 파일은 앱의 기본 정보를 담고 있는 곳이다.

예시:

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="com.example.broadcast.MY_NOTIFICATION"/>
    </intent-filter>
</receiver>
  • android:name=".MyBroadcastReceiver": 이 부분은 우리가 만들 리시버 클래스의 이름을 알려준다.
  • <action android:name="com.example.broadcast.MY_NOTIFICATION"/>: 이 부분은 어떤 종류의 알림을 받을지를 정의한다. 이 경우 "com.example.broadcast.MY_NOTIFICATION"이라는 이름의 알림을 받겠다는 뜻이다.

2. 리시버 클래스 정의하기

리시버 클래스는
앱이 알림을 받았을 때 어떤 행동을 취할지를 정의하는 곳이다. 이 클래스는 알림을 받기 위해 특별한 코드가 필요하다.

예시:

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log

class MyBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        // 알림을 받았을 때 실행될 코드
        Log.d("MyBroadcastReceiver", "Broadcast received!")
    }
}
  • BroadcastReceiver를 상속받아 MyBroadcastReceiver 클래스를 만든다.
  • onReceive() 메서드는 알림이 오면 호출된다. 여기서 알림이 왔다는 메시지를 로그로 기록한다. (로그는 개발 중에 디버깅 용도로 사용됨)

3. 액티비티에서 리시버 동적으로 등록하기

동적 등록은
앱이 실행 중일 때만 리시버를 사용하겠다는 뜻이다. 앱이 꺼지면 리시버도 자동으로 해제된다.

예시:

class MainActivity : AppCompatActivity() {

    private val myReceiver = MyBroadcastReceiver()

    override fun onResume() {
        super.onResume()
        // 어떤 알림을 받을지 정의합니다.
        val filter = IntentFilter("com.example.broadcast.MY_NOTIFICATION")
        // 리시버를 등록합니다.
        registerReceiver(myReceiver, filter)
    }

    override fun onPause() {
        super.onPause()
        // 리시버를 해제합니다.
        unregisterReceiver(myReceiver)
    }
}
  • private val myReceiver = MyBroadcastReceiver(): 리시버 객체를 생성한다.
  • onResume(): 앱이 화면에 나타날 때, 즉 사용자가 앱을 볼 때 리시버를 등록한다.
  • onPause(): 앱이 화면에서 사라질 때, 즉 사용자가 앱을 보지 않을 때 리시버를 해제한다. 이로써 앱이 필요 없는 시점에 리시버가 계속 동작하지 않도록 한다.

브로드캐스트 리시버를 활용하면 앱이 다양한 시스템 상태 변경을 감지하고 적절한 대응을 할 수 있습니다. 다만, 잘못 사용하면 배터리 소모를 유발할 수 있으므로 주의가 필요합니다.

카카오톡 예시

  1. 매니페스트 등록:
    카카오톡이 어떤 이벤트를 받을지를 정의한다. (예: 새로운 메시지 도착)

  2. 리시버 클래스:
    이벤트(예: 새로운 메시지)가 발생했을 때 카카오톡이 어떻게 반응할지를 정의한다.

  3. 동적 등록: 카카오톡이 사용 중일 때만 이벤트를 감지하도록 설정한다.

    • onResume(): 카카오톡의 채팅 화면이 보일 때(즉, 사용자가 채팅 화면을 보고 있을 때) 새로운 메시지 이벤트를 감지하도록 리시버를 등록한다.

    • onPause(): 채팅 화면이 다른 화면으로 전환되거나 앱이 백그라운드에 있을 때 리시버를 해제하여 이벤트를 더 이상 감지하지 않도록 한다.

용어 정리

1. 액티비티 인텐트 (Activity Intent)

  • 정의: 액티비티 간의 전환을 위해 사용된다.
  • 용도: 새로운 액티비티를 시작하거나 기존 액티비티에 데이터를 전달할 때 사용한다.
  • 예시: 사용자가 버튼을 클릭했을 때 다른 화면으로 이동하는 경우.

2. 서비스 인텐트 (Service Intent)

  • 정의: 백그라운드에서 실행되는 서비스와 상호작용하기 위해 사용된다.
  • 용도: 서비스 시작, 중지 또는 서비스에 데이터를 전달할 때 사용한다.
  • 예시: 음악 재생 서비스 시작, 다운로드 서비스 요청 등.

3. 브로드캐스트 인텐트 (Broadcast Intent)

  • 정의: 여러 앱에 동시에 메시지를 전달하기 위해 사용된다.
  • 용도: 시스템 이벤트나 앱 간의 통신을 위해 사용된다.
  • 예시: 배터리 상태 변화, 네트워크 연결 상태 변화 등을 알리는 경우.

4. 리시버 (Receiver)

  • 정의: 인텐트를 수신하고 처리하는 컴포넌트
  • 종류:
    • 액티비티 리시버: 액티비티에서 인텐트를 수신하여 UI를 업데이트하거나 다른 작업을 수행한다.
    • 서비스 리시버: 서비스에서 인텐트를 수신하여 백그라운드 작업을 수행한다.
    • 브로드캐스트 리시버: 시스템이나 다른 앱에서 보내는 브로드캐스트 인텐트를 수신하여 특정 작업을 수행한다.

요약

  • 액티비티 인텐트: 액티비티 간의 전환.
  • 서비스 인텐트: 백그라운드 서비스와의 상호작용.
  • 브로드캐스트 인텐트: 여러 앱에 메시지 전달.
  • 리시버: 인텐트를 수신하고 처리하는 컴포넌트.

인텐트 vs 리시버

인텐트 (Intent)

역할:
인텐트는 특정 작업을 수행하기 위한 "지시서" 또는 "레시피"다. 이 지시서는 어떤 작업을 수행할지, 어떤 데이터를 사용할지, 그리고 어떤 컴포넌트(액티비티, 서비스 등)를 호출할지를 정의한다.

예시:
"사용자에게 새로운 화면을 보여줘" 또는 "음악 재생 서비스를 시작해줘"와 같은 지시를 포함한다.

리시버 (Receiver)

역할:
리시버는 인텐트를 수신하고 그에 따라 행동하는 "요리사"다. 리시버는 인텐트를 받아서 그 지시서에 따라 실제로 작업을 수행한다.

예시:
인텐트를 수신한 후, 새로운 액티비티를 시작하거나, 백그라운드에서 작업을 수행하거나, 특정 이벤트에 반응하여 사용자에게 알림을 보내는 등의 작업을 한다.

예시

1. 액티비티 전환

  • 상황: 사용자가 버튼을 클릭하여 새로운 화면으로 이동하고 싶을 때.
  • 인텐트: "MainActivity에서 SecondActivity로 이동해줘"라는 인텐트를 생성한다.
  • 리시버: SecondActivity가 이 인텐트를 수신하여 화면을 전환한다. 이 과정에서 필요한 데이터(예: 사용자 입력)를 전달할 수도 있다.

2. 서비스 시작

  • 상황: 음악 재생 앱에서 사용자가 음악을 재생하고 싶을 때.
  • 인텐트: "음악 재생 서비스를 시작해줘"라는 인텐트를 생성한다.
  • 리시버: 음악 재생 서비스가 이 인텐트를 수신하여 음악을 재생한다. 이 서비스는 백그라운드에서 실행되며, 사용자가 앱을 떠나도 음악을 계속 재생할 수 있다.

3. 브로드캐스트 수신

  • 상황: 시스템 이벤트(예: 배터리 잔량 변화, 네트워크 상태 변화 등)에 반응하고 싶을 때.
  • 인텐트: 시스템에서 발생하는 브로드캐스트 인텐트(예: ACTION_BATTERY_CHANGED)를 생성합니다.
  • 리시버: 특정 리시버가 이 인텐트를 수신하여 배터리 상태에 따라 사용자에게 알림을 보내거나 UI를 업데이트한다.

4. 알림 처리

  • 상황: 특정 이벤트(예: 메시지 수신)에 대해 사용자에게 알림을 보내고 싶을 때.
  • 인텐트: "새로운 메시지가 도착했음을 알리는 인텐트"를 생성한다.
  • 리시버: 알림 리시버가 이 인텐트를 수신하여 사용자에게 알림을 표시한다.

시스템 상태 파악하기

시스템에서 발생하는 인텐트는 다양한 이벤트를 나타내며, 이러한 이벤트를 감지하고 처리하기 위해 앱의 리시버를 설정할 수 있다.

1. 부팅 완료 (BOOT_COMPLETED)

부팅 완료 인텐트는 시스템이 부팅된 후 발생한다. 이 인텐트를 수신하는 리시버는 시스템이 완전히 시작된 후 특정 작업을 수행할 수 있다.

설정 방법

  1. 리시버 클래스 정의:

    class BootCompletedReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
                // 부팅 완료 후 수행할 작업
                Log.d("BootCompletedReceiver", "System boot completed")
                // 예: 특정 서비스를 시작하거나 초기화 작업을 수행
            }
        }
    }
  2. 매니페스트에 리시버 등록:

    <receiver android:name=".BootCompletedReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>
  3. 퍼미션 추가:
    부팅 완료 인텐트를 수신하려면 RECEIVE_BOOT_COMPLETED 퍼미션이 필요합니다.

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

2. 화면 켬/끔 (SCREEN_ON, SCREEN_OFF)

화면 켬/끔 인텐트는 화면이 켜지거나 꺼질 때 발생한다. 이를 통해 화면 상태에 따라 특정 작업을 수행할 수 있다.

설정 방법

  1. 리시버 클래스 정의:

    class ScreenStateReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                Intent.ACTION_SCREEN_ON -> {
                    // 화면이 켜졌을 때 수행할 작업
                    Log.d("ScreenStateReceiver", "Screen turned ON")
                }
                Intent.ACTION_SCREEN_OFF -> {
                    // 화면이 꺼졌을 때 수행할 작업
                    Log.d("ScreenStateReceiver", "Screen turned OFF")
                }
            }
        }
    }
  2. 매니페스트에 리시버 등록:

    <receiver android:name=".ScreenStateReceiver">
        <intent-filter>
            <action android:name="android.intent.action.SCREEN_ON"/>
            <action android:name="android.intent.action.SCREEN_OFF"/>
        </intent-filter>
    </receiver>

3. 배터리 상태 변화 (BATTERY_CHANGED)

배터리 상태 변화 인텐트는 배터리 상태가 변경될 때 발생한다. 이를 통해 배터리 상태에 따라 앱에서 알림을 보내거나 사용자에게 정보를 제공할 수 있다.

설정 방법

  1. 리시버 클래스 정의:

    class BatteryStatusReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == Intent.ACTION_BATTERY_CHANGED) {
                val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
                val scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
                val batteryPct = level * 100 / scale.toFloat()
                
                // 배터리 상태 처리
                Log.d("BatteryStatusReceiver", "Battery level changed: $batteryPct%")
            }
        }
    }
  2. 매니페스트에 리시버 등록:

    <receiver android:name=".BatteryStatusReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BATTERY_CHANGED"/>
        </intent-filter>
    </receiver>

동적 등록 (동적 리시버)

동적 리시버는 코드에서 런타임 중에 등록하고 해제할 수 있으며, 특정 상황에서만 리시버를 활성화할 때 사용된다. 예를 들어, 배터리 상태를 모니터링하고 싶지만, 앱이 실행 중일 때만 관심이 있을 때 사용할 수 있다.

class MainActivity : AppCompatActivity() {
    private val batteryReceiver = BatteryStatusReceiver()

    override fun onResume() {
        super.onResume()
        val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
        registerReceiver(batteryReceiver, filter)
    }

    override fun onPause() {
        super.onPause()
        unregisterReceiver(batteryReceiver)
    }
}

요약

  • 부팅 완료 (BOOT_COMPLETED): 시스템이 부팅 완료 후 특정 작업을 수행할 때 사용.
  • 화면 켬/끔 (SCREEN_ON, SCREEN_OFF): 화면 상태가 변경될 때 작업을 수행할 때 사용.
  • 배터리 상태 변화 (BATTERY_CHANGED): 배터리 상태가 변경될 때 상태를 모니터링하고 처리할 때 사용.
profile
화려한 외면이 아닌 단단한 내면

0개의 댓글