Deperecated/Android_강의

안드로이드 - 시스템 메세지

누알라리 2020. 2. 19. 03:26
1. 시스템 메세지란?

- 안드로이드에서는 단말기에서 사건이 발생했을 경우 각 사건마다 정해 놓은 이름으로 시스템 메세지를 발생시킨다.(배터리용량 부족, 메세지 도착, 부팅 완료 등)

- 이 메세지와 동일한 이름으로 설정되어 있는 BroadCastReceiver를 찾아 개발자가 만든 코드를 동작시킬 수 있다.

- 안드로이드 8.0(오레오) 부터는 사용할 수 있는 시스템 메세지의 수가 줄어들었다. (암시적 인텐트)

 

https://developer.android.com/guide/components/broadcast-exceptions

 

암시적 브로드캐스트 예외  |  Android 개발자  |  Android Developers

백그라운드 제한에서 제외되는 암시적 브로드캐스트입니다.

developer.android.com

- 하지만 위 BroadCast 메세지들은 app이 동작하고있지 않더라도 암시적 인텐트로 리시버 등록이 가능하다.

 

2. 예제 - 부팅 완료 브로드캐스트

1. 권한을 등록한다.

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

2. BR을 상속하는 클래스를 만들고, 리시버에 intent-filter로 action 이름을 달아준다.

        <receiver
            android:name=".TestReceiver"
            android:enabled="true"
            android:exported="true">

            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>

        </receiver>

3. BR 클래스에서 BroadCast를 받으면 자동으로 호출되는 onReceive()에 분기별로 나눠서 처리해준다.

    // 2.
    // 자동으로 호출됨
    // BR은 화면을 처리하는게 아니기때문에 토스트메세지나 노티피케이션을 이용해 메세지를 띄워줘야한다.
    override fun onReceive(context: Context, intent: Intent) {


        // 3. 하나의 리시버에서 다중의 메세지를 처리하려면 분기별로 나눠야하는데, 그 정보는 intent가 갖고있다.
        when(intent.action)
        {
            // 4. 재부팅 완료 브로드캐스트(암시적 인텐트).
            "android.intent.action.BOOT_COMPLETED" ->
            {
                var t1 = Toast.makeText(context, "부팅 완료", Toast.LENGTH_SHORT)
                t1.show()
            }
        }
    }

 

3. 예제 - 문자메세지 수신 시 (발신자 번호 : 문자메세지 내용)이 나오는 코드

1. 권한 요청을 한다.

    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    // 문자 메세지 받을 때 등록을 위해 Permission List
    var permission_list = arrayOf(
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.RECEIVE_SMS
    )

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


        checkPermission()
    }

    fun checkPermission()
    {
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
        {
            return
        }

        for(permission : String in permission_list)
        {
            var chk = checkCallingOrSelfPermission(permission)
            if(chk == PackageManager.PERMISSION_DENIED)
            {
                requestPermissions(permission_list, 0)
                break

            }
        }
    }

2. 리시버에 문자메세지를 받으면 나오는 코드를 작성한다.

class TestReceiver : BroadcastReceiver() {

    // 2.
    // 자동으로 호출됨
    // BR은 화면을 처리하는게 아니기때문에 토스트메세지나 노티피케이션을 이용해 메세지를 띄워줘야한다.
    override fun onReceive(context: Context, intent: Intent) {


        // 3. 하나의 리시버에서 다중의 메세지를 처리하려면 분기별로 나눠야하는데, 그 정보는 intent가 갖고있다.
        when(intent.action)
        {
            // 4. 재부팅 완료 브로드캐스트(암시적 인텐트).
            //"android.intent.action.BOOT_COMPLETED" ->
            Intent.ACTION_BOOT_COMPLETED ->
            {
                var t1 = Toast.makeText(context, "부팅 완료", Toast.LENGTH_SHORT)
                t1.show()
            }
           // "android.provider.Telephony.SMS_RECEIVED" ->
            Telephony.Sms.Intents.SMS_RECEIVED_ACTION ->
            {
                // 5.
                // 문자 메세지를 받으면 토스트메시지로 (발신자 : 문자 내용)이 뜨는 코드.
                // bundle안에 pdus라는 이름으로 문자메세지 정보가 들어가있다.
                var str = ""
                var bundle = intent.extras
                if(bundle != null)
                {
                    var obj = bundle.get("pdus") as Array<Any>
                    var msg = arrayOfNulls<SmsMessage>(obj.size)

                    for (i in obj.indices)
                    {
                        msg[i] = SmsMessage.createFromPdu(obj[i] as ByteArray)
                    }

                    // 6. 문자 발신자 전화번호를 뽑음.
                    for (i in msg.indices)
                    {
                        str = msg[i]?.originatingAddress + " : " + msg[i]?.messageBody
                        var t2 = Toast.makeText(context, str, Toast.LENGTH_SHORT)
                        t2.show()
                    }
                }
            }
        }
    }
}