Tencent/matrix · error · IllegalStateException
Illegal battery state
Error message
Illegal battery state: <action>
What it means
dispatchBatteryStateChangedEvent(action) throws IllegalStateException for any battery-state broadcast action it does not recognize. It only handles the known set of ACTION_BATTERY_CHANGED-derived events (charging/discharging/full/not-charging etc.); an unknown action string falls into the terminal else branch.
Solutions
- Only dispatch actions produced by the delegate's own parsing layer; filter out unhandled actions before calling.
- Add a whitelist check: if the action is not one of the supported BatteryState events, ignore it instead of dispatching.
- Upgrade the Matrix battery-canary version if a new platform action must be supported.
Example fix
// before
@Override
public void onReceive(Context ctx, Intent i) {
delegate.dispatchBatteryStateChangedEvent(i.getAction()); // throws for LOW/OKAY
}
// after
@Override
public void onReceive(Context ctx, Intent i) {
String action = i.getAction();
if (BatteryManager.ACTION_BATTERY_CHANGED.equals(action)) {
delegate.dispatchBatteryStateChangedEvent(action);
}
} Defensive patterns
Strategy: validation
Validate before calling
private static final Set<String> SUPPORTED = new HashSet<>(Arrays.asList(
BatteryManager.ACTION_BATTERY_CHANGED /* + delegate-supported actions */));
if (!SUPPORTED.contains(action)) return; // ignore unknown battery actions Try / catch
try {
delegate.dispatchBatteryStateChangedEvent(action);
} catch (IllegalStateException e) {
MatrixLog.w(TAG, "unsupported battery action: " + action);
} Prevention
- Only forward battery events parsed by the delegate's own listener plumbing, never raw broadcast actions.
- Filter out ACTION_BATTERY_LOW/ACTION_BATTERY_OKAY and OEM-specific actions at the receiver.
- Test on target OEM ROMs for non-standard battery actions.
When it happens
Trigger: Calling onBatteryChangeEvent(...) or the async run() path with a battery state action string outside the supported set (e.g. ACTION_BATTERY_LOW / ACTION_BATTERY_OKAY, or a vendor-patched action), which is then forwarded to dispatchBatteryStateChangedEvent.
Common situations: Forwarding raw BroadcastReceiver actions (BatteryManager.ACTION_BATTERY_LOW, ACTION_POWER_CONNECTED) directly into the delegate; OEM ROMs emitting custom battery actions; forwarding an event from a different Android version with changed action strings.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Call #init() first!
- Context should not be null
- Use #onStateChanged(BatteryState, String) instead
- <getTag()> is not yet init!
- No start tag found
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/7163f79bd4c9b0ce.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-battery-canary/src/main/java/com/tencent/matrix/batterycanary/BatteryEventDelegate.java:428
}
@VisibleForTesting
void dispatchBatteryStateChangedEvent(Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_BATTERY_OKAY.equals(action) || Intent.ACTION_BATTERY_LOW.equals(action)) {
MatrixLog.i(TAG, "onBatteryStateChanged >> " + action);
synchronized (mListenerList) {
BatteryState batteryState = currentState();
for (Listener item : mListenerList) {
if (item instanceof Listener.ExListener) {
if (((Listener.ExListener) item).onBatteryStateChanged(batteryState, Intent.ACTION_BATTERY_LOW.equals(action))) {
removeListener(item);
}
}
}
}
} else {
throw new IllegalStateException("Illegal battery state: " + action);
}
}
@VisibleForTesting
void dispatchBatteryPowerChanged(int pct) {
MatrixLog.i(TAG, "onBatteryPowerChanged >> " + pct + "%");
synchronized (mListenerList) {
BatteryState batteryState = currentState();
for (Listener item : mListenerList) {
if (item instanceof Listener.ExListener) {
if (((Listener.ExListener) item).onBatteryPowerChanged(batteryState, pct)) {
removeListener(item);
}
}
}
}
}
View on GitHub (pinned to 3b8293bd65)