SoFunction
Updated on 2025-03-11

The implementation principle of slow charging and fast charging prompts in Android 8.0

1. Slow charging and fast charging prompts

\frameworks\base\packages\SystemUI\res-keyguard\values-zh-rCN

Chinese prompts

<string name="keyguard_plugged_in" msg>"Recharge"</string>
  <string name="keyguard_plugged_in_charging_fast" msg>"Fast charging"</string>
  <string name="keyguard_plugged_in_charging_slowly" msg>"Slow charging"</string>

English prompts

\frameworks\base\packages\SystemUI\res-keyguard\values

1. Fast Charging Charger - Displays Fast Charging String

<!-- When the lock screen is showing and the phone plugged in, and the battery is not fully charged, and it's plugged into a fast charger, say that it's charging fast. --> 
<string name="keyguard_plugged_in_charging_fast">Charging rapidly</string>

2. Ordinary charger - display charging, which is the same as 7.0 and its previous characteristics

<!-- When the lock screen is showing and the phone plugged in, and the battery is not fully charged, say that it's charging. --> 
<string name="keyguard_plugged_in">Charging</string>

3. Display on the computer or laptop - slow charging

<!-- When the lock screen is showing and the phone plugged in, and the battery is not fully charged, and it's plugged into a slow charger, say that it's charging slowly. --> 
<string name="keyguard_plugged_in_charging_slowly">Charging slowly</string>

2. Principle

Calculate the current speed based on the current maximum voltage and current, and classify it as slow charging, charging, and fast charging

2.1 Raw data in source code

•public static final String EXTRA_MAX_CHARGING_CURRENT = “max_charging_current”;
•public static final String EXTRA_MAX_CHARGING_VOLTAGE = “max_charging_voltage”;

Send the "battery broadcast" position and send the maximum current and voltage to the application layer. Here are some newly added data above 8.1. This data was previously available before 7.0, but the framework layer was not used.

frameworks/base/services/core/java/com/android/server/
// Send battery broadcast eventprivate void sendIntentLocked() {
  // Pack up the values and broadcast them to everyone
  final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
  (Intent.FLAG_RECEIVER_REGISTERED_ONLY
      | Intent.FLAG_RECEIVER_REPLACE_PENDING);
.......
(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, );
(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, );

2.2 adb shell view linux file nodes

• Obtain the current current

adb shell cat /sys/class/power_supply/battery/current_max
adb shell cat /sys/class/power_supply/battery/current_max
30000001

• Obtain the current voltage

adb shell cat /sys/class/power_supply/battery/voltage_max
adb shell cat /sys/class/power_supply/battery/voltage_max
50000001

•Specific source code

system/core/healthd/
#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,mChargerNames[i].string());

2.3 The upper layer receives broadcast

frameworks/base/packages/SystemUI/src/com/android/keyguard/

Focus on the algorithm rules of maxChargingMicroAmp and maxChargingMicroVolt

private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    ....
    } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
        final int status = (EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
        final int plugged = (EXTRA_PLUGGED, 0);
        final int level = (EXTRA_LEVEL, 0);
        final int health = (EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
        final int maxChargingMicroAmp = (EXTRA_MAX_CHARGING_CURRENT, -1);
        int maxChargingMicroVolt = (EXTRA_MAX_CHARGING_VOLTAGE, -1);
        final int maxChargingMicroWatt;
        if (maxChargingMicroVolt <= 0) {
          maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
        }
        if (maxChargingMicroAmp > 0) {
          // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
          // to maintain precision equally on both factors.
          maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
              * (maxChargingMicroVolt / 1000);
        } else {
          maxChargingMicroWatt = -1;
        }
        final Message msg = (
            MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
                maxChargingMicroWatt));
        (msg);

2.4 Display string

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/

Event Receive

protected class BaseKeyguardCallback extends KeyguardUpdateMonitorCallback {
    public static final int HIDE_DELAY_MS = 5000;
    private int mLastSuccessiveErrorMessage = -1;
    @Override
    public void onRefreshBatteryInfo( status) {
      boolean isChargingOrFull =  == BatteryManager.BATTERY_STATUS_CHARGING
          ||  == BatteryManager.BATTERY_STATUS_FULL;
      boolean wasPluggedIn = mPowerPluggedIn;
      mPowerPluggedIn = () && isChargingOrFull;
      mPowerCharged = ();
      mChargingWattage = ;
      mChargingSpeed = (mSlowThreshold, mFastThreshold);
      updateIndication();
      if (mDozing) {
        if (!wasPluggedIn && mPowerPluggedIn) {
          showTransientIndication(computePowerIndication());
          hideTransientIndicationDelayed(HIDE_DELAY_MS);
        } else if (wasPluggedIn && !mPowerPluggedIn) {
          hideTransientIndication();
        }
      }
    }
=====================================================================================================
  public static class BatteryStatus {
    public static final int CHARGING_UNKNOWN = -1;
    public static final int CHARGING_SLOWLY = 0;
    public static final int CHARGING_REGULAR = 1;
    public static final int CHARGING_FAST = 2;
    public final int status;
    public final int level;
    public final int plugged;
    public final int health;
    public final int maxChargingWattage;
    public BatteryStatus(int status, int level, int plugged, int health,
        int maxChargingWattage) {
       = status;
       = level;
       = plugged;
       = health;
       = maxChargingWattage;
    }
  public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
    return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
        maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
        maxChargingWattage > fastThreshold ? CHARGING_FAST :
        CHARGING_REGULAR;
  }

Show string

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/
    int chargingId;
    switch (mChargingSpeed) {
      case .CHARGING_FAST:
        chargingId = hasChargingTime
            ? .keyguard_indication_charging_time_fast
            : .keyguard_plugged_in_charging_fast;
        break;
      case .CHARGING_SLOWLY:
        chargingId = hasChargingTime
            ? .keyguard_indication_charging_time_slowly
            : .keyguard_plugged_in_charging_slowly;
        break;
      default:
        chargingId = hasChargingTime
            ? .keyguard_indication_charging_time
            : .keyguard_plugged_in;
        break;
    }

Summarize

The above is the implementation principle of Android 8.0 slow charging and fast charging prompts introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support for my website!