Nat Strangerweather
01/14/2021, 10:18 PMnglauber
01/15/2021, 12:28 AMval context = AmbientContext.current
onActive {
val broadcast = object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
//intent?.getStringExtra("param") ?: ""
}
}
context.registerReceiver(broadcast, IntentFilter("SOME_ACTION"))
onDispose {
context.unregisterReceiver(broadcast)
}
}
Adam Powell
01/15/2021, 12:36 AMnglauber
01/15/2021, 12:42 AMval context = AmbientContext.current
val broadcast = remember {
object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
pressed(intent?.getStringExtra("key") ?: "")
}
}
}
DisposableEffect(subject = broadcast, effect = {
context.registerReceiver(broadcast, IntentFilter("SOME_ACTION"))
onDispose {
context.unregisterReceiver(broadcast)
}
})
Adam Powell
01/15/2021, 12:44 AMcontext
would be a valid subject here as it's what you're registering the receiver with. You should also consider what pressed
is here. If it's a lambda param to the function you likely want something like:
val currentPressed by rememberUpdatedState(pressed)
val context = AmbientContext.current
DisposableEffect(context) {
val broadcast = ... currentPressed(...) ...
...
}
nglauber
01/15/2021, 12:45 AMpressed
is a lambda, but i just use this name to help here quickly… 😛Adam Powell
01/15/2021, 12:46 AMrememberUpdatedState
is specifically for this kind of usage, when you need composition to update something used by a long-lived object without recreating that long-lived object and potentially restarting some sort of heavyweight registration or subscription. Also useful for things like LaunchedEffect
that suspend over time if you don't want to restart the whole coroutine.Modifier.pointerInput {}
)nglauber
01/15/2021, 12:49 AMNat Strangerweather
01/15/2021, 6:38 AMDisposableEffect(context) {
val broadcast = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val code = codesProvider.getInterruptionFilter(context!!)
}
}
context.registerReceiver(broadcast, intentFilter)
onDispose {
context.unregisterReceiver(broadcast)
}
}
How does code
reach the actual Composable to be used?nglauber
01/15/2021, 11:37 AMsendBroadcast
is called, your code
will be received.Adam Powell
01/15/2021, 3:47 PM@Composable fun MyBroadcastReceiver(
param1: T1,
param2: T2,
receiver: (code: Int) -> Unit
) {
val context = AmbientContext.current
val currentReceiver by rememberUpdatedState(receiver)
DisposableEffect(context, param1, param2) {
val intentFilter = IntentFilter().apply {
// add actions/filter params based on param1/param2
}
val broadcast = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val code = codesProvider.getInterruptionFilter(context!!)
currentReceiver(code)
}
}
context.registerReceiver(broadcast, intentFilter)
onDispose {
context.unregisterReceiver(broadcast)
}
}
}
rememberUpdatedState
to let composition change the receiver
callback that is invoked with code
when the BroadcastReceiver receives a broadcast without unregistering and reregistering the underlying BR
2. Parameters to the constructed IntentFilter
become keys to the DisposableEffect
, because we do need to unregister and reregister the BR if the IntentFilter we need to build changessuspendCancellableCoroutine