Android实现获取手机的电池电量和充电状态

在 Android 开发中,获取电池电量和充电状态主要通过监听系统广播 Intent.ACTION_BATTERY_CHANGED 来实现。以下是详细的实现方法和代码示例。

图片[1]_Android实现获取手机的电池电量和充电状态_知途无界

方法一:通过广播接收器实时监听(推荐)

1. 创建广播接收器

public class BatteryReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
            // 获取电池电量百分比
            int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
            float batteryPct = level * 100 / (float) scale;
            
            // 获取充电状态
            int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                               status == BatteryManager.BATTERY_STATUS_FULL;
            
            // 获取充电方式(AC/USB/无线)
            int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
            boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
            boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
            boolean wirelessCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_WIRELESS;
            
            // 获取电池健康状态
            int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, -1);
            String healthStatus = getHealthStatus(health);
            
            // 获取电池技术(如 Li-ion)
            String technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
            
            // 获取电池温度(摄氏度)
            int temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
            float tempCelsius = temperature / 10.0f;
            
            // 获取电池电压(毫伏)
            int voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
            
            // 打印日志或更新UI
            Log.d("BatteryInfo", String.format(
                "电量: %.1f%%, 充电状态: %s, 充电方式: %s, 健康: %s, 温度: %.1f°C",
                batteryPct, getStatusString(status), getPlugTypeString(chargePlug),
                healthStatus, tempCelsius
            ));
            
            // 可以在这里更新UI或触发回调
            updateBatteryInfo(batteryPct, isCharging, usbCharge, acCharge, wirelessCharge,
                             healthStatus, technology, tempCelsius, voltage);
        }
    }
    
    // 将状态码转换为可读字符串
    private String getStatusString(int status) {
        switch (status) {
            case BatteryManager.BATTERY_STATUS_UNKNOWN:
                return "未知";
            case BatteryManager.BATTERY_STATUS_CHARGING:
                return "充电中";
            case BatteryManager.BATTERY_STATUS_DISCHARGING:
                return "放电中";
            case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
                return "未充电";
            case BatteryManager.BATTERY_STATUS_FULL:
                return "已充满";
            default:
                return "未定义";
        }
    }
    
    private String getPlugTypeString(int plugType) {
        switch (plugType) {
            case BatteryManager.BATTERY_PLUGGED_AC:
                return "交流电";
            case BatteryManager.BATTERY_PLUGGED_USB:
                return "USB";
            case BatteryManager.BATTERY_PLUGGED_WIRELESS:
                return "无线充电";
            default:
                return "未充电";
        }
    }
    
    private String getHealthStatus(int health) {
        switch (health) {
            case BatteryManager.BATTERY_HEALTH_UNKNOWN:
                return "未知";
            case BatteryManager.BATTERY_HEALTH_GOOD:
                return "良好";
            case BatteryManager.BATTERY_HEALTH_OVERHEAT:
                return "过热";
            case BatteryManager.BATTERY_HEALTH_DEAD:
                return "损坏";
            case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
                return "电压过高";
            case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
                return "未指明故障";
            case BatteryManager.BATTERY_HEALTH_COLD:
                return "过冷";
            default:
                return "未定义";
        }
    }
    
    // 更新电池信息的回调方法(可根据需要实现)
    private void updateBatteryInfo(float batteryPct, boolean isCharging, boolean usbCharge,
                                  boolean acCharge, boolean wirelessCharge, String healthStatus,
                                  String technology, float tempCelsius, int voltage) {
        // 在这里更新UI或发送回调给Activity/Fragment
    }
}

2. 在 Activity 或 Service 中注册广播接收器

public class MainActivity extends AppCompatActivity {
    private BatteryReceiver batteryReceiver;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        registerBatteryReceiver();
    }
    
    private void registerBatteryReceiver() {
        batteryReceiver = new BatteryReceiver();
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(batteryReceiver, filter);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 记得取消注册广播接收器
        if (batteryReceiver != null) {
            unregisterReceiver(batteryReceiver);
        }
    }
}

方法二:使用 BatteryManager API(单次获取)

对于只需要偶尔获取电池信息的场景,可以使用 BatteryManager

private void getBatteryInfoOnce() {
    BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
    
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        // 获取当前电池电量(API 21+)
        int batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
        
        // 检查是否在充电
        boolean isCharging = batteryManager.isCharging();
        
        Log.d("BatteryInfo", "电量: " + batteryLevel + "%, 充电状态: " + isCharging);
    } else {
        // 旧版本回退到广播方式
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent batteryStatus = registerReceiver(null, filter);
        
        if (batteryStatus != null) {
            int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
            int batteryPct = (int) ((level / (float) scale) * 100);
            
            int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                               status == BatteryManager.BATTERY_STATUS_FULL;
            
            Log.d("BatteryInfo", "电量: " + batteryPct + "%, 充电状态: " + isCharging);
        }
    }
}

方法三:Kotlin 扩展函数(Kotlin 项目推荐)

如果你使用 Kotlin,可以创建扩展函数简化调用:

// BatteryExtensions.kt
fun Context.getBatteryInfo(): Map<String, Any>? {
    val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
    val intentFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
    val batteryStatus = registerReceiver(null, intentFilter)
    
    return batteryStatus?.let { intent ->
        val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
        val scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
        val batteryPct = level * 100 / scale.toFloat()
        
        val status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
        val isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                        status == BatteryManager.BATTERY_STATUS_FULL
        
        mapOf(
            "level" to batteryPct,
            "isCharging" to isCharging,
            "status" to status,
            "temperature" to intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) / 10.0f,
            "voltage" to intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0),
            "technology" to intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY) ?: "Unknown"
        )
    }
}

// 在 Activity 中使用
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        val batteryInfo = getBatteryInfo()
        batteryInfo?.let {
            Log.d("Battery", "电量: ${it["level"]}%, 充电: ${it["isCharging"]}")
        }
    }
}

权限要求

AndroidManifest.xml 中添加权限(实际上监听 ACTION_BATTERY_CHANGED 不需要声明权限):

<!-- 虽然不需要显式声明,但有些设备可能需要 -->
<uses-permission android:name="android.permission.BATTERY_STATS" />

注意事项

  1. 实时性​:ACTION_BATTERY_CHANGED 是粘性广播,注册时会立即返回当前电池状态
  2. 性能考虑​:持续监听会消耗少量资源,不需要时应及时注销接收器
  3. 兼容性​:不同设备和 Android 版本可能返回的数据有差异
  4. 后台限制​:在 Android 8.0+ 的后台限制下,长时间运行的广播接收器可能被限制

完整示例 UI 展示

public class BatteryActivity extends AppCompatActivity {
    private TextView tvBatteryLevel;
    private TextView tvChargingStatus;
    private BatteryReceiver batteryReceiver;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_battery);
        
        tvBatteryLevel = findViewById(R.id.tv_battery_level);
        tvChargingStatus = findViewById(R.id.tv_charging_status);
        
        setupBatteryReceiver();
    }
    
    private void setupBatteryReceiver() {
        batteryReceiver = new BatteryReceiver() {
            @Override
            protected void updateBatteryInfo(float batteryPct, boolean isCharging, 
                                            boolean usbCharge, boolean acCharge, 
                                            boolean wirelessCharge, String healthStatus,
                                            String technology, float tempCelsius, int voltage) {
                runOnUiThread(() -> {
                    tvBatteryLevel.setText(String.format("电量: %.1f%%", batteryPct));
                    
                    String chargingText = "充电状态: " + getStatusString(
                        isCharging ? BatteryManager.BATTERY_STATUS_CHARGING : 
                                   BatteryManager.BATTERY_STATUS_DISCHARGING
                    );
                    
                    if (isCharging) {
                        if (acCharge) chargingText += " (交流电)";
                        else if (usbCharge) chargingText += " (USB)";
                        else if (wirelessCharge) chargingText += " (无线)";
                    }
                    
                    tvChargingStatus.setText(chargingText);
                });
            }
        };
        
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(batteryReceiver, filter);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (batteryReceiver != null) {
            unregisterReceiver(batteryReceiver);
        }
    }
}

以上方法可以根据你的具体需求选择使用。对于大多数实时监测场景,推荐使用广播接收器的方式;对于偶尔获取的场景,可以使用 BatteryManager API。

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞66 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容