You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何通过Intent从BroadcastReceiver向Fragment传递步数数据

步数追踪BroadcastReceiver的Fragment数据传递问题

我需要在后台及APP关闭时追踪步数,因此创建了两个BroadcastReceiver:一个用于后台通知显示步数,另一个用于更新Fragment UI(会在Fragment销毁时注销)。以下是后者的实现流程:

步骤1:Foreground Service发送步数广播

Intent().also { intent ->
    intent.setAction(ACTION_STEP_COUNTER_NOTIFICATION)
    intent.putExtra("stepCount", "$todayTotalStepCount")
    sendBroadcast(intent)
}

步骤2:BroadcastReceiver接收广播并尝试传递给Fragment

open class StepCountBroadcastReceiver : BroadcastReceiver() {
 override fun onReceive(context: Context?, intent: Intent?) {
     super.onReceive(context, intent)

     if(intent!!.action == ACTION_STEP_COUNTER_NOTIFICATION) {
         var intent = Intent()
         var stepCount = intent.getStringExtra("stepCount")

         var sendMyDiary = Intent(context!!, MyDiaryFragment::class.java)
         sendMyDiary.putExtra("stepCount", stepCount)
         context.startActivity(sendMyDiary)
     }
 }
}

步骤3:Fragment中注册BroadcastReceiver

private val stepCountBroadcastReceiver: BroadcastReceiver = StepCountBroadcastReceiver()

val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply {
    addAction(ACTION_STEP_COUNTER_NOTIFICATION)
}
LocalBroadcastManager.getInstance(requireActivity()).registerReceiver(stepCountBroadcastReceiver, filter)

我的疑问

每次BroadcastReceiver被调用时,我不知道如何在Fragment中获取传来的stepCount。是否只需添加如下代码即可?

var stepCount = requireActivity().intent.getStringExtra("stepCount")

也就是改成:

val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply {
    addAction(ACTION_STEP_COUNTER_NOTIFICATION)
}
LocalBroadcastManager.getInstance(requireActivity()).registerReceiver(stepCountBroadcastReceiver, filter)
var stepCount = requireActivity().intent.getStringExtra("stepCount")

解答

你的写法存在几个关键问题,直接添加那段代码无法获取到步数数据,正确的实现方式如下:

  1. 修复BroadcastReceiver的逻辑错误
    原Receiver代码里重新创建了空的Intent,导致无法获取广播传来的步数数据;同时用startActivity启动Fragment的做法完全错误——Fragment不能作为独立组件通过startActivity启动,它必须依附于Activity。

    正确的做法是让Receiver直接在Fragment内部处理数据更新,不需要单独定义Receiver类,而是在Fragment中创建匿名Receiver。

  2. 修改Fragment的Receiver注册与数据处理
    在Fragment的onCreate中定义并注册Receiver,直接在onReceive方法中获取步数并更新UI:

    // 定义匿名Receiver,直接关联Fragment的UI更新
    private val stepCountBroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            intent?.takeIf { it.action == ACTION_STEP_COUNTER_NOTIFICATION }?.let {
                // 从广播Intent中直接获取步数
                val stepCount = it.getStringExtra("stepCount")
                // 在这里更新Fragment的UI,比如更新TextView
                // stepCountTextView.text = stepCount
            }
        }
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 注册Receiver,若不需要监听网络变化,可去掉ConnectivityManager.CONNECTIVITY_ACTION
        val filter = IntentFilter().apply {
            addAction(ACTION_STEP_COUNTER_NOTIFICATION)
        }
        LocalBroadcastManager.getInstance(requireActivity())
            .registerReceiver(stepCountBroadcastReceiver, filter)
    }
    
    // 记得在Fragment销毁时注销Receiver,避免内存泄漏
    override fun onDestroy() {
        super.onDestroy()
        LocalBroadcastManager.getInstance(requireActivity())
            .unregisterReceiver(stepCountBroadcastReceiver)
    }
    
  3. 同步Foreground Service的广播发送方式
    因为Fragment用LocalBroadcastManager注册Receiver,所以Service中也需要用LocalBroadcastManager发送广播,确保能被接收:

    LocalBroadcastManager.getInstance(this).sendBroadcast(Intent(ACTION_STEP_COUNTER_NOTIFICATION).apply {
        putExtra("stepCount", "$todayTotalStepCount")
    })
    

关键说明

  • 不要通过requireActivity().intent获取广播数据:Activity的启动Intent和广播传递的Intent是完全独立的,广播触发时不会更新Activity的Intent,所以这种方式根本拿不到数据。
  • 必须在onReceive方法中直接从广播Intent里提取数据,然后直接更新Fragment的UI,这是最直接且正确的方式。

内容的提问来源于stack exchange,提问作者Hyejung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 18:10:36