广播接收器更改 UI

sig*_*jak 5 broadcastreceiver android-jetpack-compose

我进行了广泛的搜索,但没有找到这个问题的答案:Is it possible to change a variable in a Jetpack compose user interface from a BroadcastReceiver?

小智 10

您可以使用DisposableEffectLocalContext.current来注册和取消BroadcastReceiver注册您的邮件。请记住使用rememberUpdatedState来保持对 lambda 的更新引用

BroadcastReceiver这是compose 中泛型的示例

@Composable
fun SystemBroadcastReceiver(
    systemAction: String,
    onSystemEvent: (intent: Intent?) -> Unit
) {
    val context = LocalContext.current

    val currentOnSystemEvent by rememberUpdatedState( onSystemEvent )

    DisposableEffect(context, systemAction){

        val intentFilter = IntentFilter( systemAction )

        val receiver = object : BroadcastReceiver(){
            override fun onReceive(context: Context?, intent: Intent?) {
                currentOnSystemEvent( intent )
            }
        }

        context.registerReceiver( receiver, intentFilter)

        onDispose {
            context.unregisterReceiver(receiver)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是我如何使用它来提取 OTP 的示例:

// this is the value I want to change
var myOtp : String by remember{ mutableStateOf("") }

SystemBroadcastReceiver(systemAction = SMS_RETRIEVED_ACTION){ intent ->
    if( intent?.action == SMS_RETRIEVED_ACTION ){

        val extras = intent.extras
        val status = extras?.get( EXTRA_STATUS) as? Status

        if( status?.statusCode == CommonStatusCodes.SUCCESS){
            val message = extras.getString(EXTRA_SMS_MESSAGE, "")

            val otpReceived = Regex("[0-9]{6}").find( message )?.value

            if( otpReceived != null ){

                // here i change the value of "myOtp" !!
                myOtp = otpReceived
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是上面示例的链接:

https://developer.android.com/jetpack/compose/migrate/interoperability-apis/views-in-compose#case-study-broadcastreceivers


Jan*_*ína 2

您无法直接从广播接收器修改您的撰写 ui。相反,您的广播接收器应该更改数据层中的一些数据 - 数据存储、首选项、数据库或仅在某些存储库单例类的内存中。然后,您应该使这些数据可观察,并从您的 compose ui 中观察它们。