시스템이나 다른 앱에서 보내는 브로드 캐스트 메시지를 받아서 처리하는 것
브로드캐스트 리시버는 등록 방식에 따라 정적, 동적으로 나뉜다. 동적으로 리시버를 등록하는 것은 4대 컴포넌트 중 브로드캐스트 리시버가 유일하다. (상황에 따라 리시브 할 때가 있고 안할 때가 있기 때문)
정적 리시버로 등록하면 앱이 꺼져있는 중에도 브로드캐스트 리시버로 설정한 intent를 받는다
<receiver android:name=".LocaleChangeReceiver" android:exported="false">
<intent-filter>
<!-- 로케일 변경에 대한 시스템 broadcast 수신 -->
<action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
LocaleChangeReceiver라는 파일에서 언어 설정이 바뀔 때마다 브로드캐스트 리시버로부터 인텐트를 수신하도록 정적으로 manifest에 설정해 놓았다.
private const val TAG = "LocaleChangeRece_싸피"
class LocaleChangeReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "onReceive: receive 받기: ${intent.action}")
}
}
브로드캐스트 리시버는 onReceive만을 override 한다. 인텐트를 받을 때마다(언어 설정이 바뀔 때마다) 로그가 출력된다.
https://developer.android.com/guide/components/broadcast-exceptions?hl=ko
현재는 정적으로 등록할 수 있는 개수가 위 링크 의 브로드캐스트로 한정되어 있다.
Intentfilter에 원하는 브로드캐스트 인텐트를 담고
리시버를 object:
를 통해 anonymous class 로 만들었다. 그리고 만든 리시버에
registerReceiver(receiver, intentFilter2);
코드로 시스템에 리시버를 등록했다.
class BroadcastActivity : AppCompatActivity() {
lateinit var receiver:BroadcastReceiver
lateinit var brBattery: BatteryReceiver
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_broadcast)
setTitle("BroadcastActivity")
/***** Screen On/Off *******/
val intentFilter2 = IntentFilter(Intent.ACTION_SCREEN_OFF)
intentFilter2.addAction(Intent.ACTION_SCREEN_ON)
receiver = object: BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
Log.d(TAG, "receive : $action")
when (action) {
Intent.ACTION_SCREEN_ON -> {
// do something
Log.d(TAG,"ACTION_SCREEN_ON");
}
Intent.ACTION_SCREEN_OFF -> {
// do something
Log.d(TAG,"ACTION_SCREEN_OFF");
}
}
}
}
registerReceiver(receiver, intentFilter2);
/***** Screen On/Off *******/
/***** Power On/Off isInteractive로 화면 상태 알 수 있음. *******/
val pm = getSystemService(Context.POWER_SERVICE) as PowerManager
if (pm.isInteractive) {
// screen on
Log.d(TAG,"POWER_SERVICE - Power ON");
} else {
// screen off
Log.d(TAG,"POWER_SERVICE - Power OFF");
}
/***** Power On/Off *******/
/***** low receiver. emulator에서 battery수치 15이하로 조정. *******/
brBattery = BatteryReceiver()
val filterBattery = IntentFilter(Intent.ACTION_BATTERY_LOW)
registerReceiver(brBattery, filterBattery)
}
override fun onDestroy() {
super.onDestroy()
unregisterReceiver(receiver)
unregisterReceiver(brBattery)
}
}
<receiver android:name=".SSAFYNewsReceiver" android:enabled="true" android:exported="false" >
<intent-filter>
<!-- 사용자 정의 broadcast 수신 -->
<action android:name="example.MY" />
</intent-filter>
</receiver>
intent filter에 수신할 action을 작성하고
private const val TAG = "MainActivity_싸피"
class MainActivity : AppCompatActivity() {
private lateinit var broadcastBtn: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
broadcastBtn = findViewById(R.id.broadcast_btn)
broadcastBtn.setOnClickListener {
val intent = Intent(this, SSAFYNewsReceiver::class.java)
intent.action = "example.MY"
intent.putExtra("content", "오늘도 티끌을 모아봅니다.")
sendBroadcast(intent)
Log.d(TAG, "onCreate: 발송 완료")
}
}
}
action을 정하고 명시적으로 수신할 리시버를 지정해준다. 위에 액티비티에서 버튼을 누르면 브로드캐스트를 하도록 해주었다.
private const val TAG = "SSAFYNewsReceiver_싸피"
class SSAFYNewsReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "onReceive: receive 받기: ${intent.action}")
Log.d(TAG, "onReceive: extra: ${intent.getStringExtra("content")}")
}
}
리시버에서 받을 시 할 실행문을 적어주어 로그로 action과 데이터를 받도록 하였다.
특정 권한을 가진 앱만 브로드캐스트 받기
<!-- 사용자 정의 permission 선언 -->
<permission
android:name="com.ssafy.android.news.funny.PRIVATE"
android:protectionLevel="signature" /> <!-- permission 사용 선언 -->
<uses-permission android:name="com.ssafy.android.news.funny.PRIVATE" />
사용자 정의 permission 생성 및 사용 선언
<receiver
android:name=".SSAFYNewsReceiver2"
android:enabled="true"
android:exported="false"
android:permission="com.ssafy.android.news.funny.PRIVATE">
<intent-filter>
<!-- 사용자 정의 broadcast 수신 -->
<action android:name="com.ssafy.android.news.funny" />
</intent-filter>
</receiver>
수신받을 리시버와 액션 선언
private const val TAG = "SSAFYNewsReceiver2_싸피"
class SSAFYNewsReceiver2 : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "onReceive: receive 받기: ${intent.action}")
Log.d(TAG, "onReceive: extra: ${intent.getStringExtra("content")}")
}
}
리시버에서 브로드캐스트 수신시 실행할 문 작성