Archives
Recent Posts
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Today
Total
관리 메뉴

안드로이드 개발자의 창고

[39일차 Android] Broadcast Receiver 본문

Computer/Android

[39일차 Android] Broadcast Receiver

Wise-99 2023. 6. 27. 22:46

 

 

 

출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT

 

 

 

📖 Broadcast Receiver

  • 안드로이드 OS에서 특정 상황에 발생하는 메시지를 받아 들여 동작하는 실행 단위
  • 반드시 외부에서 접근을 하기 위한 이름을 가져야 한다.
  • 실제 동작은 애플리케이션이 단말기에 설치되면 안드로이드 OS는 Broad Cast Receiver에 등록된 이름으로 정리하여 목록화한다.
  • 안드로이드 OS에서 어떤 사건이 발생하면 사건과 관련된 이름으로 지정된  Broad Cast Receiver를 찾아 동작 시킨다.
  • 또 애플리케이션에서 이름을 전달하여 실행을 요청하면 해당 이름이 지정된 Broad Cast Receiver를 찾아 동작 시킨다.

Broadcast Receiver의 이름

  • Broad Cast Receiver는 평소에는 동작하지 않다가 동작 요청이 발생하면 동작하게 된다.
  • 이 때, 동작 요청은 이름을 통해 요청할 수 있으며 intent filter를 통해 이름을 등록한다.

안드로이드 8.0 이후 제약 사항

  • 안드로이드 8.0부터는 개발자가 만든 Broad Cast Receiver와 OS에서 제공하는 일부 Broad Cast Receiver는 코드를 통해서만 등록이 가능하다.
  • 이는 보안 상의 이유로 Broad Cast Receiver를 가진 애플리케이션 내부에서만 사용하기 위한 제약이다.

 

 

 

📖 예제 코드

같은 애플리케이션에 있는 Broadcast Receiver 실행

 

TestReceiver.kt

class TestReceiver : BroadcastReceiver() {

    // BroadcastReceiver가 동작할 때 자동으로 호출되는 메서드
    override fun onReceive(context: Context, intent: Intent) {
        var str1 = "브로드캐스트 리시버가 동작하였습니다."
        val t1 = Toast.makeText(context, str1, Toast.LENGTH_SHORT)
        t1.show()
    }
}

 

MainActivity.kt

button.setOnClickListener {
    // 클래스 이름을 지정하여 같은 애플리케이션에 있는 BR를 동작시킨다.
    val brIntent = Intent(this@MainActivity, TestReceiver::class.java)
    sendBroadcast(brIntent)
}
  • MainActivity의 button을 클릭했을 때 brIntent를 생성한다.
  • brIntent 내부에 클래스 이름을 지정하여 TestReceiver를 동작시킨다.
  • TestReceiver는 Toast 메세지를 띄운다.

다른 애플리케이션에 있는 Broadcast Receiver 실행

다른 애플리케이션의 AndroidManifest.xml

<receiver
    android:name=".App2Receiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.test.testbr"/>
    </intent-filter>

</receiver>

 

다른 애플리케이션의 App2Receiver.kt

class App2Receiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val str1 = "App2의 BR이 동작하였습니다."
        val t1 = Toast.makeText(context, str1, Toast.LENGTH_SHORT)
        t1.show()
    }
}

 

다른 애플리케이션의 MainActivity.kt

class MainActivity : AppCompatActivity() {

    // BR 객체 생성
    val r1 = App2Receiver()

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

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            val filter = IntentFilter("com.test.testbr")
            registerReceiver(r1, filter)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        // 등록된 BR을 해제한다.
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            unregisterReceiver(r1)
        }
    }
}
  • 안드로이드 8.0부터는 BR를 코드로 등록해야지만 다른 어플리케이션이 사용할 수 있다.
  • 따라서 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ ... } 코드를 통해 SDK 버전을 확인하여 코드로 등록한다.

 

MainActivity.kt

button2.setOnClickListener {

    val brIntent = Intent("com.test.testbr")
    sendBroadcast(brIntent)
}
  • 다른 애플리케이션의 AndroidManifest.xml에서 설정한 BR의 이름을 확인하여 Intent로 넘겨준다.
  • 이 이름으로 다른 애플리케이션의 BR을 찾아 실행시킨다.

시스템 메세지를 이용한 Broadcast Receiver 실행

AndroidManifest.xml

<receiver
    android:name=".TestReceiver2"
    android:enabled="true"
    android:exported="true" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>

</receiver>

 

class TestReceiver2 : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        // BR를 등록했을 때 사용한 이름을 가져온다.
        when(intent.action){
            // 부팅 완료
            "android.intent.action.BOOT_COMPLETED" -> {
                Toast.makeText(context, "부팅 완료", Toast.LENGTH_LONG).show()
            }
            // 문자 수신
            "android.provider.Telephony.SMS_RECEIVED" -> {
                // 수신 문자를 가지고 있는 객체를 추출한다.
                if (intent.extras != null){
                    // 문자 메세지 정보 객체를 추출한다.
                    val objs = intent.extras?.get("pdus") as Array<Any?>
                    if (objs != null){
                        // 추출한 메세지 수 만큼 반복한다.
                        for (obj in objs){
                            // 문자 메세지 객체를 추출한다.
                            val format = intent.extras?.getString("format")
                            // 문자 메세지 객체를 생성한다.
                            val currentSMS = SmsMessage.createFromPdu(obj as ByteArray?, format)

                            val str1 = """전화번호 : ${currentSMS.displayOriginatingAddress}
                                |내용 : ${currentSMS.displayMessageBody}
                            """.trimMargin()

                            Toast.makeText(context, str1, Toast.LENGTH_LONG).show()
                        }
                    }
                }
            }
        }
    }
}
  • 안드로이드에서는 단말기에서 사건이 발생했을 경우 각 사건에 대해 정해진 메시지를 발생시킨다.
  • 개발자가 각 사건에 대한 이름으로 Broadcast Receiver를 등록해 놓으면 OS가 이를 찾아 동작시키는 방식이다.

'Computer > Android' 카테고리의 다른 글

[39일차 Android] Fargment  (0) 2023.07.01
[39일차 Android] Service  (0) 2023.06.29
[39일차 Android] Thread, runOnUiThraad  (0) 2023.06.26
[38일차 Android] 다양한 Notification  (0) 2023.06.25
[38일차 Android] Pending Intent  (0) 2023.06.25