Android Kotlin:调用函数从BroadcastReceive更新UI

Android Kotlin:调用函数从BroadcastReceive更新UI,android,broadcastreceiver,kotlin,Android,Broadcastreceiver,Kotlin,我是科特林的新手,看起来棒极了!虽然今天,我一直在尝试做一些在Java中非常简单的事情,但我完全被卡住了 我正在使用广播接收器确定设备何时连接/断开电源。我所需要做的就是相应地更新我的UI 我的代码 这是我的BroadcastReceiver类,它似乎工作正常 class PlugInReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { va

我是科特林的新手,看起来棒极了!虽然今天,我一直在尝试做一些在Java中非常简单的事情,但我完全被卡住了

我正在使用广播接收器确定设备何时连接/断开电源。我所需要做的就是相应地更新我的UI


我的代码 这是我的
BroadcastReceiver
类,它似乎工作正常

class PlugInReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val action = intent.action

        if (action == Intent.ACTION_POWER_CONNECTED) {
            // Do stuff when power connected
        } 
        else if (action == Intent.ACTION_POWER_DISCONNECTED) {
            // Do more stuff when power disconnected
        }
    }
}
现在,在我的
MainActivity
(稍后在其他地方)中,我想在触发意图时更新我的UI,例如在下面的函数中,背景颜色会发生变化

private fun updateBackgroundColor( newBgColorId: Int = R.color.colorAccent){
    val mainLayout = findViewById<View>(R.id.mainLayout)
    val colorFade = ObjectAnimator.ofObject(
            mainLayout, "backgroundColor", ArgbEvaluator(), oldBgColor, newBgColor)
    colorFade.start()
}
private fun updateBackgroundColor(newgcolorid:Int=R.color.colorAccent){
val mainLayout=findViewById(R.id.mainLayout)
val colorFade=ObjectAnimator.ofObject(
主布局,“背景颜色”,argbeevaluator(),oldBgColor,newgcolor)
colorfide.start()文件
}

问题 当
BroadcastReceiver
触发事件时,如何调用MainActivity上的函数或更新UI


到目前为止我都试过了
  • 我希望在某个地方有一个静态变量,存储BroadcastReceiver的结果,然后在我的UI类中有一个可观察的变量,并相应地观察和调用相应的函数。尽管在谷歌上搜索了如何做到这一点,但在科特林看来这并不是一个好方法

  • 曾考虑尝试在UI线程上运行BroadcastReceiver,但这听起来是个糟糕的主意

  • 尝试将Java实现与我的Kotlin类混合,但无法使其工作

令人沮丧的是,我发现了几个非常相似的问题。但是,它们的实现似乎都使用Java特定的功能:



我相信这对大多数Android开发者来说都是一个微不足道的问题,但我迷路了!如果你需要更多的细节,请告诉我。非常感谢

onReceive(…)方法在主线程上运行。您可以在onStart()中注册您的活动,并在onStop()中注销它,这将保证在收到事件时您的UI存在。

共享信息以在Kotlin中注册BroadcastReceiver

第一步。在MainActivity.kt中创建BroadcastReceiver

private val mPlugInReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        when (intent?.action) {
            Intent.ACTION_POWER_CONNECTED -> {
                //update your main background color
                updateBackgroundColor()
            }
            Intent.ACTION_POWER_DISCONNECTED -> {
                //update your main background color
                updateBackgroundColor()
            }
        }
    }
}
第二步。创建意图过滤器

private fun getIntentFilter(): IntentFilter {
    val iFilter = IntentFilter()
    iFilter.addAction(Intent.ACTION_POWER_CONNECTED)
    iFilter.addAction(Intent.ACTION_POWER_DISCONNECTED)
    return iFilter
}
第三步。在onStart()上注册接收器

第四步。在onStop()上注销接收器

如果您有自定义的BroadcastReceiver,则可以使用
LocalBroadcastManager
注册并创建本地
IntentFilter

private val mLocalBroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        when (intent?.action) {
            AnyService.UPDATE_ANY -> {

            }
        }
    }
}

private fun getLocalIntentFilter(): IntentFilter {
    val iFilter = IntentFilter()
    iFilter.addAction(AnyService.UPDATE_ANY)
    return iFilter
}
寄存器本地接收机
LocalBroadcastManager.getInstance(applicationContext).registerReceiver(mLocalBroadcastReceiver,getLocalContentFilter())


取消注册本地接收器
LocalBroadcastManager.getInstance(applicationContext).取消注册接收器(mLocalBroadcastReceiver)

实现这一点的最佳方法是在BroadcastReceiver中创建一个抽象方法,当调用onReceive()方法时,可以调用将由活动实现的方法

广播接收机示例:

abstract class ConnectionBroadcastReceiver : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
     //Do the checks or whatever you want
     var isConnected = true

    broadcastResult(isConnected)
}

protected abstract fun broadcastResult(connected: Boolean)
}

以及活动中的代码(例如在onCreate或onStart中)。在这里,您可以使用方法实现注册广播接收器,在这里,您可以更新UI:

    var connectionBroadcastReceiver = object : ConnectionBroadcastReceiver() {
        override fun broadcastResult(connected: Boolean) {
            if(isConnected){
                refreshList()
            }
        }
    }
    val intentFilter = IntentFilter()
    intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
    this.registerReceiver(connectionBroadcastReceiver, intentFilter)

别忘了在(onPause | | onStop | | onDestroy)中注销接收器,但这并不是绝对必要的。

谢谢你的回答,但这本身并没有什么意义(我是Kotlin的初学者)。您能否更详细地介绍一下在
onStart()
中注册什么,以及它如何仍然可以访问操作UI的函数?这对您来说应该是可行的:这是Java中的问题,这正是问题所在…?您不能在同一个文件中混合使用Kotlin和Java。您的类必须完全使用Java或完全使用Kotlin。可以在同一个项目中混合使用Kotlin和Java类,但不能在同一个类中混合使用Java/Kotlin代码。这是你问题的根源吗?我知道!!这就是我要说的——我的项目完全是Kotlin,但您共享的链接是Java!如果broadcastreceiver是一个单独的文件,如何更新ui
abstract class ConnectionBroadcastReceiver : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
     //Do the checks or whatever you want
     var isConnected = true

    broadcastResult(isConnected)
}

protected abstract fun broadcastResult(connected: Boolean)
    var connectionBroadcastReceiver = object : ConnectionBroadcastReceiver() {
        override fun broadcastResult(connected: Boolean) {
            if(isConnected){
                refreshList()
            }
        }
    }
    val intentFilter = IntentFilter()
    intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
    this.registerReceiver(connectionBroadcastReceiver, intentFilter)