import android.content.BroadcastReceiver
import android.content.IntentFilter
import androidx.activity.ComponentActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.launch
/**
* 주어진 Lifecycle 상태 이상일 때만 BroadcastReceiver를 등록하고,
* 상태가 내려가면 자동으로 해제하는 Lifecycle-aware 유틸리티 함수입니다.
*
* LifecycleOwner의 repeatOnLifecycle 블록에서 동작하므로, 안전하게 register/unregister를 관리합니다.
*
* 사용 예시1: Activity
* ```
* registerReceiverWithLifecycle(
* state = Lifecycle.State.RESUMED,
* receiverProducer = {
* object : BroadcastReceiver() {
* override fun onReceive(context: Context?, intent: Intent?) {
* val level = intent?.getIntExtra("level", -1)
* Log.d("BatteryReceiver", "Battery level: $level")
* }
* }
* },
* intentFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED),
* flags = ContextCompat.RECEIVER_EXPORTED
* )
* ```
* 사용 예시2: Fragment
* ```
* requireActivity().registerReceiverWithLifecycle(
* ownerProducer = { viewLifecycleOwner },
* state = Lifecycle.State.RESUMED,
* receiverProducer = {
* object : BroadcastReceiver() {
* override fun onReceive(context: Context?, intent: Intent?) {
* val level = intent?.getIntExtra("level", -1)
* Log.d("BatteryReceiver", "Battery level: $level")
* }
* }
* },
* intentFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED),
* flags = ContextCompat.RECEIVER_EXPORTED
* )
* ```
*
* @param ownerProducer LifecycleOwner를 반환하는 람다입니다. 기본값은 현재 Activity입니다.
* @param state receiver가 활성화될 최소 Lifecycle 상태입니다. 예: Lifecycle.State.STARTED
* @param receiverProducer BroadcastReceiver 인스턴스를 생성하는 람다입니다.
* @param intentFilter 등록할 IntentFilter입니다.
* @param flags registerReceiver에 전달될 플래그입니다. 예: ContextCompat.RECEIVER_EXPORTED
*/
fun ComponentActivity.registerReceiverWithLifecycle(
ownerProducer: () -> LifecycleOwner = { this },
state: Lifecycle.State,
receiverProducer: () -> BroadcastReceiver,
intentFilter: IntentFilter,
@ContextCompat.RegisterReceiverFlags flags: Int
) {
val owner = ownerProducer()
owner.lifecycleScope.launch {
owner.repeatOnLifecycle(state) {
val receiver = receiverProducer()
ActivityCompat.registerReceiver(
this@registerReceiverWithLifecycle, receiver, intentFilter, flags
)
try {
awaitCancellation()
} finally {
unregisterReceiver(receiver)
}
}
}
}