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

Android广播接收器未在电源切换时刷新电池数据问题求助

问题分析与解决方案

哎,我明白为啥电源切换时数据不刷新了!你现在的代码只在Fragment创建的时候调用了一次retrieveBatteryData获取电源状态,之后不管电源怎么插拔,都没有任何机制去监听这个状态变化并触发界面更新。虽然ACTION_BATTERY_CHANGED是系统粘性广播,但你只是一次性拿了当前状态,没注册接收器盯着后续的变化呀。

下面给你一步步解决这个问题:


核心思路

  1. 注册BroadcastReceiver监听ACTION_BATTERY_CHANGED广播,每次电源状态变化时都会收到通知
  2. 在Fragment生命周期中正确注册/注销接收器,避免内存泄漏
  3. 复用现有RecyclerView适配器,更新数据后通知界面刷新,不用每次都新建适配器

修改后的代码示例

更新BatteryFragment

public class BatteryFragment extends Fragment {
    FragmentBatteryBinding fragmentBatteryBinding;
    BatteryFragmentVm batteryFragmentVm;
    List<PojoMain> batteryData;
    RecyclerAdapter recyclerDeviceAdapter;
    // 定义电池状态广播接收器
    private BroadcastReceiver batteryStatusReceiver;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        fragmentBatteryBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_battery, container, false);
        batteryFragmentVm = new BatteryFragmentVm();
        fragmentBatteryBinding.setBatteryVm(batteryFragmentVm);
        
        // 初始化数据列表与适配器
        batteryData = new ArrayList<>();
        recyclerDeviceAdapter = new RecyclerAdapter(batteryData, requireContext());
        fragmentBatteryBinding.batteryRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
        fragmentBatteryBinding.batteryRecyclerView.setAdapter(recyclerDeviceAdapter);
        
        // 初始化获取一次电池数据
        refreshBatteryStatus();
        
        // 初始化广播接收器:收到状态变化时刷新数据
        batteryStatusReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                refreshBatteryStatus();
            }
        };
        
        return fragmentBatteryBinding.getRoot();
    }

    // 修正后的电源来源判断方法(注意区分充电类型和电池状态)
    private String getPowerSource(Context context) {
        Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        int pluggedType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        
        if (pluggedType == BatteryManager.BATTERY_PLUGGED_AC) {
            return "Plugged AC";
        } else if (pluggedType == BatteryManager.BATTERY_PLUGGED_USB) {
            return "Plugged USB";
        } else if (pluggedType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
            return "Plugged Wireless";
        } else {
            // 未连接任何充电设备,处于放电状态
            return "Discharging";
        }
    }

    // 刷新电池数据并更新界面
    private void refreshBatteryStatus() {
        batteryData.clear();
        batteryData.add(new PojoMain("Power Source", getPowerSource(requireContext())));
        // 通知适配器数据变化
        recyclerDeviceAdapter.notifyDataSetChanged();
    }

    @Override
    public void onResume() {
        super.onResume();
        // 注册广播接收器
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        requireContext().registerReceiver(batteryStatusReceiver, filter);
    }

    @Override
    public void onPause() {
        super.onPause();
        // 注销接收器,防止内存泄漏
        requireContext().unregisterReceiver(batteryStatusReceiver);
    }
}

优化BatteryFragmentVm(可选,改用LiveData更贴合Android生命周期)

ViewModel不应该持有Context引用,改用LiveData来管理数据会更安全:

public class BatteryFragmentVm extends ViewModel {
    private final MutableLiveData<List<PojoMain>> batteryDataLiveData = new MutableLiveData<>();

    public void updateBatteryData(List<PojoMain> newData) {
        batteryDataLiveData.postValue(newData);
    }

    public LiveData<List<PojoMain>> getBatteryDataLiveData() {
        return batteryDataLiveData;
    }
}

然后在Fragment的onCreateView里添加观察者:

batteryFragmentVm.getBatteryDataLiveData().observe(getViewLifecycleOwner(), data -> {
    batteryData.clear();
    batteryData.addAll(data);
    recyclerDeviceAdapter.notifyDataSetChanged();
});

对应的refreshBatteryStatus方法改成:

private void refreshBatteryStatus() {
    List<PojoMain> newData = new ArrayList<>();
    newData.add(new PojoMain("Power Source", getPowerSource(requireContext())));
    batteryFragmentVm.updateBatteryData(newData);
}

关键注意点

  1. 修正了原代码中的逻辑错误:BATTERY_STATUS_DISCHARGING是电池的工作状态,而EXTRA_PLUGGED返回的是充电类型,两者不要混淆
  2. 广播接收器必须在onPause中注销,否则会导致内存泄漏
  3. 复用RecyclerView适配器比每次新建更高效,避免不必要的视图重建

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:23:27