Hun's Blog

[Android] 안드로이드 4대 컴포넌트 - Broadcast Receiver 본문

Android

[Android] 안드로이드 4대 컴포넌트 - Broadcast Receiver

jhk-im 2020. 3. 21. 23:58

Broadcast Receiver

 

안드로이드에서 다양한 이벤트와 정보를 받아 반응하는 컴포넌트이다. Broadcast는 메시지를 여러 객체에게 전달하는 방법을 의미하는데 이렇게 전달되는 Broadcast 메시지를 Broadcast Receiver라는 어플리케이션 구성요소를 이용해 받을 수 있다.

*방송의 특징과 흡사하다. 방송은 불특정 다수에게 송신하고 필요한 사람만 수신하는 구조이다. 경우에 따라 특정 사람에게만 송신되는 경우도 있다.(유료채널)
이러한 방송에 귀 기울이고 있는 수신자가 Broadcast Receiver 이다.
수신만 가능한 것이 아니라 필요에 의해 방송도 가능하다.
이때 방송에서 채널에 해당하는 것이 action이다.
ex) 베터리 상태확인 action -> ACTION_BATTERY_CHANGED

*방송은 항상 송신되고 있지만 가입한 상품에 따라 수신할 수 있는 채널의 종류가 다르듯이 수많은 브로드캐스트 중에서 어떤 것을 수신할 것인지 등록하는 과정이 필요하다.

action 중 원하는 action을 IntentFilter를 통해 지정할 수 있다.

1
2
3
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

방송으로 따지면 2개의 채널이 있는 것인데 이중 채널을 선택하는 방법은 무엇일까?

브로드캐스트 리시버의 onReceive()를 통해 선택한다.
@Overridepublic void onReceive(Context context, Intent intent) { if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){ Toast.makeText(context, "Battery status is changed", Toast.LENGTH_SHORT).show(); }else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)){ Toast.makeText(context, "Screen ON", Toast.LENGTH_SHORT).show(); } }

1
2
3
4
5
6
7
@Overridepublic void onReceive(Context context, Intent intent) {
    if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){
        Toast.makeText(context, "Battery status is changed", Toast.LENGTH_SHORT).show();
    }else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
        Toast.makeText(context, "Screen ON", Toast.LENGTH_SHORT).show();
    }
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

BroadcastReceiver 를 상속받은 클래스에서 오버라이딩 하여 생성한다.
BroadcastReceiver로 감지된 내용이 최종적으로 onReceiver()로 들어오는 것이다.
onReceiver 내부에 원하는 action에 대한 처리를 하면 된다.

위 내용은 안드로이드 매니패스트에서 바로 적용할 수 있다.

1
2
3
4
5
<receiver android:name=".MyReceiver">
    <intent-filter>
        <action android:name="example.test.broadcast"></action>
    </intent-filter>
</receiver>
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

코드로 작성하는 것이 아닌 매니페스트에서 브로드캐스트 리시버를 사용하는 것의 차이는 filter의 등록방법 차이다. 브로드캐스트 리스트를 상속받은 클래스는 receiver가 되어 filter.addAction() 을 통해 수신할 action을 지정한 것을 매니페스트에 바로 적용할 수 있다.


특징
- 디바이스에서 발생하는 일 중 앱이 알아야 하는 상황이 발생하면 알림
- Receiver를 이용해 디바이스의 상황을 감지하고 적절한 작업을 수행
- 대부분 UI가 존재하지 않음


예제

// 안드로이드에 저장되어 있는 action을 활용해서 만들어보자
*베터리 상태 변화와 화면 켜짐에 대한 정보를 수신
*변화 감지시 토스트 메시지를 보여줌
*액티비티 내부에 BroadcastReceiver 객체를 생성해서 구현

1.MainActivity

BroadcastReceiver 객체 생성

1
2
3
4
5
6
7
8
9
10
BroadcastReceiver br = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){
            Toast.makeText(context, "Battery status is changed", Toast.LENGTH_SHORT).show();
        }else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
            Toast.makeText(context, "Screen ON", Toast.LENGTH_SHORT).show();
        }
    }
};
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

위처럼 액티비티 내부에 객체를 생성하면 자동으로 onReceive()가 생성된다.
BroadcastReceiver로 감지되는 내용이 최종적으로 onReceive 안으로 들어온다.
ACTION_BATTERY_CHANGED - 베터리의 변화감지
ACTION_SCREEN_ON - 화면 켜짐 감지
안드로이드에서 지원하는 두가지 기능을 선택하였다.
변화가 감지되면 각각 변화에 맞게 토스트 메세지를 뿌린다.
이제 두가지 변화가 감지 되었을때 onReceive 로 들어올수 있도록 해보자.

onResume()안에다 다음과같이 설정한다.

1
2
3
4
5
6
7
8
9
@Override
protected void onResume() {
    super.onResume();
    Log.e("onResume","Resume!");
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_BATTERY_CHANGED);
    filter.addAction(Intent.ACTION_SCREEN_ON);
    registerReceiver(br,filter);
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

onResume은 사용자가 해당 액티비티를 사용하고 있는 상태이다.
그전에 안드로이드 매니페스트안에 셋팅한 것을 기억해보자.
<receiver> 안에 <IntentFilter> 안에 <action> 을 셋탕했었다.
*위 예제를보면 IntentFilter를 생성하고 그안에 액션을 추가한다.
매니페스트 파일안에 action을 기입해 넣는 행위를 코드로 하고 있는 것이다.
마지막으로 registerReceiver(브로드캐스트리시버객체, 인텐트필터객체) 를 입력하면 2가지의 액션에 반응하는 브로드캐스트 리시버가 완성된다.

* 이제 onResume 상태일 때 베터리가 변화하거나 스마트폰화면을 껐다가 켜면 위에서 만들었던 onReceive() 로 들어가 해당 변화에 따른 토스트 메세지를 띄우게 된다.




// 나만의 action을 커스텀 해서 구현해보자 
*버튼을 누르면 지정 action으로 브로드캐스트를 하고 토스트메시지 보여줌

1. 인텐트 선언 후 나만의 action 생성
여기서 오레오 이전버전과 이후 버전으로 나뉜다 !! 대환장 삽질 .. 
오레오 이후 버전으로 먼저 가보자

MyReceiver 생성
앱 -> new -> other - > Broadcast Receiver를 생성하면
MyReceiver.java 가 생성되고 매니패스트 파일도 자동으로 추가된다.

매니패스트파일

1
2
3
4
5
<receiver android:name=".MyReceiver"
    android:enabled="true"
    android:exported="true"
    >
</receiver>
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 

1
2
3
4
5
6
7
8
9
public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {      
        if(intent.getAction().equals("action.test.BROADCAST_TEST")){
            Toast.makeText(context, "Custom Broadcast", Toast.LENGTH_SHORT).show();
        }
    }
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

BroadcastReceiver를 상속받는 클래스이다.
첫번째 예제의 브로드캐스트 리시버 객체와 모양이 거의 비슷하다.
action.test.BROADCAST_TEST - 임의로 만들어놓은 action이다


String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";

베터리를 감지하는 액션도 사실 위와같은 스트링 형태이다.

나만의 커스텀 action을 간단하게 만들었으니 이제 MyReceiver의 onReceive 로 들어와서 토스트를 띄워보도록 하자.

MainActivity.java 

우선 MyReceiver 객체를 선언해두고
private MyReceiver myReceiver;

 

onResume

1
2
3
4
5
6
7
8
9
@Override
protected void onResume() {
    super.onResume();
    Log.e("onResume","Resume!");
    myReceiver = new MyReceiver();
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("action.test.BROADCAST_TEST");
    registerReceiver(myReceiver,intentFilter);
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

첫번째 예제와 동일하다.
사용자가 해당 액티비티를 사용하고있는 상태가 될 때 위에서 임의로 정한 action.test.BROADCAST_TEST를 인텐트 필터에 액션으로 추가한 후에 registerReceiver()메소드로 브로드캐스트 리시버 객체를 완성한다.

임의로 만든 액션은 안드로이드에서 제공하는 것처럼 따로 쓰레드로 검사하면서 감지하는 기능은 없기 때문에 간단하게 버튼을 눌러서 onReceive() 로 들어가 토스트메세지를 띄워보도록 하자.


1
2
3
4
5
6
7
8
9
Button send = findViewById(R.id.button_send_broadcast);
send.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
 
        Intent intent = new Intent("action.test.BROADCAST_TEST");
        sendBroadcast(intent);
    }
});
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 

다음처럼 인텐트를 생성하고 생성자 입력값으로 임의로 만든 액션을 입력한다.
sendBroadcast() 안에 인텐트객체를 넣고 버튼을 누르고 실행하면 MyReceiver로 들어가 임의의 액션을 거쳐 토스트 메세지를 띄우게 된다.



* 오레오 이전 버전으로 설명해보겠다.
간단하다.

먼저 onResume에서 MyReceiver에관한 내용을 지운다.

매니패스트파일 변경

1
2
3
4
5
<receiver android:name=".MyReceiver">
    <intent-filter>
        <action android:name="action.test.BROADCAST_TEST"></action>
    </intent-filter>
</receiver>
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

다음과같이 변경하고 실행



문제없이 동작한다.  끝 ...............



정리 - 

브로드캐스트리시버란 이름에 맞게 방송과 비교해서 설명하는게 좋을 것 같다. 
*방송의 특징이 불특정 다수에게 송신하고 필요한 사람만 수신하는 구조이다.
*유료채널처럼 특정 사용자에게만 송신되는 경우가 있다.
*이 모든것들을 채털로 구분한다. 

안드로이드에는 여러가지 기능이 있는데 베터리 변화를 감지하거나 화면의 켜짐 꺼짐등을 감지하는 것이다. 
*해당 기능은 불특정 다수에게 제공(송신)되고 필요한 경우에만 수신한다.
*특정 사용자 혹은 특정 상황에만 제공(송신)될 수 있다.
*이 모든것들을 action으로 구분한다. 

브로드캐스트 리시버는 위의 내용들을 제어하고 관리한다. 
1. 브로드캐스트 리시버가 생성되면 매니페스트파일에 등록된다.
2. 등록된 리시버 내부에 인텐트 필터가 생성되야하고 그 필터로 사용할 액션들을 설정할 수 있다. 
3. 최종적으로 onReceiver를 통해 액션에 따른 상황들을 설정한다. 
4. 안드로이드에서 제공하는 액션을 사용할 수도 있고 직접 커스텀해서 사용도 가능하다. 



참고
https://junghun0.github.io/2019/05/21/android-broadcastreceiver/
https://developer.android.com/guide/components/broadcasts?hl=ko
https://coding-factory.tistory.com/205
https://brunch.co.kr/@mystoryg/48

 

브로드캐스트 개요  |  Android 개발자  |  Android Developers

Android 앱은 Android 시스템 및 기타 Android 앱에서 게시-구독 디자인 패턴과 유사한 브로드캐스트 메시지를 받거나 보낼 수 있습니다. 관심 있는 이벤트가 발생할 때 이러한 브로드캐스트가 전송됩니다. 예를 들어 Android 시스템은 시스템 부팅 또는 기기 충전 시작과 같은 다양한 시스템 이벤트가 발생할 때 브로드캐스트를 전송합니다. 또한 앱은 맞춤 브로드캐스트를 전송하여 다른 앱이 관심을 가질만한 사항(예: 일부 새로운 데이터가 다운로드

developer.android.com

 

[Android] 안드로이드 4대 컴포넌트(구성요소)란 무엇인가?

안드로이드의 4대 컴포넌트는 액티비티, 서비스, 콘텐트제공자, 방송수신자 이렇게 4가지를 말합니다. 어플리케이션을 만들때 주요 구성요소이자 안드로이드의 사실상의 모든 구성요소입니다. 각각의 구성요소는..

coding-factory.tistory.com

 

브로드캐스트 리시버 (BroadcastReceiver)

4대 컴포넌트 | 브로드캐스트 리시버  (BroadcastReceiver) 브로드캐스트는 단어 그대로 방송을 하는 것이다. 방송의 특징을 생각해보면 방송국은 불특정 다수에게 송신을 하고 필요한 사람은 수신하는 구조이다. 경우에 따라서 특정 사람에게만 송신되는 경우(ex. IPTV 가입자)도 있다. 안드로이드도 이와 별반 다를 것이 없다. (네트워크 분야에도 유니캐스트/멀티

brunch.co.kr

 

[Android] BroadCastReceiver 오레오 이후 변경 - Junghoon's Blog

Android BroadCastReceiver 오레오 이후 변경된 점

Junghun0.github.io