广播接收器改变UI。

huangapple go评论55阅读模式
英文:

Broadcast receiver change UI

问题

是否可以从广播接收器更改Jetpack Compose用户界面中的变量?

英文:

I have searched widely but not found an answer to this question:
Is it possible to change a variable in a Jetpack compose user interface from a broadcast receiver?

答案1

得分: 4

你可以使用 DisposableEffectLocalContext.current 来在Compose中注册和注销你的 BroadcastReceiver。记得使用 rememberUpdatedState 来保持对lambda的更新引用。

这里是一个通用的Compose中的 BroadcastReceiver 示例:

@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)
        }
    }
}

以下是一个示例,展示了如何使用它来提取OTP:

// 这是我想要更改的值
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) {

                // 在这里我更改了"myOtp"的值 !!
                myOtp = otpReceived
            }
        }
    }
}

以上是示例链接:

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

英文:

You can make use of DisposableEffect and LocalContext.current for register and unregister your BroadcastReceiver in compose. Remeber to use rememberUpdatedState for keep an updated reference to the lambda

Here is an example of a generic BroadcastReceiver in 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)
        }
    }
}

Here is an example of how I used it to extract an 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
            }
        }
    }
}

here is link of the above example:

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

答案2

得分: 1

你不能直接从广播接收器修改Compose UI。相反,你的广播接收器应该在数据层中更改一些数据 - 数据存储、偏好设置、数据库或者只是在某个存储库单例类中的内存中。然后,你应该将这些数据设置为可观察,并从Compose UI中观察它们。

英文:

You can't modify your compose ui from Broadcast receiver directly. Instead, your Broadcast receiver should change some data in your data layer - datastore, preferences, database or just in memory in some Repository singleton class. Then you should make this data observable and observe them from your compose ui.

huangapple
  • 本文由 发表于 2023年6月1日 23:04:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76383296.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定