diff --git a/src/InfoScreen.tsx b/src/InfoScreen.tsx index 7df2b76..d481130 100644 --- a/src/InfoScreen.tsx +++ b/src/InfoScreen.tsx @@ -218,9 +218,13 @@ export default function InfoScreen({ route, navigation }: Props) { }; const readBatteryCharacteristic = async () => { - let lastValidBattery: number | null = null; + const validSamples: number[] = []; - for (let attempt = 0; attempt < 4; attempt += 1) { + // Some devices briefly report a default battery value right after the first + // connection. Read a few samples and prefer the later stable value. + await sleep(250); + + for (let attempt = 0; attempt < 5; attempt += 1) { try { const bytes = await readCharacteristicWithRetry("180f", "2a19", 1); const batteryValue = bytes[0]; @@ -230,22 +234,36 @@ export default function InfoScreen({ route, navigation }: Props) { batteryValue >= 0 && batteryValue <= 100 ) { - if (lastValidBattery !== null && lastValidBattery === batteryValue) { - return `${batteryValue}%`; - } - - lastValidBattery = batteryValue; + validSamples.push(batteryValue); + console.log( + `🔋 battery sample ${attempt + 1}: ${batteryValue}%` + ); } } catch { // Continue retrying with a short gap below. } - if (attempt < 3) { - await sleep(220); + if (attempt < 4) { + await sleep(260); } } - return lastValidBattery !== null ? `${lastValidBattery}%` : "未知"; + if (validSamples.length === 0) { + return "未知"; + } + + const lastSample = validSamples[validSamples.length - 1]; + const previousSample = validSamples[validSamples.length - 2]; + + if (previousSample !== undefined && previousSample === lastSample) { + return `${lastSample}%`; + } + + const lastNonHundredSample = [...validSamples] + .reverse() + .find((value) => value !== 100); + + return `${lastNonHundredSample ?? lastSample}%`; }; const subscribePowerDataIfNeeded = async () => { @@ -1108,4 +1126,4 @@ const styles = StyleSheet.create({ -}); \ No newline at end of file +});